Эффект Glitch Лукаса Беббера выглядит очень круто — как будто вы смотрите на текст на старом мониторе, который слишком часто роняли на пол и у него «плавает» вертикальная синхронизация и сведение.
Реализация этого эффекта на CSS выглядит вполне убедительно. Мне пришлось немного поломать голову, чтобы выяснить, как он работает, и теперь я хочу объяснить это вам. Кроме того, я воспроизвёл этот эффект не только для текста, но и для растровых изображений и SVG, а так же написал несколько примесей Sass, чтобы облегчить работу с ним.

HTML для этого примера выглядит просто:
С помощью псевдоэлементов создаются две дополнительные копии основного элемента, которыми можно управлять индивидуально:
Все три копии текста расположены друг над другом:

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

Пока что нам видна только самая верхняя из трёх копий. Скорее всего, это версия
У
Вот как может выглядеть результат обрезки, для наглядности фон сделан непрозрачным и слои смещены друг относительно друга:

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

Я подумал, что хорошо бы добавить этому эффекту возможность удобного повторного использования. Например, написать примесь Sass с параметрами, с помощью которых можно контролировать эффект:
Вот что у меня получилось:
Конечно, можно придумать ещё миллион способов, как реализовать эту примесь — всё зависит от того, какие параметры вы хотите настраивать, какая у вас разметка HTML и т.д.
Я также написал ещё две примеси, одну для растровых изображений, вторую — для SVG. Они отличаются деталями реализации — там не используются псевдоэлементы, смещение и цветной ореол тоже делаются по-другому и т.д. Вот все три примеси в одном файле. А вот так выглядит их работа:

Реализация этого эффекта на CSS выглядит вполне убедительно. Мне пришлось немного поломать голову, чтобы выяснить, как он работает, и теперь я хочу объяснить это вам. Кроме того, я воспроизвёл этот эффект не только для текста, но и для растровых изображений и SVG, а так же написал несколько примесей Sass, чтобы облегчить работу с ним.

Три копии текста
HTML для этого примера выглядит просто:
<div class="glitch" data-text="GLITCH">GLITCH</div>
С помощью псевдоэлементов создаются две дополнительные копии основного элемента, которыми можно управлять индивидуально:
.glitch { position: relative; } .glitch::before, .glitch::after { content: attr(data-text); position: absolute; top: 0; left: 0; width: 100%; height: 100%; }
Все три копии текста расположены друг над другом:

Изменяем копии
Каждая из дополнительных копий идентична оригиналу за исключением того, что:
- они смещены влево или вправо;
- У них есть цветной ореол, созданный с помощью
text-shadow.
Именно смещение и ореол служат основой для эффекта неисправного монитора.
.glitch::before { /* ... всё, что нужно, чтобы сделать слой идентичным оригиналу */ /* отличия от оригинала */ left: 2px; text-shadow: -1px 0 red; /* Важно: непрозрачный фон закрывает предыдущий слой */ background: black; } .glitch::after { /* ... всё, что нужно, чтобы сделать слой идентичным оригиналу */ /* отличия от оригинала */ left: -2px; text-shadow: -1px 0 blue; /* Важно: непрозрачный фон закрывает предыдущий слой */ background: black; }
Теперь наши три копии выглядят так:

Обрезаем копии
Пока что нам видна только самая верхняя из трёх копий. Скорее всего, это версия
::after, если только вы не меняли z-index. Но это не важно, так как мы будем попеременно показывать части всех трёх копий с помощью свойства clip. В данный момент это свойство уже считается устаревшим, его должно заменить clip-path, но на момент написания статьи именно свойство clip работало лучше. Конечно, со временем это изменится, так что нужно иногда поглядывать на ситуацию. В случае чего, их легко будет поменять, например, с помощью Autoprefixer.У
clip довольно странный синтаксис. Требуются четыре значения, логично было бы предположить, что это координаты верхнего левого угла и длина с шириной, или координаты верхнего левого и нижнего правого углов, но вместо этого числа означают отступы, как в свойствах margin или padding (top/right/bottom/left)..glitch::before { clip: rect(44px, 450px, 56px, 0); /* Получился прямоугольник с верхним левым углом 0, 44px и нижним правым 450px, 56px */ }
Вот как может выглядеть результат обрезки, для наглядности фон сделан непрозрачным и слои смещены друг относительно друга:

Анимируем обрезку
Для свойства
clip можно использовать анимации CSS, меняя положение обрезающего прямоугольника. Вот пример такой анимации:@keyframes glitch-anim { 0% { clip: rect(70px, 450px, 76px, 0); } 20% { clip: rect(29px, 450px, 16px, 0); } 40% { clip: rect(76px, 450px, 3px, 0); } 60% { clip: rect(42px, 450px, 78px, 0); } 80% { clip: rect(15px, 450px, 13px, 0); } 100% { clip: rect(53px, 450px, 5px, 0); } }
Обратите внимание, что левый и правый край остаются неизменными, меняются только верхний и нижний край. И эти значения выбраны совершенно произвольно. С помощью Sass вполне можно генерировать их случайным образом:
@keyframes glitch-anim { $steps: 10; @for $i from 0 through $steps { #{percentage($i*(1/$steps))} { clip: rect(random(100)+px, 9999px, random(100)+px, 0); } } }
Так как нам понадобятся два набора случайных обрезающих прямоугольников, надо будет сделать два набора ключевых кадров и применить их к двум копиям:
.glitch::before { ... animation: glitch-anim-1 2s infinite linear alternate-reverse; } .glitch::after { ... animation: glitch-anim-2 2s infinite linear alternate-reverse; }
В этом месте мы можем отрегулировать скорость анимации зациклить её. Эффект готов:

Примеси Sass
Я подумал, что хорошо бы добавить этому эффекту возможность удобного повторного использования. Например, написать примесь Sass с параметрами, с помощью которых можно контролировать эффект:
.example-one { font-size: 100px; @include textGlitch("example-one", 17, white, black, red, blue, 450, 115); }
Вот что у меня получилось:
/* (TEXT) PARAMS ================= 1. Namespace 2. Intensity 3. Text color 4. Background color (flat) 5. Highlight #1 color 6. Highlight #2 color 7. Width (px) 8. Height (px) */ @mixin textGlitch($name, $intensity, $textColor, $background, $highlightColor1, $highlightColor2, $width, $height) { color: $textColor; position: relative; $steps: $intensity; // Ensure the @keyframes are generated at the root level @at-root { // We need two different ones @for $i from 1 through 2 { @keyframes #{$name}-anim-#{$i} { @for $i from 0 through $steps { #{percentage($i*(1/$steps))} { clip: rect( random($height)+px, $width+px, random($height)+px, 0 ); } } } } } &:before, &:after { content: attr(data-text); position: absolute; top: 0; left: 0; width: 100%; background: $background; clip: rect(0, 0, 0, 0); } &:after { left: 2px; text-shadow: -1px 0 $highlightColor1; animation: #{$name}-anim-1 2s infinite linear alternate-reverse; } &:before { left: -2px; text-shadow: 2px 0 $highlightColor2; animation: #{$name}-anim-2 3s infinite linear alternate-reverse; } }
Конечно, можно придумать ещё миллион способов, как реализовать эту примесь — всё зависит от того, какие параметры вы хотите настраивать, какая у вас разметка HTML и т.д.
Я также написал ещё две примеси, одну для растровых изображений, вторую — для SVG. Они отличаются деталями реализации — там не используются псевдоэлементы, смещение и цветной ореол тоже делаются по-другому и т.д. Вот все три примеси в одном файле. А вот так выглядит их работа:

