Кроссбраузерные отражения, свечения и размытия CSS

отражение, свечение и размытие в CSS

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

Детали учебника

Сложность: Средняя

Примерное время выполнения: 30 мин.

Совместимость: современные браузеры, IE7+

скачать исходникидемо

Предпосылки

Изучение данного материала предполагает, что:

— Вы знаете HTML;

— Вы знакомы с селекторами CSS и CSS2;

— Если хотите в точности воспроизвести образец, то должны знать, как работает тень блока box-shadow. Она в этом учебнике не является ключевой, так что вам придется постигать ее самим. Если понадобится объяснение, предлагаю вам взглянуть на статью CSS3 vs. Photoshop : закругленные углы и тени блока.

Box-reflect vs. «Свой метод»

Box-reflect — свойство CSS, как раз предназначенное для этой цели: создания отражений. Мы не станем применять box-reflect и mask-image, потому что:

— На момент написания этой статьи оба свойства поддерживаются только webkit (Chrome и Safari).

— Реализация кишит ошибками, если не сказать более.

Когда Microsoft представил свои эффекты фильтра (вспомните эпоху IE 4, вложенные таблицы для разметки и изображения для отражений), устаревшие фильтры не применялись ко всему данному элементу. Думаю, они использовали некий вид граничного блока из верхнего левого к нижнему правому углу элемента, что имело смысл, так как, насколько я знаю, не было способа выйти за пределы этого блока. Однако, так и не исправили это.

Сейчас, в век Chrome 17, webkit сделал ту же ошибку. Рисунки маски, ключ к -webkit-box-reflect, делают некий вид динамического снэпшота внутри граничного блока, вставляют его снизу и меняют непрозрачность. Я постарался восстановить демо-образец с помощью -webkit-box-reflect:

Я его не закончил, но проблема ясна. У отображаемого элемента (будем называть его ETBR — Element to be Reflected) есть border-radius и box-shadow. Тень блока видна внутри, а не снаружи граничного блока.

В моем собственном методе матрица видоизменяется, вставленная тень блока и непрозрачность заменят box-reflect и mask-image. Ограничения:

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

— Встроенная тень блока не влияет на текст отображаемого элемента (ETBR). Это происходит, если цвет текста не такой же, как фоновый цвет поверхности.

Поиграть с образцом | Полноэкранное изображение

Цвет текста не становится темнее там, где это делает фон. Поэтому, кажется, нельзя получить другой цвет и тень блока одновременно.

Выбор…

Кстати говоря, о матрицах и отражениях…

«Выбираете синюю таблетку – я показываю, как воссоздать демо-образец шаг за шагом. Выбираете красную – покажу, как сделать отражения чего угодно и расскажу, где можно купить отражающие тени по очень привлекательной цене»

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

Дополнительно: подготовка

Демо-образец начинается с шаблона HTML5…

index.html

<!DOCTYPE html>
<html>
    <head>
        <meta charset="utf-8" />
        <meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1" />
        <title>CSS3 Reflections</title>
        <meta name="description" content="Reflection..." />
        <meta name="author" content="Bob de Ruiter" />
        <meta name="viewport" content="width=device-width; initial-scale=1.0" />
        <link rel="shortcut icon" href="/favicon.ico" />
        <link rel="apple-touch-icon" href="/apple-touch-icon.png" />
    </head>
    <body>
    </body>
</html>

…и этого файла CSS.

style.css

html {
    height: 100%;
}
body {
    text-align: center;
    line-height: 1;
    margin: 0;
    padding: 0;
    height: 100%;
}
p {
    line-height: 1.2;
}

И, конечно, в таблицу стилей добавим ссылку:

<head>
    <meta charset="utf-8" />
    <meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1" />
    <title>CSS reflections!</title>
    <meta name="description" content="" />
    <meta name="author" content="Bob" />
    <meta name="viewport" content="width=device-width; initial-scale=1.0" />
 
    <link rel="stylesheet" href="style.css" />
 
    <link rel="shortcut icon" href="/favicon.ico" />
    <link rel="apple-touch-icon" href="/apple-touch-icon.png" />
</head>

2D, но 3D

Демо-образец двухмерный. Ни единого 3D-элемента. Мы об этом знаем, но наша цель – заставить их считать, что мы это создали, а затем сфотографировали фронтальный вид.

