CSS Зигзагообразная граница с текстурированным фоном

#html #css #svg #web-frontend

Вопрос:

Я работал над заголовком с зигзагообразной рамкой. Один из способов сделать это-использовать изображения для создания эффекта зигзага.

(1) Есть ли какой-либо способ создать практичную межбраузерную зигзагообразную границу в CSS без использования изображений?

Я также пытаюсь наложить текстурированный фон на этот заголовок, который распространяется на зигзаги. Однако вертикальный размер заголовка может измениться, и я не могу реализовать заголовок в виде одного изображения.

Если я попытаюсь добавить текстуру как к краям зигзага, так и к элементу заголовка, скорее всего, текстура будет синхронизирована.

(2) Есть какие-либо идеи по реализации текстурированного фона, который распространяется на зигзаги без отключения синхронизации?

Мой [старый] код (вместе с текстурой) находится здесь, в jsFiddle.

 body {
  padding: 20px;
}

header {
  width: 240px;
  background-color: #BCED91;
}

header:after {
  content: " ";
  display: block;
  position: relative;
  width: 240px;
  bottom: -15px;
  height: 15px;
  background: url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAACgAAAAPCAYAAACWV43jAAAAw0lEQVRIx83RsQ3CMBCF4T83AZKLVOmyBa1HSIlXwKySGaDOBClZAToWQIpETQONyxAS 2J4pe9knd5X9EP7QicPYAsUwBnYaHwqSsd1QGmNv1rjL0AZ3pJTKDTorPGnsUE/tDvg KsG70D96TiAMKvDbtYDO6Cyxt  LYadKpY8hthNtTaVGHLRJJ3R5mJy0SbVJp9D7FJaSyWXNUk1yGVt0lTyMWK3ZmtLySUnaQy55CZdSi7AHmis8U/ JOGWBji8AaYPVy6VELZvAAAAAElFTkSuQmCC) repeat-x;
}

img {
  margin-top: 50px;
} 
 <header>
  <br />
  <br />
  <br />
  <br />
</header>

<img src="http://i.imgur.com/qKsVr.png" /> 

Правка №1:

Спасибо тебе, Ана, за код. Я взял его и усовершенствовал.

http://dabblet.com/gist/3401493

Я не думаю, что будет возможна последовательная предыстория.

Комментарии:

1. Ваша ссылка на даббет мертва, не могли бы вы скопировать код сюда, пожалуйста?

Ответ №1:

Если вы собираетесь использовать border-image , то это не кроссбраузерное решение, потому что IE его не поддерживает.

Кроме того, несмотря на то , что каждая текущая версия браузера, кроме IE9, поддерживает как градиенты CSS (что позволило бы вам получить зигзагообразный шаблон), так и border-image , когда я проверял в последний раз (что было довольно много месяцев назад, так что лучше протестировать это еще раз), использование градиентов работало border-image только в WebKit. Кроме того, я не думаю, что даже в WebKit это работает с несколькими градиентами (так как вы можете установить только одно изображение границы, а один градиент-это одно изображение), и вам нужно два градиента для зигзагообразного рисунка.

