CSS-анимации

На собеседованиях я часто спрашивал, какие CSS-свойства можно анимировать. Почему-то многих он ставил в тупик, кто-то вспоминал отдельные свойства, но сформулировать общее правило не получалось. А ведь всё довольно просто. Что вообще такое «анимация»? Это некое изменение внешнего вида, имеющее промежуточные положения, благодаря чему изменение происходит плавно, а не дискретно. У чего бывают промежуточные состояния? У всего, что можно измерить числами. Это может быть ширина объекта, его отступ, да даже цвет: будь то hex, rgba и пр., это всё числа. И нельзя анимировать display, имеющий определённый набор свойств.

Следующим был вопрос о стоимости анимации, какие же свойства можно использовать со спокойной душой, а с какими надо быть осторожными. Здесь достаточно запомнить три свойства: transform, opacity и filter (c которым не всё так просто).

Если у нас есть некий элемент, который мы хотим подвигать туда-сюда, то почему же его двигать лучше при помощи transform, а не left, margin или чего-то ещё?

Выставление рейтинга

Несколько лет назад я реализовывал подобный элемент — выставление рейтинга пользователем. И вот вновь столкнулся с подобной задачей. Но вариант копирования решения со старого проекта не рассматривался, ведь там просто сборище дивов и куча jQuery (а по-другому я и не умел). Поэтому, начал рассуждать, как сделать лучше.

Интерактивная карта в одном SVG

Сделал интерактивную карту Канады, состоящей из 10 провинций и 3 территорий. Небольшой блок с информацией появляется при наведении на административную единицу.
Никаких скриптов и дополнительных тегов, всё в одном встроенном SVG.

Alberta Capital:Land area:Population:GDP: Edmonton640,081 km²4,306,039$314.944 billion British Columbia Capital:Land area:Population:GDP: Victoria925,186 km²4,841,078$263.706 billion Manitoba Capital:Land area:Population:GDP: Winnipeg548,360 km²1,343,371$67.863 billion New Brunswick Capital:Land area:Population:GDP: Fredericton71,450 km²760,868$34.224 billion Newfoundland and Labrador Capital:Land area:Population:GDP: St. John's373,872 km²528,817$31.112 billion Nova Scotia Capital:Land area:Population:GDP: Halifax52,942 km²957,600$41.726 billion Northwest Territories Capital:Land area:Population:GDP: Yellowknife1,183,085 km²44,718$4.739 billion Nunavut Capital:Land area:Population:GDP: Iqaluit1,877,787 km²38,243$2.443 billion Ontario Capital:Land area:Population:GDP: Toronto917,741 km²14,279,196$794.835 billion Prince Edward Island Capital:Land area:Population:GDP: Charlottetown5,660 km²152,784$6.321 billion Quebec Capital:Land area:Population:GDP: Quebec City1,365,128 km²8,356,851$394.819 billion Saskatchewan Capital:Land area:Population:GDP: Regina591,670 km²1,168,057$75,261 billion Yukon Capital:Land area:Population:GDP: Whitehorse474,391 km²38,669$2.800 billion

Небольшой трюк с SVG

Рассмотрим ситуацию, когда на странице есть одинаковые графические элементы с точки зрения формы, но разного размера и цвета. Конечно же хочется использовать одно изображение. Поскольку графика векторная, то разный размер не является проблемой. А вот что с цветом? Первым делом на ум приходит инлайновая вставка и использование fill="currentColor" или аналогичной записи через CSS.

Но что, если хочется использовать тег <img> для контенного изображения, дабы оно и кешировалось, и индексировалось? Или наоборот, не хочется почём зря инлайнить совсем уж декоративное изображение, засоряя разметку, ведь для этого есть background-image. Нам помогут <symbol> и <use>.

Mobile + input[type="date"] + placeholder

Попалась в одном проекте, рассчитанном только на мобильные устройства, форма с различными полями, у которых есть плейсхолдеры. Одно из полей — дата. Конечно же, захотелось сделать это поле <input type="date">, чтобы и нативные дейтпикеры вызывались на устройствах, и не использовать какие бы то ни было плагины, регулярные выражения и пр. Но проблема в плейсхолдере, который для данного инпута не работает.

В процессе поиска было найдено несколько решений, но все они не подходили по разным причинам, работали не так, как надо. В итоге, методом проб и ошибок сделал свой вариант.

Фуригана и ruby

В процессе редизайна самоучителя Plain Japanese одной из проблем вновь стал вопрос с иероглифами, чтение которых надо пояснять. Обычно это делается при помощи фуриганы — фонетических подсказок.

В японском языке есть две азбуки, которые изучаются в самом начале, общее количество знаков там менее 100. Но есть и тысячи иероглифов, чтение которых — уже непростая задача. Для этого используются фонетические подсказки в обучающих материалах. И даже в текстах для японцев такие подсказки присутствуют у иероглифов, не входящих в список рекомендованных Министерством образования Японии к повседневному использованию. Данный список насчитывает 2136 иероглифов.
Furigana example

Автоматический интерлиньяж

Плохо не только ставить нецелочисленные размеры шрифтов, но также и интерлиньяж. Это делает неровным как макет, так и вёрстку. Очень часто дизайнеры, выбрав в Фотошопе размер шрифта, не задают ему интерлиньяж, оставляя параметр Auto. В вёрстке это равносильно line-height: 1.2.

Возьмём, к примеру, размер шрифта, равный 18. Интерлиньяж рассчитывается следующим образом: 18 × 1,2 = 21,6. Но расстояние между базовыми линиями не  может быть дробным, поэтому будет округляться, причём в разных местах по-разному.

Auto line-height

Старайтесь всегда ставить целочисленные значения.

Как сверстать экраны в перспективе

source

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

Если тень добавлять программно к элементам, то она будет не только на соседнем элементе, но и вокруг, на белом фоне; а если пытаться её сместить, то тени наоборот может не хватать.

Что если вырезать тень отдельным слоем? Возникает вопрос, когда её вставлять. Очевидно, что она должна появляться постепенно, для этого мы можем менять ей непрозрачность. Но есть два нюанса. Во-первых, в данном макете тень нарисована только там, где мы сейчас её видим, и если убрать один элемент сверху, то под ним её не будет. Во-вторых, слой с тенью в режиме умножения, что для вёрстки не годится. А это значит, что тень надо рисовать заново.

Допустим, верстальщик смог сам нарисовать новую тень, или попросил дизайнера, всё равно остаётся ещё одна проблема. Когда объект отбрасывает тень на поверхность, то при изменении расстояния меняется не только насыщенность, но и степень размытия тени, повлиять на которую мы не можем в текущем решении. Что ж, тогда попробуем сделать всё при помощи CSS.

Кнопки в лифте

У меня в доме установлены лифты со следующей кнопочной панелью:

elevator-panel

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

Кстати, расстояние между соседними столбцами гораздо меньше расстояний между кнопками в горизонтальном ряду, а должно быть наоборот.

А ещё шрифтом Брайля на 24-м этаже написано «14».