Если мы хотим заставить их поверить, что это 3D, то должны определить, как объекты располагаются и вращаются в трехмерном пространстве. У демо-образца есть горизонт. Верхние 10% — это черное «небо», прочие 90% — фальшивая трехмерная плоскость. Отображаемый элемент и плоскость перпендикулярны друг другу (под углом 90°), отражение должно быть параллельно отображаемому элементу.

Шаг 1: дополнительный Плоскость и отображаемый элемент

HTML:

<body>
    <div id="plane">
        <header><span id="ETBR">reflection</span></header>
    </div>
</body>

Отражаемый элемент (ETBR) – потомок плоскости. Таким образом, он остается в одном и том же положении видимым с плоскости, а свечение остается на плоскости.

body {
    text-align: center;
    line-height: 1;
    margin: 0;
    padding: 0;
    background-color: #000;
    height: 100%;
}
p {
    line-height: 1.2;
}
#plane {
    left: 0;
    top: 10%;
    width: 100%;
    bottom: 0;
    min-width: 1080px;
    min-height: 600px;
    position: absolute;
    overflow: hidden;
    overflow-x: visible;
}

Примечание:

— У плоскости есть минимальная ширина min-width и минимальная высота min-height, поэтому отражаемый элемент всегда виден.

— Переполнение overflow-y установлено на hidden, поэтому свечение отражаемого элемента остается на плоскости. (Небо должно быть непроглядно черным.)

— У плоскости нет фонового цвета, она получает свою окраску от свечения, что совершенно бессмысленно, но смотрится лучше всего.

Шаг 2: разметка отражения

Определите место отражаемого объекта (ETBR), скопируйте его, вставьте внутрь самого себя и переименуйте в refl:

<span id="ETBR">reflection<span id="refl">reflection</span></span>

Теперь внутри css создайте селектор объекта. Добавьте к селектору #refl, чтобы наши стили применялись к обоим элементам:

#ETBR, #refl {
 
}

По существу, CSS и HTML отражения должны быть такими же, как CSS и HTML отражаемого элемента ETBR. Мы разместим, зеркалируем и приукрасим отражение, начиная с шага 5. А сейчас мы скроем отражение.

#ETBR, #refl {
 
}
#refl {
    display: none;
}

Internet Explorer – это всегда Internet Explorer, так что нам придется добавить немного условного HTML:

<!DOCTYPE html>
<html>
    <head>
        <meta charset="utf-8" />
        <meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1" />
        <title>CSS3 Reflections</title>
        <meta name="description" content="Reflection..." />
        <meta name="author" content="Bob de Ruiter" />
        <meta name="viewport" content="width=device-width; initial-scale=1.0" />
 
        <link rel="stylesheet" href="style.css" />
 
        <link rel="shortcut icon" href="/favicon.ico" />
        <link rel="apple-touch-icon" href="/apple-touch-icon.png" />
    </head>
    <!--[if lt IE 9 ]> <body class="oldie"> <![endif]-->
    <!--[if IE 9 ]> <body class="ie9"> <![endif]-->
    <!--[if (gt IE 9)|!(IE)]><!--> <body class="modern"> <!--<![endif]-->
        <div id="plane">
            <header><span id="ETBR">reflection<span id="refl">reflection</span></span></header>
        </div>
    </body>
</html>

Вы можете спросить «почему?», просто немного потерпите. Так как вы нетерпеливы, первый раздел Поиграть с образцом будет совершенно черным. Хотите увидеть влияние плоскости? Измените размер.

Поиграть с образцом | Полноэкранное изображение

Шаг 3: дополнительный Основные стили

Здесь объяснения не нужны:

#ETBR, #refl {
    color: #004;
 
    font-family: Impact, 'Arial Black', Helvetica, Arial, sans-serif;
    text-transform: uppercase;
    font-size: 200px;
    background-color: #FFE;
    font-weight: bold;
    padding: 30px;
    display: inline-block;
}
#refl {
    display: none;
}

Ну хорошо, немного объясню. Сочетание text-align: center; и display: inline-block; располагает элемент по центру, но это – не поиски Святого Грааля; встраиваемые элементы не могут содержать элементы блоков. Я применил это, потому что не хотел добавлять к образцу тысячи «плавающих» контейнеров. Хотя в общем, это – то, что нужно.

Поиграть с образцом | Полноэкранное изображение

Шаг 4: дополнительный Закругленные углы и свечение

