Зубчики на CSS

31 July, 2013

Fun, XHTML/CSS

Внезапно пост! Небольшой странный чисто webkit трюк который вам пригодится разве что чтобы удивить свою девушку верстальщицу.

Что будет

Зззубчики:


Интересный эффект чтобы показать вырезки

И вот что получилось в итоге или то же на codepen.

Как это сделать

Будем считать что у нас такой вот HTML:

  1. <div class=”pic”>
  2. <img src=”pic.jpg”>
  3. </div>

Ничего такого, просто див.

Первое и самое простое, как это можно сделать, вырезать непрозрачную картинку с фоном и зубчиками, и накладывать поверх нашей.
Но тогда станет невозможным такой вариант


Зубчики накладываются друг на друга

CSS Маски

Да, это существует, хотя и работает пока далеко не везде и не полностью. Но к счастью мой проект только для webkit. Да, да, в этом месте можно завидовать.

Как это работает: мы рисуем картинку (gif, png, svg), важно только что у нее есть прозрачные и не очень пиксели-области.
Потом «накладываем» на блок и получается:


Как работают маски в css, иллюстрация от genn

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

Делается в CSS это как-то так:

  1. mask-image: url(mask.png); // можно и svg
  2. // или так:
  3. mask-image: url(mask.svg) top left / cover; // можно и svg

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

-webkit-mask-box-image

Эта штука называется страшно и непонятно, но суть ее такая же как у border-image. Она условно делит картинку на 9 областей, и растягивает их или повторяет, чтобы создать рамку и уголки вокруг блока.
Только нашем случае это не рамка, а маска, вот и вся разница. Вдаваться в теорию не буду, она по ссылке.

А вот такой код сотворит магию:

  1. -webkit-mask-box-image: url(mask.png) 0 3 0 3 repeat;

При этом вот такая картинка mask.png:


увеличенная в стотысячмиллионов раз

Числа 0 означают что ширина бордера-маски сверху и снизу равна 0, там у нас гладкая картинка. Два других числа это ширины двух зубчиков, по 3 пикселя.

Но и этого оказалось мне мало, ведь теперь уголки у блоков не стыковались, зубчики соседних элементов не могли войти друг в друга и образовать цельный блок.


Нестыковка

Потому я перерисовал маску в такой вид, сдвинув второй зубец:


Вот такая картинка для маски

Это и стало финальным вариантом.

Обводка

Тут все скучно, несмотря на то как красиво выглядят зубчики, ни border ни outline ни box-shadow не обходят всю границу, выглядит это примерно так:


Бордер и тень остаются квадратными

Потому пришлось идти дедовским способом известным со времен не работающего в браузерах text-shadow:

  1. .pic:before{
  2. -webkit-mask-box-image: url(mask.png) 0 3 0 3 repeat; такая же маска
  3. position: absolute;
  4. top: -1px;
  5. right: -1px;
  6. left: -1px;
  7. display: block;
  8. height: 100%;
  9. width: 100%;
  10. padding: 1px; // Это важно, делает высоту блока ровно 100% + 2px
  11. background: yellow;
  12. z-index: 2;

То есть создать псевдоэлемент, точно такой же как эта картинка, с такой же маской, закрасить его каким-то цветом, и растянуть на 1px за пределы блока. Ничего гениального, но в сочетании с маской работает невероятно красиво.

Такая вот маленькая приятная штука получилась, надеюсь кому-то пригодится =) А вот codepen, поиграться с ней.
Я до сих пор не могу удивиться больше, понадобилась всего одна миниатюрная картинка для реализации того что, еще несколько лет назад казалось невозможным.

Еще почитать на тему

Fun, XHTML/CSS

14 комментариев к “Зубчики на CSS”

Genn | 1. 31 July, 2013

Adventure Time + MLP:FiM ^___^ /)

rilian | 2. 31 July, 2013

вот такими дедовскими способами раньше рисовались скругленные углы у блоков ;)

Genn | 3. 31 July, 2013

Вот помню таблицы…

cssfish | 4. 1 August, 2013

ура, блог жив! :)

ilko725 | 5. 2 August, 2013

Аж прослезился :)
С возвращением.
А способ классный, но если бы на 3 недели раньше узнал. Эх… :)

Татьяна | 6. 2 August, 2013

О да, впечатляет!

Артём Сапегин | 7. 6 August, 2013

Клёво! Ещё бы шрифт в блоге раза в два увеличить — не видно же ничего, мы уже старые стали :-/

HTMLER | 8. 29 August, 2013

Класс! Жаль, только для Webkit, но точно применимо (не только для девушки)

Вадим Бородин | 9. 27 October, 2013

Самое обидное, что если дать СВГ вместо растра, то на Ай-ОС 6 с Ретиной всё станет два раза больше и поломается.
Вот пример, например: http://stackoverflow.com/questions/17384172/svg-as-border-image-on-retina-screens

akella | 10. 27 October, 2013

Но там же вроде в комментариях решение? просто переписать svg

Вадим Бородин | 11. 28 October, 2013

Не-а, ни одно предложенное решение не сработало.

ipnet | 12. 13 August, 2014

Спасибо за такую статью! очень полезный для меня материал!

Николай | 13. 24 November, 2015

Впечатляет, спасибо!

webdizcomua | 14. 29 August, 2016

Спасибо очень интересная и познавательная статья. Я узнал для себя много нового хотя мне казалось что ничем уже меня нельзя удивить в css

Оставить комментарий