Kontrol panjang garis tepi putus-putus dan jarak antara guratan

124

Apakah mungkin untuk mengontrol panjang dan jarak antara garis batas putus-putus di CSS?

Contoh di bawah ini ditampilkan secara berbeda antar browser:

div {
  border: dashed 4px #000;
  padding: 20px;
  display: inline-block;
}
<div>I have a dashed border!</div>

Perbedaan besar: IE 11 / Firefox / Chrome

Batas IE 11Perbatasan FirefoxPerbatasan Chrome

Apakah ada metode yang dapat memberikan kontrol lebih besar terhadap tampilan batas putus-putus?

AntonAL
sumber

Jawaban:

157

Nilai properti perbatasan putus-putus asli tidak menawarkan kontrol atas tanda hubung itu sendiri ... jadi bawa border-imageproperti itu!

Buat perbatasan Anda sendiri dengan border-image

Kompatibilitas : Menawarkan dukungan browser yang hebat (IE 11 dan semua browser modern). Batas normal dapat disetel sebagai cadangan untuk browser lama.

Mari buat ini

Perbatasan ini akan menampilkan lintas browser yang sama persis!

Contoh gol Contoh gol dengan celah yang lebih lebar

Langkah 1 - Buat gambar yang sesuai

Contoh ini adalah lebar 15 piksel kali tinggi 15 piksel dan lebar celah saat ini adalah 5 piksel. Ini adalah .png dengan transparansi.

Seperti inilah tampilannya di photoshop saat diperbesar:

Contoh Latar Belakang Gambar Perbatasan Blown Up

Seperti inilah ukurannya untuk diukur:

Contoh Ukuran Sebenarnya Gambar Perbatasan Latar Belakang

Mengontrol celah dan panjang pukulan

Untuk membuat celah atau goresan yang lebih lebar / pendek, perlebar / persingkat celah atau goresan pada gambar.

Berikut adalah gambar dengan celah 10px yang lebih lebar:

Celah yang lebih besar skala dengan benar = Celah yang lebih besar untuk diukur

Langkah 2 - Buat CSS - contoh ini memerlukan 4 langkah dasar

  1. Tentukan sumber gambar-perbatasan :

    border-image-source:url("http://i.stack.imgur.com/wLdVc.png");  
  2. Opsional - Tentukan lebar gambar tepi :

    border-image-width: 1;

    Nilai defaultnya adalah 1. Ini juga dapat diatur dengan nilai piksel, nilai persentase, atau sebagai kelipatan lainnya (1x, 2x, 3x dll). Ini mengesampingkan border-widthset apa pun .

  3. Tentukan potongan-gambar-perbatasan :

    Dalam contoh ini, ketebalan batas atas, kanan, bawah, dan kiri gambar adalah 2px, dan tidak ada celah di luarnya, jadi nilai potongan kami adalah 2:

    border-image-slice: 2; 

    Irisannya terlihat seperti ini, 2 piksel dari atas, kanan, bawah dan kiri:

    Contoh irisan

  4. Tentukan pengulangan gambar perbatasan :

    Dalam contoh ini, kami ingin pola berulang secara merata di sekitar div kami. Jadi kami memilih:

    border-image-repeat: round;

Menulis singkatan

Properti di atas dapat diatur secara individual, atau singkatnya menggunakan gambar tepi :

border-image: url("http://i.stack.imgur.com/wLdVc.png") 2 round;

Contoh lengkap

Perhatikan border: dashed 4px #000fallback. Browser yang tidak mendukung akan menerima batas ini.

.bordered {
  display: inline-block;
  padding: 20px;
  /* Fallback dashed border
     - the 4px width here is overwritten with the border-image-width (if set)
     - the border-image-width can be omitted below if it is the same as the 4px here
  */
  border: dashed 4px #000;
  
  /* Individual border image properties */
  border-image-source: url("http://i.stack.imgur.com/wLdVc.png");
  border-image-slice: 2;
  border-image-repeat: round;  
  
  /* or use the shorthand border-image */
  border-image: url("http://i.stack.imgur.com/wLdVc.png") 2 round;
}


/*The border image of this one creates wider gaps*/
.largeGaps {
  border-image-source: url("http://i.stack.imgur.com/LKclP.png");
  margin: 0 20px;
}
<div class="bordered">This is bordered!</div>

<div class="bordered largeGaps">This is bordered and has larger gaps!</div>