Свечение состоит из трех теней: большой растянутой тени (которая выглядит больше похожей на отражение света на поверхности), настоящего свечения (белой тени с более коротким диапазоном размытия) и черной вставленной тени (которая дает возможность отражаемому элементу ETBR выглядеть, как будто он светится). Как я уже говорил, я не собираюсь объяснять, как работает тень блока box-shadow, а уж радиус угла border-radius сейчас уже говорит сам за себя.

#ETBR, #refl {
    color: #004;
 
    font-family: Impact, 'Arial Black', Helvetica, Arial, sans-serif;
    text-transform: uppercase;
    font-size: 200px;
    background-color: #FFE;
    font-weight: bold;
    padding: 30px;
    display: inline-block;
 
    box-shadow: rgba(255,255,240,.2) 0 0 200px 100px, rgba(255,255,240,.3) 0 0 40px, inset rgba(0,0,0,.8) 0 0 20px;
    border-radius: 30px;
}

Поиграть с образцом | Полноэкранное изображение

Шаг 5: размещаем отражение

Отобразите селектор #refl, чтобы отражение стало видимым. Так как отражения «ненастоящие», наше отражение не станет частью тракта обработки документов; оно должно «плавать». Очевидный выбор – установить абсолютное позиционирование, это значит, элемент размещается относительно своего родительского элемента. Так как у родительского элемента отражения не существует, он будет расположен относительно тэга body.

Гораздо легче установить отражение относительно реального текста, который тоже является родителем отражения (совпадение?). Чтобы сделать это, сначала нужно «установить» ETBR:

#ETBR, #refl {
    color: #004;
 
    font-family: Impact, 'Arial Black', Helvetica, Arial, sans-serif;
    text-transform: uppercase;
    font-size: 200px;
    background-color: #FFE;
    font-weight: bold;
    padding: 30px;
    display: inline-block;
 
    box-shadow: rgba(255,255,240,.2) 0 0 200px 100px, rgba(255,255,240,.3) 0 0 40px, inset rgba(0,0,0,.8) 0 0 20px;
    border-radius: 30px;
 
    position: relative;
}

Таким образом местоположение в действительности не меняется, но он теперь расположен. Теперь:

#refl {
    position: absolute;
 
    top: 100%;
    left: 0;
}

Верх отражения относителен высоты и расположения отражаемого элемента (ETBR). 0% дает нам тот же верх, 200% дает зазор, равный высоте ETBR, а 100% ставит верх отражения в низ отражаемого элемента ETBR. Левое значение то же самое, но принимает процентное отношение ширины.

Поиграть с образцом | Полноэкранное изображение

Шаг 6: современное зеркалирование, размытие и прозрачность

Эти свойства есть почти у каждого часто используемого браузера, от IE6 до Google Chrome. Однако их реализация отличается. Современные браузеры очень прямолинейны, для каждой характеристики свойств: transform, blur и opacity. Еще мы применим box-shadow, но сначала зеркалирование.

Зеркалирование

#refl {
    position: absolute;
 
    top: 100%;
    left: 0;
 
    -moz-transform: scaleY(-1);
    -webkit-transform: scaleY(-1);
    -ms-transform: scaleY(-1);
}

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

Каждый дизайнер должен знать, что масштабирование на -1 по оси Y – то же самое, что зеркалирование. Масштабирование по оси Y – это умножение расстояния между верхом (и низом) и центром. Если по оси Y масштабировать в 2, расстояние между верхом и центром дважды увеличится. Если масштабировать на -1, расстояние останется прежним, но верх будет там, где был низ, а низ – где был верх. Поздравляю, вы теперь знаете, как зеркалировать!

Размытие

Очень скоро все современные браузеры будут поддерживать фильтры -webkit-filter или фильтры SVG. FF, Opera и IE10 уже поддерживают последнее, Safari и Chrome пока только создают напряжение перед их выпуском. Одним из фильтров SVG является старое доброе Гауссово размытие (Gaussian Blur). Он развивается неторопливо, но это что-то…

Создайте файл «filter.svg» в той же папке, где style.css. Его содержимое:

<?xml version="1.0" standalone="no"?>
<svg width="1" height="1" version="1.1"
xmlns="http://www.w3.org/2000/svg"
xmlns:xlink="http://www.w3.org/1999/xlink">
  <defs>
    <filter id="blur">
      <feGaussianBlur in="SourceGraphic" stdDeviation="2 3" />
    </filter>
  </defs>