Код для шаблона CSS zig-zag выглядит следующим образом:

 background: linear-gradient(#BCED91 49%, transparent 49%),
        linear-gradient(-45deg, white 33%, transparent 33%) 0 50%,
        white linear-gradient(45deg, white 33%, #BCED91 33%) 0 50%;
    background-repeat: repeat-x;
    background-size: 1px 100%, 40px 40px, 40px 40px;
 

Если вам нужна текстура ниже этой, которая синхронизирована с этой, то вы должны убедиться, что она повторяется с одинаковыми интервалами ( 40px , но вы также можете пойти 20px ).


Правка: что касается полифиллов, вы можете попробовать один из перечисленных здесь: CSS3 PIE или cssSandpaper

Комментарии:

1. Хороший оригинальный способ использования css3 для создания этого зигзага! Однако, похоже, что изображение не может быть использовано для фона (первый линейный градиент). Я думаю, что просто невозможно создать непрерывную текстуру, если высота элемента не является постоянной и предсказуемой. Кроме того, существует ли заполнение JS, чтобы это работало в IE8 и IE9?

2. Вы можете удалить первый линейный градиент и поиграть с изображениями или другими градиентами за зигзагом-вот так dabblet.com/gist/3401443 . С его помощью можно было бы многое сделать. Что касается полифиллов, вы можете проверить те, которые перечислены здесь css3clickchart.com/#linear-gradient (слева внизу страницы)

3. Завтра я попробую CSS-пирог и cssSandpaper. Но что касается фона, я хотел поместить его на саму зеленую часть, но, похоже, с линейными градиентами это безнадежное дело. Тем не менее, это отличный способ сделать это. Спасибо!

4. @Ana как вы делаете зигзаг сверху и снизу?

Ответ №2:

(В современных браузерах) вы можете использовать SVG для создания простых рисунков и использовать их в качестве фоновых изображений CSS, встроенных в URI данных.

Вот как выглядят SVG-файлы:

 body {
  background: #888;
} 
 <svg version="1.1" xmlns="http://www.w3.org/2000/svg" width="8px" height="4px">
  <polygon points="0,4 4,0 8,4" fill="#CC0000" />
</svg>
<svg version="1.1" xmlns="http://www.w3.org/2000/svg" width="8px" height="4px">
  <polygon points="0,0 4,4 8,0" fill="#CC0000" />
</svg>
<svg version="1.1" xmlns="http://www.w3.org/2000/svg" width="8px" height="4px">
  <polygon points="0,0 4,4 8,0" fill="#FFFFFF" />
</svg>
<svg version="1.1" xmlns="http://www.w3.org/2000/svg" width="8px" height="4px">
  <polygon points="0,4 4,0 8,4" fill="#FFFFFF" />
</svg> 

Пример 1:

 .zigzag-outside {
  position: relative;
  margin-top: 4px;
  margin-bottom: 4px;
  background-color: #CC0000;
  /* example content */
  padding: 1em;
  font: bold medium sans-serif;
  color: #FFFFFF;
}
.zigzag-outside:before {
  content: "";
  position: absolute;
  top: -4px;
  left: 0;
  right: 0;
  height: 4px;
  /* red up pointing triangle */
  background-image: url("data:image/svg xml,");
}
.zigzag-outside:after {
  content: "";
  position: absolute;
  bottom: -4px;
  left: 0;
  right: 0;
  height: 4px;
  /* red down pointing triangle */
  background-image: url("data:image/svg xml,");
} 
 <div class="zigzag-outside">Example 1</div> 

Пример 2:

 .zigzag-inside {
  position: relative;
  /* example content */
  width: 600px;
  height: 100px;
  background-image: url(http://i.stack.imgur.com/uOVfl.jpg);
}
.zigzag-inside:before {
  content: "";
  position: absolute;
  top: 0;
  left: 0;
  right: 0;
  height: 4px;
  /* white down pointing triangle */
  background-image: url("data:image/svg xml,");
}
.zigzag-inside:after {
  content: "";
  position: absolute;
  bottom: 0;
  left: 0;
  right: 0;
  height: 4px;
  /* white up pointing triangle */
  background-image: url("data:image/svg xml,");
} 
 <div class="zigzag-inside"></div> 

Ответ №3:

Улучшен минимальный CSS:

 div {
  background: #1ba1e2;
  position: relative;
}

div:after {
  content: "";
  display: block;
  position: absolute;
  width: 100%;
  height: 30px;
  background: linear-gradient(-45deg, transparent 75%, #1ba1e2 0) 0 50%,
              linear-gradient(45deg, transparent 75%, #1ba1e2 0) 0 50%;
  background-size: 30px 30px;
}

/* Styles just for demo */
h1 {
  color: #fff;
  text-align: center;
  margin: 0;
  padding: 0.5em;
} 
 <div>
  <h1>Zig Zag Borders</h1>
</div> 

Если вы хотите удалить повторяющиеся значения, вы можете использовать переменные CSS, также называемые пользовательскими свойствами. Они работают везде, кроме IE.

 :root {
  --background-color: #1ba1e2;
  --zigzag-item-size: 30px;
}

div {
  background: var(--background-color);
  position: relative;
}

div:after {
  content: "";
  display: block;
  position: absolute;
  width: 100%;
  height: var(--zigzag-item-size);
  background: linear-gradient(-45deg, transparent 75%, var(--background-color) 0) 0 50%,
              linear-gradient(45deg, transparent 75%, var(--background-color) 0) 0 50%;
  background-size: var(--zigzag-item-size) var(--zigzag-item-size);
}

/* Styles just for demo */
h1 {
  color: #fff;
  text-align: center;
  margin: 0;
  padding: 0.5em;
} 
 <div>
  <h1>Zig Zag Borders</h1>
</div> 

Небольшая заметка:

Я использую ноль 0 в градиентных остановках цвета, чтобы избежать дублирования предыдущих значений, потому что в соответствии со спецификациями изображений CSS3 положение остановки цвета не может быть меньше предыдущего.

Если цветовая остановка имеет позицию, которая меньше указанной позиции любой цветовой остановки перед ней в списке, установите ее позицию равной наибольшей указанной позиции любой цветовой остановки перед ней.

Комментарии:

1. Этот код отлично работает, но я хотел бы, чтобы был способ добавить тень ниже границы зигзага.

2. @andreszs Не могли бы вы задать отдельный вопрос и отправить ссылку сюда?