misterManSam
sumber
Perhatikan bahwa Anda perlu menentukan border-style: solid(atau sesuatu yang serupa) jika Anda menghilangkan fallback.
Robbendebiene
Solusi ini tidak berfungsi dengan atribut 'border-color'
Michael Rovinsky
102

Selain border-imageproperti, ada beberapa cara lain untuk membuat batas putus-putus dengan mengontrol panjang guratan dan jarak di antara mereka. Mereka dijelaskan di bawah ini:

Metode 1: Menggunakan SVG

Kita dapat membuat perbatasan putus-putus dengan menggunakan pathatau polygonelemen dan mengatur stroke-dasharrayproperti. Properti mengambil dua parameter di mana yang satu menentukan ukuran tanda hubung dan yang lainnya menentukan ruang di antara keduanya.

Kelebihan:

  1. SVG pada dasarnya adalah grafik yang dapat diskalakan dan dapat beradaptasi dengan dimensi penampung apa pun.
  2. Bisa bekerja dengan sangat baik meski ada yang border-radiusterlibat. Kami hanya akan mengganti pathdengan circleseperti dalam jawaban ini (atau) ubah pathmenjadi lingkaran.
  3. Dukungan browser untuk SVG cukup bagus dan fallback dapat disediakan menggunakan VML untuk IE8-.

Kekurangan:

  1. Jika dimensi penampung tidak berubah secara proporsional, jalur cenderung menskala yang mengakibatkan perubahan ukuran tanda hubung dan spasi di antara keduanya (coba arahkan kursor ke kotak pertama di cuplikan). Ini dapat dikontrol dengan menambahkan vector-effect='non-scaling-stroke'(seperti di kotak kedua) tetapi dukungan browser untuk properti ini nihil di IE.


Metode 2: Menggunakan Gradien

Kita dapat menggunakan beberapa linear-gradientgambar latar belakang dan memposisikannya dengan tepat untuk menciptakan efek garis putus-putus. Ini juga dapat dilakukan dengan a repeating-linear-gradienttetapi tidak banyak peningkatan karena menggunakan gradien berulang karena kita membutuhkan setiap gradien untuk diulang hanya dalam satu arah.

Kelebihan:

  1. Dapat diskalakan dan dapat beradaptasi meskipun dimensi wadahnya dinamis.
  2. Tidak menggunakan elemen semu tambahan yang berarti mereka dapat disisihkan untuk penggunaan potensial lainnya.

Kekurangan:

  1. Dukungan browser untuk gradien linier secara komparatif lebih rendah dan ini tidak dapat dilakukan jika Anda ingin mendukung IE 9-. Bahkan pustaka seperti CSS3 PIE tidak mendukung pembuatan pola gradien di IE8-.
  2. Tidak dapat digunakan jika border-radiusdilibatkan karena latar belakang tidak berdasarkan kurva border-radius. Mereka malah dipotong.

Metode 3: Bayangan Kotak

Kita dapat membuat bar kecil (dalam bentuk tanda hubung) menggunakan elemen semu dan kemudian membuat beberapa box-shadowversi untuk membuat batas seperti pada cuplikan di bawah ini.

Jika tanda hubung berbentuk persegi maka satu pseudo-element sudah cukup tetapi jika itu adalah persegi panjang, kita akan membutuhkan satu pseudo-element untuk batas atas + bawah dan satu lagi untuk batas kiri + kanan. Ini karena tinggi dan lebar tanda pisah di tepi atas akan berbeda dari yang di sebelah kiri.

Kelebihan:

  1. Dimensi dari tanda hubung dapat dikontrol dengan mengubah dimensi elemen semu. Spasi dapat dikontrol dengan memodifikasi jarak antara setiap bayangan.
  2. Efek yang sangat unik dapat dihasilkan dengan menambahkan warna berbeda untuk setiap bayangan kotak.

Kekurangan:

  1. Karena kita harus mengatur dimensi tanda hubung dan jarak secara manual, pendekatan ini tidak baik jika dimensi kotak induk dinamis.
  2. IE8 dan yang lebih rendah tidak mendukung box shadow . Namun, ini dapat diatasi dengan menggunakan pustaka seperti CSS3 PIE.
  3. Dapat digunakan dengan border-radiustetapi memposisikannya akan sangat rumit dengan harus menemukan titik pada lingkaran (dan mungkin genap transform).