</svg>

Все как обычно, кроме правил с 6 по 8. Фильтр с названием «blur» (можете назвать его как хотите) размывает 2 px по горизонтали и 3 px по вертикали. А теперь обратно к таблице стилей!

#refl {
    position: absolute;
 
    top: 100%;
    left: 0;
 
    -moz-transform: scaleY(-1);
    -webkit-transform: scaleY(-1);
    -ms-transform: scaleY(-1);
 
    filter: url(filter.svg#blur); /* FF, IE10 & Opera */
    -webkit-filter: blur(2px);
}

filter.svg#blur означает элемент ‘blur’ in filter.svg. Если бы ID фильтра было ‘anything’, url был бы filter.svg#anything. Радиус размытия определяется в файле SVG. Браузеры Webkit определяют это все в одном правиле.

Прозрачность

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

#refl {
    position: absolute;
 
    top: 100%;
    left: 0;
 
    -moz-transform: scaleY(-1);
    -webkit-transform: scaleY(-1);
    -ms-transform: scaleY(-1);
 
    filter: url(filter.svg#blur); /* FF, IE10 & Opera */
    -webkit-filter: blur(2px);
 
    opacity: .25;
}

Я не могу вложить файл SVG в ссылку «Поиграть с образцом». (Должен держать образец в подчинении, поэтому не могу смешивать семантику и презентацию. Это сильно осложнило бы все…) Но сейчас я не возмещаю размытие SVG…

Поиграть с образцом | Полноэкранное изображение

Оно неполное. Когда на третий день Apple создал отражение, оно должно было стать менее отражательным. Оно должно быть менее четким, чем дальше оно от поверхности. Пусть там будет тьма!

Это работает, только если у поверхности есть плотный цвет, а цвет шрифта похож на него: мы затемним его, добавив другую тень блока. Эта тень блока переписывает старую в селекторе #ETBR, #refl. Мы противодействуем этому, повторно заявляя встроенную тень старого селектора. Вторая тень – это новая тень. Помните, что каждая добавленная к отражению тень зеркалируется.

#refl {
    position: absolute;
 
    top: 100%;
    left: 0;
 
    -moz-transform: scaleY(-1);
    -webkit-transform: scaleY(-1);
    -ms-transform: scaleY(-1);
 
    filter: url(filter.svg#blur); /* FF, Opera + IE10*/
    -webkit-filter: blur(2px); /* webkit */
 
    opacity: .25;
 
    box-shadow: inset rgba(0,0,0,.8) 0 0 20px, inset #000 0 50px 100px; /* first shadow is old */
}

Офсет Y второй тени равен 50 px, но элемент всегда зеркалируется после применения тени. Тень не движется вниз, она движется вверх.

Смотрите здесь:

Поиграть с образцом | Полноэкранное изображение

Отлично! Теперь рассмотрите это с помощью IE8 (или поверьте мне на слово): это в основном две копии отражаемого элемента ETBR одна над другой, незеркалированные, непрозрачные и не размытые.

Шаг 7: устаревшие фильтры

В начале работы мы добавили несколько условных комментариев; три группы.

— Современные браузеры и IE10, которые не поддерживают старые фильтры IE (IE10 прекратил сопровождение), но поддерживают новые.

— IE8 и ниже, старые IE, поддерживают устаревшие фильтры и не поддерживают новые.

— IE9, понемногу поддерживающий оба вида.

Если бы IE9 не поддерживал новых фильтров, было бы гораздо проще. (Не поймите меня неверно, я счастлив, что Internet Explorer старается измениться. Но было бы легче…) А чтобы еще все усложнить, существуют различия между устаревшими фильтрами в IE9 и IE8. Хватит жаловаться, давайте что-нибудь с этим сделаем. Добавьте для каждой группы по селектору #refl и сдвиньте свойство непрозрачности на modern.

#refl {
    position: absolute;
 
    top: 100%;
    left: 0;
 
    -moz-transform: scaleY(-1);
    -webkit-transform: scaleY(-1);
    -ms-transform: scaleY(-1);
 
    filter: url(filter.svg#blur); /* FF, Opera + IE10*/
    -webkit-filter: blur(2px); /* webkit */
 
    box-shadow: inset rgba(0,0,0,.8) 0 0 20px, inset #000 0 50px 100px;
}
.modern #refl {
    opacity: .25;
}
.ie9 #refl {
 
}
.oldie #refl {
 
}

