Как сделать эффект матированного стекла

Оцените материал
(0 голосов)

Проблема

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

Разметка выглядит так:
HTML
<main>
<blockquote>
"The only way to get rid of a temptation[…]"
<footer>—
<cite>
Oscar Wilde,
The Picture of Dorian Gray
</cite>
</footer>
</blockquote>
</main>
Здесь мы используем термин подложка» для обозначения той части страницы, которая находится под элементом и которая проглядывает сквозь его полупрозрачный фон.
А CSS-код выглядит так (для краткости все незначительные детали опущены):
body {
background: url("tiger.jpg") 0 / cover fixed;
}
main {
background: hsla(0,0%,100%,.3);
}


Как вы видите, текст прочитать очень сложно, так как изображение яркое и содержит множество деталей, а фоновый цвет непрозрачен только на 25%. Разумеется, мы могли бы улучшить читабельность, увеличив параметр альфа-канала в определении фонового цвета, но тогда эффект будет не таким интересным. В традиционном печатном дизайне эту проблему часто решают путем размывания фрагмента фотографии, находящегося прямо под текстовым контейнером. Размытые фоны не такие шумные, и, следовательно, текст поверх них читается намного проще. Поскольку эффект размытия дорогостоящ в терминах вычислительных ресурсов, в прошлом эту технику невозможно было использовать на веб-сайтах и в дизайне пользовательских интерфейсов. Однако графические процессоры непрерывно совершенствуются, а аппаратное ускорение становится доступным все в большем количестве разнообразных сценариев, поэтому сегодня мы сталкиваемся с эффектом размытия в оформлении интерфейсов довольно часто. За последние несколько лет нам довелось повстречать эту технику в новых версиях как Microsoft Windows, так и Apple iOS и Mac OS X.


Увеличение значения альфа-канала для фонового цвета решает проблему читабельности, но дизайн при этом теряет изюминку


В последние годы полупрозрачные пользовательские интерфейсы с размытой подложкой встречаются все чаще, так как нагрузка на системные ресурсы, которую оказывает эффект размытия, перестала быть чрезмерно дорогой (слева -  фрагмент интерфейса из Apple
iOS 8.1; справа - фрагмент интерфейса из Apple OS X Yosemite).

В CSS у нас также есть возможность размывать элементы. Для этого используется фильтр blur() , по сути, представляющий собой аппаратно ускоренную версию соответствующего примитива фильтрации из SVG, который всегда был доступен в этом формате для размывания SVG-элементов. Однако если мы напрямую применим фильтр  blur() в нашем примере, то размытию подвергнется весь элемент, что сделает его еще менее читабельным. Существует ли способ применить эффект размытия только к подложке элемента (то есть к части фона, находящейся позади нашего элемента)?

 

Решение

При условии, что для нашего элемента определено свойство  background-attach ment со значением  fixed, исправить ситуацию можно, проявив определенную изобретательность. Поскольку мы не можем применить размытие к самому элементу, мы применим его к псевдоэлементу, расположенному позади элемента, фон которого полностью совпадает с фоном, определенным для  <body>. Для начала добавим псевдоэлемент с абсолютным позиционированием и нулевыми смещениями, полностью покрывающий элемент  <main>:
main {
position: relative;
/* [Остальные стили] */
}
main::before {
content: '';
position: absolute;
top: 0; right: 0; bottom: 0; left: 0;
background: rgba(255,0,0,.5); /* в целях отладки */
}
Это возможно и с нефиксированными фонами, но с менее изящным решением. Мы также создали полупрозрачный красный фон (цвет  red ), для того чтобы видеть, что мы делаем, в противном случае отладка стилей для прозрачного (и, следовательно, невидимого) элемента становится слишком сложным делом. В настоящий момент наш псевдоэлемент находится поверх содержимого, закрывая его. Это можно исправить, добавив  z-index :  -1 ;

Сейчас псевдоэлемент закрывает собой текст


Мы исправили проблему с затуханием размытия по краям, но теперь размывается часть изображения за пределами элемента. Будьте осторожны, используя отрицательные значения z-index для перемещения дочернего элемента под родительским: если этот ро дительский элемент вложен в другие элементы, для которых определены фоны, то они также окажутся поверх нашего дочернего элемента.

Почему бы просто не использовать background: inherit на main::before? Потому что в этом случае наследование будет выполнено от main, а не от body, и псевдоэлемент также получит полупрозрачный белый фон.
Теперь настало время заменить полупрозрачный красный фон другим фоном, в точности совпадающим с подложкой. Для этого можно либо скопировать фон из элемента  <body>, либо выделить его в собственное правило. Можно ли теперь применять размытие? Давайте попробуем:
body, main::before {
background: url("tiger.jpg") 0 / cover fixed;
}
main {
position: relative;
background: hsla(0,0%,100%,.3);
}
main::before {
content: '';
position: absolute;
top: 0; right: 0; bottom: 0; left: 0;
filter: blur(20px);
}

С помощью z-index: -1; мы поставили псевдоэлемент позади его родительского элемента


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

Красный (red) фон помогает разобраться в происходящем

Мы почти достигли цели. Эффект размытия превосходно смотрится в центре, но чем ближе к краям, тем размытие слабее. Так происходит потому, что размывающий фильтр уменьшает область, покрытую сплошным цветом, на значение, равное радиусу размытия. Снова применив красный ( red ) фон к нашему псевдоэлементу, мы сразу же поймем, в чем причина. Чтобы обойти это ограничение, сделаем псевдоэлемент по меньшей мере на  20px (радиус размытия) больше габаритных размеров его контейнера. Для этого установим размер полей, равный  -20px или еще меньше, чтобы гарантированно добиться нужного результата, так как в разных браузерах могут применяться разные алгоритмы размытия. Это решает проблему с ослаблением размытия по краям, но теперь размытие наблюдается за пределами нашего контейнера, что делает его похожим на смазанное пятно вместо матированного стекла. К счастью, это легко поправить: мы всего лишь применим  overflow :  hidden; к элементу  main, обрезав, таким образом, лишнее размытие. Финальная версия кода показана далее, а результат вы можете увидеть на рисунке:
body, main::before {
background: url("tiger.jpg") 0 / cover fixed;
}
main {
position: relative;
background: hsla(0,0%,100%,.3);
overflow: hidden;
}
main::before {
content: '';
position: absolute;
top: 0; right: 0; bottom: 0; left: 0;
filter: blur(20px);
margin: -30px;
}
Финальный результат

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

ПОПРОБУЙТЕ САМИ!
http://play.csssecrets.io/frosted-glass

 Десерт на сегодня - видео о десяти классных роботах (можете сразу перемотать на 20 секунду, так как вступление долгое):

Прочитано 468 раз Последнее изменение Воскресенье, 19 марта 2017 14:04
Другие материалы в этой категории:
Понравилась запись? Подпишитесь на обновления по почте:

Нетология

TemplateMonster

Поиск по сайту

Связной трэвел

Google+