Контроль довжини штрихової межі та відстані між штрихами


124

Чи можна контролювати довжину та відстань між штриховими штрихами в CSS?

Цей приклад нижче відображається по-різному між браузерами:

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

Великі відмінності: IE 11 / Firefox / Chrome

IE 11 кордонуБордюр FirefoxКордон Chrome

Чи існують методи, які можуть забезпечити більший контроль зовнішнього вигляду пунктирних меж?

Відповіді:



157

Власне значення пунктирної межі не пропонує контролю над самими тиреми ... тому приносьте border-imageмайно!

Заваріть свій власний кордон з border-image

Сумісність : Він пропонує чудову підтримку браузера (IE 11 та всі сучасні браузери). Звичайна межа може бути встановлена ​​як запасна версія для старих браузерів.

Давайте створимо їх

Ці межі відображатимуть саме такий крос-браузер!

Приклад цілі Приклад цілі з більш широкими прогалинами

Крок 1 - Створіть відповідне зображення

Цей приклад шириною 15 пікселів на 15 пікселів, а прогалини в даний час шириною 5 пікселів. Це .png з прозорістю.

Ось як виглядає у фотошопі при збільшенні:

Приклад фонового зображення зображення рамки

Ось як виглядає масштаб:

Приклад фонового зображення рамки Фактичний розмір

Контроль зазору та довжини ходу

Щоб створити більш широкі / короткі проміжки або штрихи, розширити / скоротити прогалини або штрихи на зображенні.

Ось зображення із ширшими пробілами в 10 пікселів:

Більші прогалини правильно масштабувати = Більші прогалини в масштабі

Крок 2 - Створіть CSS - цей приклад вимагає 4 основних кроків

  1. Визначте джерело межі зображення :

    border-image-source:url("http://i.stack.imgur.com/wLdVc.png");  
  2. Необов’язково - визначте ширину зображення рамки :

    border-image-width: 1;

    Значення за замовчуванням - 1. Його також можна встановити зі значенням пікселя, процентним значенням або як інше кратне (1x, 2x, 3x тощо). Це переосмислює будь-який border-widthнабір.

  3. Визначте фрагмент зображення рамки :

    У цьому прикладі товщина зображень верхньої, правої, нижньої та лівої меж дорівнює 2 пікселів, і поза ними немає зазору, тому наше значення зрізу дорівнює 2:

    border-image-slice: 2; 

    Епізоди виглядають приблизно так, 2 пікселі вгорі, праворуч, знизу та зліва:

    Приклад фрагментів

  4. Визнач повторне зображення-зображення :

    У цьому прикладі ми хочемо, щоб шаблон повторювався рівномірно навколо нашого діва. Тож ми обираємо:

    border-image-repeat: round;

Написання стенограми

Наведені вище властивості можна встановити окремо або стенограмою, використовуючи межу-зображення :

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

Повний приклад

Зверніть увагу на border: dashed 4px #000резервний запас. Недопоміжні веб-переглядачі отримають цю межу.

.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>


Зауважте, що вам потрібно вказати border-style: solid(чи щось подібне), якщо ви не опускаєте резервну копію.
Robbendebiene

Це рішення не працює з атрибутом 'border-color'
Михайло Ровінський

101

Окрім border-imageвластивості, існує ще кілька способів створити пунктирну облямівку з контролем за довжиною ходу та відстані між ними. Вони описані нижче:

Спосіб 1: Використання SVG

Ми можемо створити пунктирну межу, використовуючи елемент pathабо polygonелемент та встановивши stroke-dasharrayвластивість. Властивість приймає два параметри, де один визначає розмір тире, а другий визначає простір між ними.

Плюси:

  1. SVG за своєю природою є масштабованою графікою і може адаптуватися до будь-яких розмірів контейнера.
  2. Може працювати дуже добре навіть за border-radiusучасті. Ми просто замінимо на цю відповідьpath на circleподібну (або) перетворимо в коло.path
  3. Підтримка браузера для SVG є досить хорошою, і резервна копія може бути надана за допомогою VML для IE8-.

Мінуси:

  1. Коли розміри контейнера пропорційно не змінюються, контури мають тенденцію до масштабування, що призводить до зміни розміру тире та місця між ними (спробуйте навести курсор на перший ящик у фрагменті). Це можна керувати додаванням vector-effect='non-scaling-stroke'(як у другому полі), але підтримка браузера для цього властивості є нульовою в IE.


Спосіб 2: Використання градієнтів

Ми можемо використовувати кілька linear-gradientфонових зображень та розміщувати їх належним чином, щоб створити ефект пунктирної межі. Це також можна зробити за допомогою, repeating-linear-gradientале поліпшення не надто багато через використання повторюваного градієнта, оскільки нам потрібен повторний градієнт лише в одному напрямку.