Устаревшим фильтрам не нравится непрозрачность CSS2. И, если говорить о них, то мы собирается употребить следующие:

— DXImageTransform.Microsoft.BasicImage дает нам возможность зеркалировать изображение и меняет его непрозрачность

— DXImageTransform.Microsoft.MotionBlur и DXImageTransform.Microsoft.MotionBlur просто замечательные.

— DXImageTransform.Microsoft.Gradient в качестве заменителя второй тени блока.

Зеркалирование

У первого фильтра, BasicImage, на самом деле имеется свойство «mirror»! ДА-ДА! К сожалению, при установке этого свойства на 1 контент зеркалируется по горизонтали, а не вертикали. Но это не означает его бесполезность для нас. Разворот элемента на 180° и зеркалирование его по горизонтали – то же самое, что зеркалирование его по вертикали. И оно возможно:

.oldie #refl {
    filter: progid:DXImageTransform.Microsoft.BasicImage(mirror=1, rotation=2);
}

Этот разворот не измеряется в градусах: 0 – это 0°, 1 – это 90°, 2 – 180°, а 3 – это 270°. Этого требуют только браузеры-»старички». IE9 поддерживает -ms-transform.

Непрозрачность

Непрозрачность можно определять в том же фильтре…

.ie9 #refl {
    -ms-filter: "progid:DXImageTransform.Microsoft.BasicImage(opacity=.25);"
}
.oldie #refl {
    filter: progid:DXImageTransform.Microsoft.BasicImage(mirror=1, rotation=2,  opacity=.35);
}

IE9 (и IE8, но я считаю, что Internet Explorer уже получил достаточно внимания) поддерживает -ms-filter. Значение его – одна большая строка. Она создает понимание со стороны других браузеров (Firefox из-за Internet Explorer’а ходит по пятницам к психиатру).

Размытие

…но нам нужен новый фильтр для размытия. Множественные фильтры, если хотите, чтобы оно хорошо смотрелось. Никаких запятых, никаких filter:s между фильтрами, только промежуток или новая строка. -ms-filter больше не понимает новых строк…

.ie9 #refl {
    -ms-filter: "progid:DXImageTransform.Microsoft.BasicImage(opacity=.25) progid:DXImageTransform.Microsoft.Blur(PixelRadius='3', MakeShadow='false') progid:DXImageTransform.Microsoft.MotionBlur(strength=15, direction=0) progid:DXImageTransform.Microsoft.Blur(PixelRadius='3', MakeShadow='false');"
}
.oldie #refl {
    filter: progid:DXImageTransform.Microsoft.BasicImage(mirror=1, rotation=2, opacity=.35)
    progid:DXImageTransform.Microsoft.Blur(PixelRadius='3', MakeShadow='false')
    progid:DXImageTransform.Microsoft.MotionBlur(strength=15, direction=0)
    progid:DXImageTransform.Microsoft.Blur(PixelRadius='3', MakeShadow='false');
}

Если один раз сделать размытие с радиусом в 6 px, выглядит это так, будто кто-то сделал 4 копии отражения и сдвинул одну на 6 px вверх, одну на 6 px вниз, одну на 6 px влево и одну на 6 px вправо. Если хотите похвастать перед кем-нибудь в пабе, то должны знать название: размытие блока (Box Blur). При добавлении повторов (делая размытие размытого) Box Blur выглядит, как обычное размытие. Второй повтор – это размытие движения motion blur, потому что оно хорошо смотрится.

Поиграть с образцом | Полноэкранное изображение

На этот раз неверно получились не одна, а две вещи:

1. Размытие сдвинуло отражение на несколько пикселей вверх и вправо в IE9, но в IE8 сдвинуло отражение вниз. Почему? Остается тайной.

2. В IE7 и IE8 отражение везде одинаково прозрачное.

Сначала вторая проблема: так как браузеры-»старички» не поддерживают тень блока box-shadow, мы применим в качестве замены устаревшему альфа-градиенту. Это, насколько я знаю, первые значения типа RGBA в CSS, но если в спецификациях w3c что-либо вообще тогда было сказано о значениях rgba, Internet Explorer все прослушал. Вместо 6 шестнадцатеричных разрядов они использовали 8. Два первых представляют alpha; устаревшие градиенты принимают ARGB вместо RGBA, что, должен заметить, звучит гораздо лучше:

