CSS
Общее
Старайтесь не использовать короткие свойства при написании CSS, например
margin: 10px 20px 30px 40px
. Несмотря на то, что это ускоряет (незначительно) написание CSS, в будущем это приводит к возникновению конфликтов в Git (в одной ветке изменили top-часть свойства, в другом bottom — поменялась одна строчка и будет конфликт), сложнее найти того, кто последний раз менял нужную часть (blame будет указывать на того, кто последний раз менял строчку, а не часть свойства), а также можно случайно перезаписать те свойства, которые перезаписывать не планировалось (background: red
сбросит все остальные свойства, например, background-image к дефолтным значениям)./* Недопустимо */ .header { margin: 10px 20px 30px 40px; } /* Правильно */ .header { margin-top: 10px; margin-right: 20px; margin-bottom: 30px; margin-left: 40px; }
- Проверяйте стили компонента на корректное отображение при различных данных. Например, при большом количестве текста или когда текста нет совсем.
Интерактивные элементы
- При создании интерактивных элементов (элементов, с которыми пользователь может
как-то взаимодействовать — что-то происходит по нажатию на этот элемент или
наведению на него), нужно учитывать следующие состояния:
- hover — cостояние при наведении мышью на элемент;
- focus — cостояние при «наведении» на элемент с клавиатуры (табом). Фокус
должен быть явно виден на странице, т.е. должно быть однозначно видно и
понятно, какой элемент сейчас под фокусом. Наилучшим вариантом является
стандартный
outline
. Не рекомендуется заменять его на смену цвета текста \ фона, так как такое изменение малозаметно. Допускается смена цветаoutline
на тот, который более вписывается в дизайн сайта; - disabled — обязательное состояние, если семантически такое состояние есть.
- В случае отсутствия необходимых состояний в макетах, запросите их у менеджера проекта \ дизайнера. Если контакта с дизайнером нет или по каким-либо причинам нет возможности отрисовать состояния, поставьте стандартные стили, применяемые в таких ситуациях: для ховера затемнение \ высветление цвета текста \ фона, для фокуса — стандартный аутлайн, для отключенного — выключить ховер и сделать фон \ текст серым.
- Учитывайте область клика небольших элементов. Стоит добавлять таким
элементам дополнительный
padding
, чтобы область элемента стала больше и в него было проще попасть.
Анимации
- Не анимируйте свойства, который вызывают reflow (layout) элемента.
То есть те свойства, которые влияют на размеры элемента или на положение
соседних элементов. К таким свойствам можно отнести
width
иmargin
. Анимация таких свойств будет медленной и будет работать медленно на слабых устройствах, лучше обойтись без анимации или изменить принцип анимации, чтобы можно было обойтись без reflow. - Не анимируйте свойства, которые вызывают repaint у больших блоков. Такая анимация хоть и гораздо быстрее, чем анимация свойств с reflow, но всё равно может быть достаточно медленной.
Лучшие свойства для анимации — свойства, которые вызывают только compositing. Такая анимация будет наиболее производительной. Основная проблема, что такие свойства — только
opacity
иtransform
. Но через них можно сэмулировать анимацию большинства остальных свойств. Например:/* Допустимо для небольших блоков */ div { background-color: red; transition: background-color .3s ease; } div:hover { background-color: blue; } /* Более производительный вариант анимации, но при этом более замороченный */ /* Разный фон в 2 разных элементах, при изменении меняем видимый элемент */ div::after, div::before { content: ''; width: 100%; height: 100%; opacity: 0; transition: opacity .3s ease; } div::after { background-color: red; opacity: 1; } div:hover::after { background-color: blue; opacity: 1 }
Подробнее:
Доступность
Различают несколько видов скрытия элемента:
- Полное скрытие — элемент не виден на экране, не доступен при навигации с
клавиатуры и не доступен скринридерам. Применяется, когда необходимо скрыть
элемент для всех. Это скрытие через
display: none
,visibility: hidden;
или атрибутhidden
. - Визуальное — элемент не виден на экране, но доступен для управления с
клавиатуры и для экранных читалок. Применяется, когда необходимо сделать
элемент невидимым, но при этом взаимодействие с этим элементом оставить.
Например, скрытие нативных радиокнопок \ чекбоксов — если скрыть их через
display: none
, то они не будут доступны читалкам \ скринридерам. Это скрытие через технику visuallyhidden. - Семантическое скрытие — элемент виден на экране, но не доступен для
скринридеров. Применяется для скрытия презентационных элементов.
Например, если кнопка содержит в себе иконку, то скринридер не должен
зачитывать эту иконку (но при этом в кнопке должен быть атрибут
title
, который содержит текстовое описание действия). Это скрытие через атрибутaria-hidden="true"
.
/* Недопустимо */ input[type=radio] { display: none } /* Правильно */ input[type=radio] { @extend .visuallyhidden; }
- Полное скрытие — элемент не виден на экране, не доступен при навигации с
клавиатуры и не доступен скринридерам. Применяется, когда необходимо скрыть
элемент для всех. Это скрытие через
Семантическая и визуальная роли могут отличаться: визуально это может быть кнопка, а семантически — ссылка. И наоборот. При разработке компонентов стоит учитывать этот нюанс и сбрасывать все стандартные стили тегов, которыми этот компонент может обладать.
/* Недопустимо */ .link { color: red; } /* Правильно */ .link { /* сброс всех свойств к значению по-умолчанию, */ /* убирается различие между всеми тегами */ all: initial; color: red; } .link { /* Сброс стандартных стилей <button> */ background: none; border: 0; color: inherit; font: inherit; line-height: normal; overflow: visible; padding: 0; user-select: none; color: red; }