Blur-эффект на чистом css

В CSS3 есть множество новых свойств, которые могут значительно ускорить вёрстку тех или иных элементов страницы. Например, css-фильтры, об одном из которых сегодня предлагается поговорить.

Каждый из нас хотя бы раз имел возможность наблюдать эффект размытия на странице. Зачастую для его создания используется jQuery-библиотека bjurjs. Однако, не на всех сайтах целесообразно использовать jQuery, да и технологии не стоят на месте: теперь мы можем воспользоваться решением на чистом CSS. Попробуем?

Пример простейшей разметки:

<!doctype html>
<html lang="en">
  <head>
    <meta charset="UTF-8"/>
    <title>Blur</title>
    <link href="style.css" rel="stylesheet"/>
  </head>

  <body>
    <main class="wrapper">
      <div class="blur"></div>
      <div class="inner-wrapper">
        <h2>Welcome to our website!</h2>
      </div>
    </main>
  </body>

</html>

Итак, задан родительский div с классом wrapper, служащий контейнером для двух вложенных div'ов: inner-wrapper будет содержать текст приветствия, а blur — изображение, к которому нужно применить эффект размытия.

Обратимся к стилям.

.wrapper {
  position: relative;
  width: 500px;
  height: 500px;
  margin: 0 auto;
}

.inner-wrapper,
.blur {
  position: absolute;
  width: 500px;
  height: 300px;
  left: 0;
  top: 0;
  bottom: 0;
  right: 0;
}

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

.inner-wrapper {
  z-index: 100;
  color: #fff;
  text-align: center;
  text-shadow: 0 0 5px rgba(0,0,0,.5);
}

.blur {
  z-index: 99;
  background-image: url(image.png);
  background-size: cover;
  background-repeat: no-repeat;
}

На данный момент получаем простейшую страничку с картинкой и текстом:

"Без эффекта размытия"

Настало время применить магию! Увы, firefox пока не поддерживает css-фильтры, поэтому в дело пойдёт небольшой трюк: нужно «скормить» ему svg-файл со следующим содержимым:

<!-- blur.svg -->
<svg version="1.1" xmlns="http://www.w3.org/2000/svg">
  <filter id="blur">
    <feGaussianBlur stdDeviation="5"/>
  </filter>
</svg>

и указать путь к этому файлу, а также обратиться к нужному фильтру. В нашем случае фильтр всего один: тот, что определён под id blur. Вот как должен быть преобразован css-код для получения эффекта размытия:

.inner-wrapper {
  z-index: 100; /* текст не размыт */
  color: #fff;
  text-align: center;
  text-shadow: 0 0 5px rgba(0,0,0,.5);
}

.blur {
  z-index: 99; /* изображение размыто */
  background-image: url(image.png);
  background-size: cover;
  background-repeat: no-repeat;
  -webkit-filter: blur(5px);
  -moz-filter: blur(5px);
  filter: blur(5px);
  filter: url('blur.svg#blur'); /* путь к svg */
}

А вот и итоговый вариант с применением эффекта размытия:

"Эффект blur в действии"

Единственный недостаток: нечёткие границы размытия, которые выходят за пределы родительского элемента. Часто такой побочный эффект может быть нежелательным. Ну, что ж, можно поиграть с радиусом размытия или применить overflow: hidden.