.ie9 #refl {
    -ms-filter: "progid:DXImageTransform.Microsoft.BasicImage(opacity=.25) progid:DXImageTransform.Microsoft.Blur(PixelRadius='3', MakeShadow='false') progid:DXImageTransform.Microsoft.MotionBlur(strength=15, direction=0) progid:DXImageTransform.Microsoft.Blur(PixelRadius='3', MakeShadow='false');"
}
.oldie #refl {
    filter: progid:DXImageTransform.Microsoft.Gradient(startColorstr=#99000000, endColorstr=#00000000)
    progid:DXImageTransform.Microsoft.BasicImage(mirror=1, rotation=2, opacity=.35)
    progid:DXImageTransform.Microsoft.Blur(PixelRadius='3', MakeShadow='false')
    progid:DXImageTransform.Microsoft.MotionBlur(strength=15, direction=0)
    progid:DXImageTransform.Microsoft.Blur(PixelRadius='3', MakeShadow='false');
}

Градиент тоже нужно размыть, так что этим займемся в первую очередь. Градиенты устаревших фильтров по умолчанию вертикальные. startColorstr — цвет градиента вверху, а startColorstr — цвет внизу, но он зеркалирован! #99000000 – то же, что rgba(0, 0, 0, 153). Помните: чем выше мы устанавливаем непрозрачность градиента, тем ниже становится непрозрачность отражения.

Расположение – всего лишь дело метода проб и ошибок. Так как у отражения уже имеется местоположение, установленное в процентном отношении, мы не можем настроить в пикселях с помощью свойств left и top. Вместо того мы применим поле:

.ie9 #refl {
    margin-top: 20px;
    margin-left: -10px;
 
    -ms-filter: "progid:DXImageTransform.Microsoft.BasicImage(opacity=.25) progid:DXImageTransform.Microsoft.Blur(PixelRadius='3', MakeShadow='false') progid:DXImageTransform.Microsoft.MotionBlur(strength=15, direction=0) progid:DXImageTransform.Microsoft.Blur(PixelRadius='3', MakeShadow='false');"
}
.oldie #refl {
    margin-top: -20px;
    margin-left: -7px;
 
    filter: progid:DXImageTransform.Microsoft.Gradient(startColorstr=#99000000, endColorstr=#00000000)
    progid:DXImageTransform.Microsoft.BasicImage(mirror=1, rotation=2, opacity=.35)
    progid:DXImageTransform.Microsoft.Blur(PixelRadius='3', MakeShadow='false')
    progid:DXImageTransform.Microsoft.MotionBlur(strength=15, direction=0)
    progid:DXImageTransform.Microsoft.Blur(PixelRadius='3', MakeShadow='false');
}

Поиграть с образцом | Полноэкранное изображение

Шаг 8: финальные штрихи

Мы изменим две вещи до того, как начнем тратить время на что-нибудь получше, типа просмотра чихающих панд на youtube.

— Расположим отражение по ту сторону отражаемого элемента (ETBR) (в z-пространстве), так как размытое отражение лежит над ETBR и над свечением.

— Сдвинем ETBR вниз. Верх ETBR идеально выравнивается по горизонту, что смотрится очень странно.

Решения проблемы:

— Обычно мы бы установили z-index отражаемого элемента (ETBR) и отражение соответственно на 2 и 1. Но так как за отражением в образце нет других элементов (в z-пространстве), мы можем просто установить z-index отражения на -1.

— Вверху поверхности добавьте отступ. Так как ETBR является потомком поверхности, он сдвинется вниз.

Вот файл CSS.

