Найти в Дзене
Журнал «Код»

Проглючило: делаем глитч-эффект на SASS

На это можно смотреть бесконечно.
Иногда на модных сайтах и в рекламных роликах можно встретить интересный эффект. Текст как будто немного нестабилен: дрожит, странно моргает и как-то сдвигается и сразу возвращается на место. Как будто кто-то теребит кабель подключения монитора. Это называется глитч, от английского glitch — сбой или глюк.
Сегодня мы сделаем нечто подобное, используя препроцессор
Оглавление

На это можно смотреть бесконечно.

Иногда на модных сайтах и в рекламных роликах можно встретить интересный эффект. Текст как будто немного нестабилен: дрожит, странно моргает и как-то сдвигается и сразу возвращается на место. Как будто кто-то теребит кабель подключения монитора. Это называется глитч, от английского glitch — сбой или глюк.

Сегодня мы сделаем нечто подобное, используя препроцессор SASS — один из любимых инструментов фронтенд-разработчиков. Формат записи выберем SCSS — так процесс будет выглядеть проще и понятнее. Заодно и попрактикуемся в новом языке.

О препроцессорах мы писали буквально вчера. Сам глитч-эффект выглядит примерно так:

-2

Как мы это сделаем

  1. Нам понадобится простая HTML-страница, на которой мы разместим текст.
  2. Этот текст мы поместим в специальный блок <div>, к которому будем применять глитч-эффекты. Чтобы CSS понял, с чем ему нужно работать, у блока должно быть имя.
  3. Настроим CSS-стили. Так браузер поймёт, как ему нужно отобразить этот текст, чтобы проявилась магия глитча.
  4. Работать с CSS будем с помощью препроцессора SASS — это почти тот же CSS, только с дополнительными возможностями.

👉 Важное замечание: SCSS-код нельзя просто вставить в HTML-страницу — браузер не поймёт, что вы имели в виду, и будет обрабатывать это как обычный CSS-код. Когда работают с препроцессорами, перед публикацией страницы код преобразуют в привычный CSS-формат, который и вставляют в раздел <style> или сохраняют как обычный .css-файл. Чтобы вы могли вставить готовый код, мы сами преобразуем его из SCSS в CSS и выложим в конце статьи.

Готовим HTML-код

Самый простой этап. Мы просто берём наш шаблон пустой страницы и вставляем в него заголовок <h1>:

-3

Делаем специальную разметку

У нас пока на странице есть просто заголовок первого уровня. Но для глитч-эффекта нужно этот заголовок поместить в блок <div> и дать ему новый класс, он будет отвечать за эффект в целом. Сами визуальные фишки мы пропишем во вложенном элементе <h1>, которому тоже присвоим новый класс.

Сделаем это так:

<div class="box">
  <h1 class="glitch">
    Журнал «КОД»
  </h1>
</div>

Теперь нужно настроить внешний вид страницы и добавить сами эффекты.

Настраиваем внешний вид страницы

Чтобы эффект был похож на тот, что мы видели на картинке в самом начале, сделаем фон чёрным, а текст — белым и выровняем по центру:

Что тут происходит:

  1. Так как это препроцессор, то мы используем упрощённый способ записи CSS-кода.
  2. Звёздочка в самом начале говорит о том, что эти стили применяются к каждому элементу, чтобы ни у кого не было отступов.
  3. После этого мы задали стили для всего документа и содержимого страницы — сказали, что проект должен занимать всё свободное пространство в окне браузера.
  4. Отдельно указали, что фон должен быть чёрным.
  5. Рассказали браузеру, как должен выглядеть блок с классом box.
  6. Внутри класса box мы объявили класс glitch — он у нас отвечает за стиль самого заголовка. В нём мы прописали белый цвет для текста и сделали его жирнее, но это не всё, что там должно быть. Остальное добавим на следующем шаге.
-4

Всё статично и не движется.

Как устроен глитч-эффект

Чтобы добиться эффекта искажения, разработчики используют псевдоклассы :before и :after — они показывают тот же самый текст, но позади или спереди основного, который у нас прописан в <h1>. Псевдоэлемент означает, что его как бы нет на самом деле, но браузер может с ним работать так, как будто он есть.

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

Запишем то, что мы только что сказали, на SCSS, и сделаем это внутри класса glitch:

Что тут происходит:

  1. Задали общие свойства для псевдоэлементов — текст, который совпадает с текстом нашего заголовка, его цвет и отступ в 30 пикселей, как в родительском классе выше.
  2. Там же сказали, что местоположение этих псевдоэлементов будет абсолютным, то есть можно будет указывать в пикселях, на сколько его можно сместить в любую сторону.
  3. Hidden означает, что тексту нельзя будет вылезать за пределы нашего заголовка, чтобы эффект получился какой нужно.
  4. Дальше мы описали сами псевдоэлементы &:before и &:after уже по отдельности.
  5. Первому мы сказали, что он сдвинется влево на 3 пикселя, отбросит тень на три пикселя вправо и настроили анимацию: он сделает это на 2 секунды, а потом снова станет обычным элементом. У нас стоит бесконечное повторение, но визуально мы пока этого не заметим.
  6. Второму мы сказали то же самое, но про синий цвет и про смещение влево.
-5

Из-за того, что мы не настроили пока полноценный эффект, получилась такая штука: текст псевдоэлемента :before уехал вниз и сломал всю картинку.

Финал: оживляем текст

Чтобы добавить огня, используем знакомый нам по JavaScript цикл @for. Его нет в стандартном CSS, но мы же используем препроцессоры, поэтому не будем себя ограничивать.

Нам понадобится команда @keyframes — она отвечает в CSS за раскадровку анимации. Проще говоря, если мы зададим кадры с параметрами 0%, 50% и 100%, то у нас в начале, середине и конце анимации могут быть разные картинки.

Задача такая: нужно сделать анимацию из 20 кадров для каждого элемента, чтобы любой кадр немного отличался от остальных. Это даст тот самый рваный и непредсказуемый эффект, который нам нужен. Для этого мы в цикле прогоним переменную i от 0 до 20, чтобы получился 21 кадр, и каждый кадр отрисуем в прямоугольнике со случайными начальными координатами, чтобы усилить эффект:

Что тут происходит:

  1. Мы задали отдельную раскадровку для каждого из двух псевдоэлементов.
  2. Анимация каждого такого элемента будет состоять из 21 кадра (20 + нулевой начальный).
  3. В цикле @for мы задаём раскадровку с шагом в 5% (1/20).
  4. На каждом проходе цикла рисуем виртуальный прямоугольник со случайными координатами по высоте. Этот прямоугольник как бы «обрезает» проглючившую надпись (от английского clip), то есть глючная версия надписи прорывается кусками.
  5. Значение в 780 пикселей нужно для того, чтобы эффект зацепил всю надпись. Если будет меньше, то последние символы останутся без эффектов.
-6

Готовый SCSS-код:

Сконвертированный CSS-код, который можно добавить на страницу

Что дальше

Чтобы было интереснее, мы составили для вас список вопросов на подумать. Каждый ответ делает вас круче как специалиста, поэтому постарайтесь ответить на все:

  1. Почему пробел убирает один из эффектов со второго слова?
  2. Что будет, если у виртуального прямоугольника поменять координаты?
  3. А если убрать случайные значения из цикла?
  4. Что будет, если поменять местами порядок псевдоэлементов?
  5. Как применить этот эффект к конкретной букве?