Мой старый эпилептичный шрифт, воссозданный средствами CSS3.
Стилей неприлично много. Основная проблема — у text-shadow
, в отличии от box-shadow
, отсутствует параметр spread
, позволяющий с помощью тени сделать обводку. Приходится имитировать обводку восьмью тенями.
Кроме того, нельзя задать отдельно только цвет тени, поэтому каждый блок из восьми теней приходится повторять в каждом ключевом кадре анимации.
Одно хорошо: последняя Опера на Presto и последний Фаерфокс понимают анимации без префиксов, а ИЕ10 изначально не нуждался в префиксе. Остается только префикс -webkit
.
Чтобы буквы дребезжали вразнобой, каждой букве выдан рандомный класс. Всего 8 классов (по одному на каждый шаг анимации), каждый с animation-delay
равным длине шага анимации, умноженной на номер класса.
Плавность анимации можно настроить количеством шагов анимации между ключевыми кадрами. Чем больше шагов, тем плавнее анимация:
-webkit-animation-timing-function: steps(1);
animation-timing-function: steps(1);
Для непрерывной анимации steps()
заменяем на linear
(или просто стираем animation-timing-function
, так как linear
используется по умолчанию).
Сила "дребезжания" букв немного варьируется от браузера к браузеру. Я настраивал по Хрому, в других на глаз дребезжит потише. После очередного обновления у Хрома теперь как у всех. Вот и отлично.
В номинации «четкий, дерзкий» среди мобилок побеждает IE10 на винфоне. Анимирует что надо. На слабеньких мобильных вебкитах постоянно сбивается рассинхронизация и фреймрейт в целом весьма тосклив. Самая жесть в Опере Классик на Андроиде (как, впрочем, и на десктопе).
HTML:
<div class="pepyaka async">
<span class="pep5">Я</span><span class="pep2">р</span><span class="pep7">р</span><span class="pep3">р</span><span class="pep0">!</span>
</div>
CSS:
.pepyaka {
font-family: 'Book Antiqua', 'Georgia', serif;
-webkit-transform: translate3d(0,0,0);
transform: translate3d(0,0,0);
}
.pepyaka > * {
display: inline-block;
font-size: 3.5em;
letter-spacing: 0.2em;
-webkit-animation-duration: 0.4s;
animation-duration: 0.4s;
-webkit-animation-iteration-count: infinite;
animation-iteration-count: infinite;
-webkit-animation-timing-function: steps(1);
animation-timing-function: steps(1);
-webkit-animation-name: pep;
animation-name: pep;
color: #1be5a0;
text-shadow: -0.05em 0 0 #000000,
-0.03em -0.03em 0 #000000,
0 -0.05em 0 #000000,
0.03em -0.03em 0 #000000,
0.05em 0 0 #000000,
0.03em 0.03em 0 #000000,
0 0.05em 0 #000000,
-0.03em 0.03em 0 #000000;
}
.pepyaka.smooth > * {
-webkit-animation-timing-function: linear;
animation-timing-function: linear;
}
@-webkit-keyframes pep {
from {
color: #1be5a0;
text-shadow: -0.05em 0 0 #000000,
-0.03em -0.03em 0 #000000,
0 -0.05em 0 #000000,
0.03em -0.03em 0 #000000,
0.05em 0 0 #000000,
0.03em 0.03em 0 #000000,
0 0.05em 0 #000000,
-0.03em 0.03em 0 #000000;
-webkit-transform: translate(0.037em,-0.037em);
}
12.5% {
color: #b33aff;
text-shadow: -0.05em 0 0 #1be5a0,
-0.03em -0.03em 0 #1be5a0,
0 -0.05em 0 #1be5a0,
0.03em -0.03em 0 #1be5a0,
0.05em 0 0 #1be5a0,
0.03em 0.03em 0 #1be5a0,
0 0.05em 0 #1be5a0,
-0.03em 0.03em 0 #1be5a0;
-webkit-transform: translate(-0.05em,0.06em);
}
25% {
color: #fffe00;
text-shadow: -0.05em 0 0 #b33aff,
-0.03em -0.03em 0 #b33aff,
0 -0.05em 0 #b33aff,
0.03em -0.03em 0 #b33aff,
0.05em 0 0 #b33aff,
0.03em 0.03em 0 #b33aff,
0 0.05em 0 #b33aff,
-0.03em 0.03em 0 #b33aff;
-webkit-transform: translate(-0.037em,-0.075em);
}
37.5% {
color: #f12938;
text-shadow: -0.05em 0 0 #fffe00,
-0.03em -0.03em 0 #fffe00,
0 -0.05em 0 #fffe00,
0.03em -0.03em 0 #fffe00,
0.05em 0 0 #fffe00,
0.03em 0.03em 0 #fffe00,
0 0.05em 0 #fffe00,
-0.03em 0.03em 0 #fffe00;
-webkit-transform: translate(0.037em,-0.037em);
}
50% {
color: #62e51b;
text-shadow: -0.05em 0 0 #f12938,
-0.03em -0.03em 0 #f12938,
0 -0.05em 0 #f12938,
0.03em -0.03em 0 #f12938,
0.05em 0 0 #f12938,
0.03em 0.03em 0 #f12938,
0 0.05em 0 #f12938,
-0.03em 0.03em 0 #f12938;
-webkit-transform: translate(0,0);
}
62.5% {
color: #2751ef;
text-shadow: -0.05em 0 0 #62e51b,
-0.03em -0.03em 0 #62e51b,
0 -0.05em 0 #62e51b,
0.03em -0.03em 0 #62e51b,
0.05em 0 0 #62e51b,
0.03em 0.03em 0 #62e51b,
0 0.05em 0 #62e51b,
-0.03em 0.03em 0 #62e51b;
-webkit-transform: translate(-0.075em,-0.018em);
}
75% {
color: #ffc600;
text-shadow: -0.05em 0 0 #2751ef,
-0.03em -0.03em 0 #2751ef,
0 -0.05em 0 #2751ef,
0.03em -0.03em 0 #2751ef,
0.05em 0 0 #2751ef,
0.03em 0.03em 0 #2751ef,
0 0.05em 0 #2751ef,
-0.03em 0.03em 0 #2751ef;
-webkit-transform: translate(0.057em,-0.057em);
}
87.5% {
color: #000000;
text-shadow: -0.05em 0 0 #ffc600,
-0.03em -0.03em 0 #ffc600,
0 -0.05em 0 #ffc600,
0.03em -0.03em 0 #ffc600,
0.05em 0 0 #ffc600,
0.03em 0.03em 0 #ffc600,
0 0.05em 0 #ffc600,
-0.03em 0.03em 0 #ffc600;
-webkit-transform: translate(-0.060em,0.060em);
}
to {
color: #1be5a0;
text-shadow: -0.05em 0 0 #000000,
-0.03em -0.03em 0 #000000,
0 -0.05em 0 #000000,
0.03em -0.03em 0 #000000,
0.05em 0 0 #000000,
0.03em 0.03em 0 #000000,
0 0.05em 0 #000000,
-0.03em 0.03em 0 #000000;
-webkit-transform: translate(0.018em,-0.018em);
}
}
@keyframes pep {
from {
color: #1be5a0;
text-shadow: -0.05em 0 0 #000000,
-0.03em -0.03em 0 #000000,
0 -0.05em 0 #000000,
0.03em -0.03em 0 #000000,
0.05em 0 0 #000000,
0.03em 0.03em 0 #000000,
0 0.05em 0 #000000,
-0.03em 0.03em 0 #000000;
transform: translate(0.037em,-0.037em);
}
12.5% {
color: #b33aff;
text-shadow: -0.05em 0 0 #1be5a0,
-0.03em -0.03em 0 #1be5a0,
0 -0.05em 0 #1be5a0,
0.03em -0.03em 0 #1be5a0,
0.05em 0 0 #1be5a0,
0.03em 0.03em 0 #1be5a0,
0 0.05em 0 #1be5a0,
-0.03em 0.03em 0 #1be5a0;
transform: translate(-0.05em,0.06em);
}
25% {
color: #fffe00;
text-shadow: -0.05em 0 0 #b33aff,
-0.03em -0.03em 0 #b33aff,
0 -0.05em 0 #b33aff,
0.03em -0.03em 0 #b33aff,
0.05em 0 0 #b33aff,
0.03em 0.03em 0 #b33aff,
0 0.05em 0 #b33aff,
-0.03em 0.03em 0 #b33aff;
transform: translate(-0.037em,-0.075em);
}
37.5% {
color: #f12938;
text-shadow: -0.05em 0 0 #fffe00,
-0.03em -0.03em 0 #fffe00,
0 -0.05em 0 #fffe00,
0.03em -0.03em 0 #fffe00,
0.05em 0 0 #fffe00,
0.03em 0.03em 0 #fffe00,
0 0.05em 0 #fffe00,
-0.03em 0.03em 0 #fffe00;
transform: translate(0.037em,-0.037em);
}
50% {
color: #62e51b;
text-shadow: -0.05em 0 0 #f12938,
-0.03em -0.03em 0 #f12938,
0 -0.05em 0 #f12938,
0.03em -0.03em 0 #f12938,
0.05em 0 0 #f12938,
0.03em 0.03em 0 #f12938,
0 0.05em 0 #f12938,
-0.03em 0.03em 0 #f12938;
transform: translate(0,0);
}
62.5% {
color: #2751ef;
text-shadow: -0.05em 0 0 #62e51b,
-0.03em -0.03em 0 #62e51b,
0 -0.05em 0 #62e51b,
0.03em -0.03em 0 #62e51b,
0.05em 0 0 #62e51b,
0.03em 0.03em 0 #62e51b,
0 0.05em 0 #62e51b,
-0.03em 0.03em 0 #62e51b;
transform: translate(-0.075em,-0.018em);
}
75% {
color: #ffc600;
text-shadow: -0.05em 0 0 #2751ef,
-0.03em -0.03em 0 #2751ef,
0 -0.05em 0 #2751ef,
0.03em -0.03em 0 #2751ef,
0.05em 0 0 #2751ef,
0.03em 0.03em 0 #2751ef,
0 0.05em 0 #2751ef,
-0.03em 0.03em 0 #2751ef;
transform: translate(0.057em,-0.057em);
}
87.5% {
color: #000000;
text-shadow: -0.05em 0 0 #ffc600,
-0.03em -0.03em 0 #ffc600,
0 -0.05em 0 #ffc600,
0.03em -0.03em 0 #ffc600,
0.05em 0 0 #ffc600,
0.03em 0.03em 0 #ffc600,
0 0.05em 0 #ffc600,
-0.03em 0.03em 0 #ffc600;
transform: translate(-0.060em,0.060em);
}
to {
color: #1be5a0;
text-shadow: -0.05em 0 0 #000000,
-0.03em -0.03em 0 #000000,
0 -0.05em 0 #000000,
0.03em -0.03em 0 #000000,
0.05em 0 0 #000000,
0.03em 0.03em 0 #000000,
0 0.05em 0 #000000,
-0.03em 0.03em 0 #000000;
transform: translate(0.018em,-0.018em);
}
}
/*
Async wobbling styles
Defining different colors and shadows for each `pep` class isn't
necessary, but it gives colorful letters at the start, while waiting
for initial `animation-delay` to pass.
They can be omitted at the price of
same-colored letters at the start of the animation.
*/
.async .pep0 {
/* nothing here */
}
.async .pep1 {
-webkit-animation-delay: 0.05s;
animation-delay: 0.05s;
color: #b33aff;
text-shadow: -0.05em 0 0 #1be5a0,
-0.03em -0.03em 0 #1be5a0,
0 -0.05em 0 #1be5a0,
0.03em -0.03em 0 #1be5a0,
0.05em 0 0 #1be5a0,
0.03em 0.03em 0 #1be5a0,
0 0.05em 0 #1be5a0,
-0.03em 0.03em 0 #1be5a0;
}
.async .pep2 {
-webkit-animation-delay: 0.1s;
animation-delay: 0.1s;
color: #fffe00;
text-shadow: -0.05em 0 0 #b33aff,
-0.03em -0.03em 0 #b33aff,
0 -0.05em 0 #b33aff,
0.03em -0.03em 0 #b33aff,
0.05em 0 0 #b33aff,
0.03em 0.03em 0 #b33aff,
0 0.05em 0 #b33aff,
-0.03em 0.03em 0 #b33aff;
}
.async .pep3 {
-webkit-animation-delay: 0.15s;
animation-delay: 0.15s;
color: #f12938;
text-shadow: -0.05em 0 0 #fffe00,
-0.03em -0.03em 0 #fffe00,
0 -0.05em 0 #fffe00,
0.03em -0.03em 0 #fffe00,
0.05em 0 0 #fffe00,
0.03em 0.03em 0 #fffe00,
0 0.05em 0 #fffe00,
-0.03em 0.03em 0 #fffe00;
}
.async .pep4 {
-webkit-animation-delay: 0.2s;
animation-delay: 0.2s;
color: #62e51b;
text-shadow: -0.05em 0 0 #f12938,
-0.03em -0.03em 0 #f12938,
0 -0.05em 0 #f12938,
0.03em -0.03em 0 #f12938,
0.05em 0 0 #f12938,
0.03em 0.03em 0 #f12938,
0 0.05em 0 #f12938,
-0.03em 0.03em 0 #f12938;
}
.async .pep5 {
-webkit-animation-delay: 0.25s;
animation-delay: 0.25s;
color: #2751ef;
text-shadow: -0.05em 0 0 #62e51b,
-0.03em -0.03em 0 #62e51b,
0 -0.05em 0 #62e51b,
0.03em -0.03em 0 #62e51b,
0.05em 0 0 #62e51b,
0.03em 0.03em 0 #62e51b,
0 0.05em 0 #62e51b,
-0.03em 0.03em 0 #62e51b;
}
.async .pep6 {
-webkit-animation-delay: 0.3s;
animation-delay: 0.3s;
color: #ffc600;
text-shadow: -0.05em 0 0 #2751ef,
-0.03em -0.03em 0 #2751ef,
0 -0.05em 0 #2751ef,
0.03em -0.03em 0 #2751ef,
0.05em 0 0 #2751ef,
0.03em 0.03em 0 #2751ef,
0 0.05em 0 #2751ef,
-0.03em 0.03em 0 #2751ef;
}
.async .pep7 {
-webkit-animation-delay: 0.35s;
animation-delay: 0.35s;
color: #000000;
text-shadow: -0.05em 0 0 #ffc600,
-0.03em -0.03em 0 #ffc600,
0 -0.05em 0 #ffc600,
0.03em -0.03em 0 #ffc600,
0.05em 0 0 #ffc600,
0.03em 0.03em 0 #ffc600,
0 0.05em 0 #ffc600,
-0.03em 0.03em 0 #ffc600;
}