html {
    height: 100%;
}
body {
    text-align: center;
    line-height: 1;
    margin: 0;
    padding: 0;
    background-color: #000;
    height: 100%;
}
p {
    line-height: 1.2;
}
#plane {
    padding-top: 5%;
 
    left: 0;
    top: 10%;
    width: 100%;
    bottom: 0;
    min-width: 1080px;
    min-height: 600px;
    position: absolute;
    overflow: hidden;
    overflow-x: visible;
}
#ETBR, #refl {
    color: #004;
 
    font-family: Impact, 'Arial Black', Helvetica, Arial, sans-serif;
    text-transform: uppercase;
    font-size: 200px;
    background-color: #FFE;
    font-weight: bold;
    padding: 30px;
    display: inline-block;
 
    box-shadow: rgba(255,255,240,.2) 0 0 200px 100px, rgba(255,255,240,.3) 0 0 40px, inset rgba(0,0,0,.8) 0 0 20px;
    border-radius: 30px;
 
    position: relative;
}
#refl {
    position: absolute;
    z-index: -1;
 
    top: 100%;
    left: 0;
 
    -moz-transform: scaleY(-1);
    -webkit-transform: scaleY(-1);
    -ms-transform: scaleY(-1);
 
    filter: url(filter.svg#blur); /* FF, Opera + IE10*/
    -webkit-filter: blur(2px); /* webkit */
 
    box-shadow: inset rgba(0,0,0,.8) 0 0 20px, inset #000 0 50px 100px;
}
.modern #refl {
    opacity: .25;
}
.ie9 #refl {
    margin-top: 20px;
    margin-left: -10px;
 
    -ms-filter: "progid:DXImageTransform.Microsoft.BasicImage(opacity=.25) progid:DXImageTransform.Microsoft.Blur(PixelRadius='3', MakeShadow='false') progid:DXImageTransform.Microsoft.MotionBlur(strength=15, direction=0) progid:DXImageTransform.Microsoft.Blur(PixelRadius='3', MakeShadow='false');"
}
.oldie #refl {
    margin-top: -20px;
    margin-left: -7px;
 
    filter: progid:DXImageTransform.Microsoft.Gradient(startColorstr=#99000000, endColorstr=#00000000)
    progid:DXImageTransform.Microsoft.BasicImage(mirror=1, rotation=2, opacity=.35)
    progid:DXImageTransform.Microsoft.Blur(PixelRadius='3', MakeShadow='false')
    progid:DXImageTransform.Microsoft.MotionBlur(strength=15, direction=0)
    progid:DXImageTransform.Microsoft.Blur(PixelRadius='3', MakeShadow='false');
}

index.html

<!DOCTYPE html>
<html>
    <head>
        <meta charset="utf-8" />
        <meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1" />
        <title>CSS3 Reflections</title>
        <meta name="description" content="Reflection..." />
        <meta name="author" content="Bob de Ruiter" />
        <meta name="viewport" content="width=device-width; initial-scale=1.0" />
 
        <link rel="stylesheet" href="style.css" />
 
        <link rel="shortcut icon" href="/favicon.ico" />
        <link rel="apple-touch-icon" href="/apple-touch-icon.png" />
    </head>
    <!--[if lt IE 9 ]> <body class="oldie"> <![endif]-->
    <!--[if IE 9 ]> <body class="ie9"> <![endif]-->
    <!--[if (gt IE 9)|!(IE)]><!--> <body class="modern"> <!--<![endif]-->
        <div id="plane">
            <header><span id="ETBR">reflection<span id="refl">reflection</span></span></header>
        </div>
    </body>
</html>

filter.svg

<?xml version="1.0" standalone="no"?>
<svg width="1" height="1" version="1.1"
xmlns="http://www.w3.org/2000/svg"
xmlns:xlink="http://www.w3.org/1999/xlink">
  <defs>
    <filter id="blur">
      <feGaussianBlur in="SourceGraphic" stdDeviation="2 3" />
    </filter>
  </defs>
</svg>

Заключение

Вот и все! Вот последний образец, без размытия фильтра SVG.

Поиграть с образцом | Полноэкранное изображение

Вот дополнительно чистый CSS (кроме звездочек на фоне) Мак Дока (Mac Dock), применяющего ту же технику.

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

Автор: Bob de Ruiter

Источник: http://webdesign.tutsplus.com/

Редакция: Команда webformyself.

Учебник по основам CSS для начинающих

Прямо сейчас изучи CSS с нуля!

Смотреть курс

Метки:

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

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

Комментарии (4)

  1. Александр

    HTML5 И CSS3 ЭТО ВЕЩЬ!

  2. Алексей

    Здравствуйте! Перезалейте исходники по новому адресу, при скачивании выдает внутренняя ошибка сервиса.

  3. Сергей

    Кроссбраузерное решение предполагает поддержку в ИЕ (на сегодняшний день хотя бы до 8 версии включительно). В данном же решении в 9 ие не все так гладко (про восьмой вообще не говорим).

Добавить комментарий

Ваш e-mail не будет опубликован. Обязательные поля помечены *

Можно использовать следующие HTML-теги и атрибуты: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <strike> <strong>

Я не робот.

Spam Protection by WP-SpamFree