Плюси:

  1. Масштабується і може адаптуватися, навіть якщо розміри контейнера динамічні.
  2. Не використовує жодних зайвих псевдоелементів, а це означає, що їх можна залишати осторонь для будь-якого іншого потенційного використання.

Мінуси:

  1. Підтримка браузера для лінійних градієнтів порівняно нижча, і це не означає, якщо ви хочете підтримувати IE 9-. Навіть бібліотеки на зразок CSS3 PIE не підтримують створення градієнтних шаблонів у IE8-.
  2. Неможливо використовувати, коли border-radiusце задіяно, оскільки фони не криві на основі border-radius. Вони замість цього обрізаються.

Спосіб 3: Коробки тіней

Ми можемо створити невелику смугу (у формі тире), використовуючи псевдоелементи, а потім створити кілька її box-shadowверсій, щоб створити рамку, як у нижченаведеному фрагменті.

Якщо тире квадратної форми, то одного псевдоелемента буде достатньо, але якщо це прямокутник, нам знадобиться один псевдоелемент для верхньої + нижньої меж і ще один для лівих + правих меж. Це тому, що висота і ширина штриха на верхній облямівці будуть відрізнятися від висоти зліва.

Плюси:

  1. Розміри штриха керуються зміною розмірів псевдоелемента. Інтервал можна керувати, змінюючи простір між кожною тінню.
  2. Дуже унікальний ефект можна отримати, додавши різний колір для кожної тіньової коробки.

Мінуси:

  1. Оскільки нам доводиться вручну встановлювати розміри тире та проміжки, такий підхід не корисний, коли розміри батьківського вікна є динамічними.
  2. IE8 і новіші версії не підтримують тінь поля . Однак це можна подолати, використовуючи бібліотеки типу CSS3 PIE.
  3. Можна використовувати, border-radiusале розташування їх було б дуже складно з необхідністю знаходити точки на колі (а можливо, навіть transform).


Якщо ви збираєтесь використовувати рішення svg, я раджу додати pointer-events:noneдо SVG inorder, щоб мати можливість взаємодіяти зі вмістом.
Содж

Чудова відповідь.
Девіація

22

Короткий: Ні, це не так. Натомість вам доведеться працювати з зображеннями.


5
ця відповідь застаріла станом на 2018 рік
godblessstrawberry

2
@WilliamHampshire Я б пішов з цією технікою youtu.be/vs34f9FiHps?t=779, але перевіримо прийняту відповідь, можливо, вам сподобаються інші рішення краще
godblessstrawberry

1
@godblessstrawberry Спасибі !! Але це використовується SVG, тому все ще не використовується просто css ...
Вільям Хемпшир,

1
@WilliamHampshire є тіньове рішення в темі, на яку я мав на увазі відповідь Гаррі
godblessstrawberry

@godblessstrawberry Ви спробували рішення? Розчин намалював пунктирною лінією за сегментом. Це просто POC і марний на практиці!
Yu Jianrong

6

Є класний інструмент, створений компанією @kovart, який називається генератором пунктирних меж .

Він використовує svg як фонове зображення, щоб дозволити встановити бажаний масив штрихових штрихів, і це досить зручно.

Потім ви просто використовуватимете його як фонове властивість на своєму елементі замість межі:

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;
}

Це просте, просте і швидке рішення
jamesioppolo

Це добре працювало!
Кевін Раффай

3

Довжина ходу залежить від ширини ходу. Ви можете збільшити довжину, збільшивши ширину і приховавши частину бордюру внутрішнім елементом.

.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/


Але таким чином ви не зможете натиснути вміст оригінального елемента, оскільки псевдоелемент "after" покриє його. Тож найкращий спосіб - використовувати SVG.
ili4

Ви можете додати, pointer-events: noneщоб запобігти проблемі з накладанням.
benJ

0

У мене нещодавно була та сама проблема.

Мені вдалося вирішити це за допомогою двох абсолютно розташованих дівок, що переносять кордон (один для горизонтального та один для вертикального), а потім їх перетворення. Зовнішній ящик просто повинен бути розташований відносно.

<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>

Примітка: я використовував тахіони в цьому прикладі, але я здогадуюсь, що заняття є своєрідними поясненнями.


-1

Це зробить помаранчеву та сіру межу за допомогою класу = "myclass" у діві.

.myclass {
    outline:dashed darkorange  12px;
    border:solid slategray  14px;
    outline-offset:-14px;
}

Завдяки «забезпеченню більшого контролю над зовнішнім виглядом пунктирних меж», ОР (оригінальний плакат) означає, що він хоче контролювати довжину кожного тире, як зазначено на початку запитання. Вибачте за замішання.
Скайлар
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.