Статьи

Создание теней вокруг полигонов в CSS

Недавно клиенты несколько раз просили меня реализовать такие проекты:

Вкладка с окружающими тенями

Когда я говорю так, я имею в виду тень от всего компонента. Как в главном блоке, так и в выбранной вкладке сверху есть тени, но они не перекрываются; они объединяются, чтобы сформировать единый градуированный результат. По сути, они описывают непрямоугольный многоугольник .

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

Итак, как бы вы пошли на реализацию такого рода эффекта? И будет ли вас удивлять, если я скажу вам, что я сделал это с чистым CSS , без использования каких-либо изображений вообще?

Основой всего этого является область, где соединяются вкладка и поле. Как получить тень для описания этой сложной формы в CSS ? Очевидно, что это будет включать box-shadow (и его эквиваленты вендора), но это свойство может создавать только прямоугольные формы. Он является гибким по отношению к border-radius (и его эквивалентам вендора), поэтому он может описывать закругленные углы, а не ограничиваться прямыми краями. Но, тем не менее, этого предостережения недостаточно для описания сложного многоугольника, который требуется для этого проекта. Так как это сделать?

Ответ обманчиво прост!

Почти каждый многоугольник может быть сведен к комбинации более простых форм — сокращение — это суть того, как мы создаем сложные формы с помощью HTML и CSS . Этот пример можно сократить до двух прямоугольников: вкладка и главное окно.

Итак, что мы должны сделать, это применить тень к обоим этим блокам , а затем отрезать перекрытие с clip !

Полигон Box-тени

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

 #container { position:relative; } #small { background:#336; width:8em; height:3em; position:absolute; left:1em; top:0; z-index:100; clip:rect(-10px 9em 3em -10px); -moz-box-shadow:0 0 10px #002; -webkit-box-shadow:0 0 10px #002; box-shadow:0 0 10px #002; } #large { background:#336; width:18em; height:20em; position:relative; top:3em; z-index:0; -moz-box-shadow:0 0 10px #002; -webkit-box-shadow:0 0 10px #002; box-shadow:0 0 10px #002; } направо #container { position:relative; } #small { background:#336; width:8em; height:3em; position:absolute; left:1em; top:0; z-index:100; clip:rect(-10px 9em 3em -10px); -moz-box-shadow:0 0 10px #002; -webkit-box-shadow:0 0 10px #002; box-shadow:0 0 10px #002; } #large { background:#336; width:18em; height:20em; position:relative; top:3em; z-index:0; -moz-box-shadow:0 0 10px #002; -webkit-box-shadow:0 0 10px #002; box-shadow:0 0 10px #002; } 

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

Тень большого прямоугольника может свободно распространяться, но часть его, которая примыкает к маленькому, покрыта этим маленьким, потому что его z-index выше, помещая его выше. В целом, комбинация позиционирования и удаления clip скрывает части тени, которые нам не нужны.

И это создает конечный эффект, который мы ищем: появление чистых CSS- теней вокруг непрямоугольной формы!

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

И вот оно! Эта техника будет работать во всех современных браузерах, включая Internet Explorer. Конечно, IE не имеет box-shadow , но у него есть фильтр Glow , и это может создать достаточно разумный эффект, если использовать его незаметно.