Harry
sumber
Jika Anda akan menggunakan solusi svg, saya sarankan menambahkan pointer-events:noneke svg inorder agar dapat berinteraksi dengan konten.
Sodj
Jawaban yang luar biasa.
Deviance
22

Singkatnya: Tidak, tidak. Anda harus bekerja dengan gambar sebagai gantinya.

Ham Vocke
sumber
5
jawaban ini sudah usang pada 2018
godblessstrawberry
2
@WilliamHampshire Saya akan menggunakan teknik ini youtu.be/vs34f9FiHps?t=779 tetapi periksa jawaban yang diterima, Anda mungkin lebih menyukai solusi lain yang lebih baik
godblessstrawberry
1
@tokopedia Tapi itu menggunakan SVG jadi masih tidak hanya menggunakan css ...
Kyle Krzeski
1
@WilliamHampshire ada solusi kotak-bayangan di utas yang saya maksud jawaban oleh Harry
godblessstrawberry
@godblessstrawberry Sudahkah Anda mencoba solusinya? Solusi menggambar garis putus-putus segmen demi segmen. Ini hanya POC dan tidak berguna dalam praktiknya!
Yu Jianrong
6

Ada alat keren yang dibuat oleh @kovart yang disebut generator perbatasan putus - putus .

Ini menggunakan svg sebagai gambar latar belakang untuk memungkinkan pengaturan array stroke dash yang Anda inginkan, dan cukup nyaman.

Anda kemudian hanya akan menggunakannya sebagai properti latar belakang pada elemen Anda di tempat perbatasan:

div {
  background-image: url("data:image/svg+xml,%3csvg width='100%25' height='100%25' xmlns='http://www.w3.org/2000/svg'%3e%3crect width='100%25' height='100%25' fill='none' stroke='black' stroke-width='4' stroke-dasharray='6%2c 14' stroke-dashoffset='0' stroke-linecap='square'/%3e%3c/svg%3e");
  padding: 20px;
  display: inline-block;
}
Balthazar
sumber
Ini adalah solusi yang sederhana, mudah dan cepat
jamesioppolo
Ini bekerja dengan baik!
Kevin Raffay
3

Panjang goresan tergantung pada lebar goresan. Anda dapat menambah panjang dengan menambah lebar dan menyembunyikan bagian perbatasan dengan elemen dalam.

.thin {
    background: #F4FFF3;
    border: 2px dashed #3FA535;  
    position: relative;
}

.thin:after {
    content: '';
    position: absolute;
    left: -1px;
    top: -1px;
    right: -1px;
    bottom: -1px;
    border: 1px solid #F4FFF3;
}

https://jsfiddle.net/ok6srt2z/

ili4
sumber
Namun dengan cara ini Anda tidak akan dapat mengklik konten elemen asli karena pseudoelement "setelah" akan menutupinya. Jadi cara terbaik adalah menggunakan SVG.
ili4
Anda dapat menambahkan pointer-events: noneuntuk mencegah masalah overlay.
benJ
0

Saya baru saja mengalami masalah yang sama.

Saya berhasil menyelesaikannya dengan dua div yang benar-benar diposisikan membawa perbatasan (satu untuk horizontal dan satu untuk vertikal), dan kemudian mengubahnya. Kotak luar hanya perlu ditempatkan secara relatif.

<div class="relative">
    <div class="absolute absolute--fill overflow-hidden">
        <div class="absolute absolute--fill b--dashed b--red"
            style="
                border-width: 4px 0px 4px 0px;
                transform: scaleX(2);
        "></div>
        <div class="absolute absolute--fill b--dashed b--red"
            style="
                border-width: 0px 4px 0px 4px;
                transform: scaleY(2);
        "></div>
    </div>

    <div> {{Box content goes here}} </div>
</div>

Catatan: Saya menggunakan tachyons dalam contoh ini, tetapi saya kira kelasnya cukup jelas.

razzz
sumber
-1

Ini akan membuat perbatasan oranye dan abu-abu menggunakan class = "myclass" pada div.

.myclass {
    outline:dashed darkorange  12px;
    border:solid slategray  14px;
    outline-offset:-14px;
}
BJC
sumber
Dengan "memberikan kontrol yang lebih besar terhadap tampilan batas putus-putus", OP (Poster Asli) berarti bahwa ia ingin mengontrol panjang setiap tanda hubung, seperti yang dinyatakan di awal pertanyaan. Maaf atas kebingungannya.
Skylar