Коллекция советов, которые помогут вам стать лучше в CSS.
Вы найдете больше классных списков под кураторством @sindresorhus.
- Используйте CSS Reset
- Наследуйте
box-sizing - Используйте
unsetвместо сброса всех свойств - Используйте
:not()для добавления / удаления границ в меню навигации - Проверьте, установлен ли шрифт локально
- Добавьте
line-heightвbody - Установите
:focusдля элементов формы - Выровнять всё по вертикали
- Используйте
aspect-ratioвместо задания ширины, высоты - Списки, разделенные запятыми
- Выбирайте элементы с использованием отрицательных значений в
nth-child - Используйте SVG для значков
- Используйте селектор "Лоботомированная сова"
- Используйте
max-heightдля ползунков на чистом CSS - Ячейки таблицы равной ширины
- Используйте Flexbox вместо margin
- Используйте селектор атрибутов для пустых ссылок
- Управляйте специфичностью лучше, с помощью
:is() - Стиль "по умолчанию" для ссылок
- Блок с собственным отношением сторон
- Задайте стили для поломанныx изображений
- Используйте
remдля глобальных размеров; Используйтеemдля локальных размеров - Отключите автовоспроизведение видео с включенным звуком
- Используйте
:rootдля шрифтов - Установите
font-sizeдля элементов формы, чтобы оптимизировать просмотр на мобильных устройствах - Использовать события указателя для управления событиями мыши
- Установите
display: noneна разрывы строк, используемые как интервалы - Используйте
:empty, чтобы скрыть пустые HTML элементы
Сброс CSS помогает обеспечить согласованность стилей между различными браузерами и с чистого листа начать оформление элементов. Вы можете использовать CSS библиотеки сброса такие как Normalize и др., или вы можете использовать более простой способ сброса:
*,
*::before,
*::after {
box-sizing: border-box;
margin: 0;
padding: 0;
}Теперь для всех элементов свойства margin и padding будут равны нулю, а box-sizing: border-box позволяет указывать размеры всему блоку, а не его содержимому.
Примечание: Если вы будете следовать совету Наследуйте box-sizing, то вы можете не включать свойство box-sizing в ваш CSS Reset.
Пусть box-sizing будет унаследован от html:
html {
box-sizing: border-box;
}
*,
*::before,
*::after {
box-sizing: inherit;
}Так значительно проще изменять box-sizing в плагинах или других компонентах, которые задают иное поведение.
При сбросе свойств элемента нет необходимости сбросить каждое отдельное свойство:
button {
background: none;
border: none;
color: inherit;
font: inherit;
outline: none;
padding: 0;
}Вы можете указать все свойства элемента, используя сокращенное выражение all. Установка значения unset изменяет свойства элемента на их начальные значения:
button {
all: unset;
}Вместо того, чтобы добавлять границу...
/* add border */
.nav li {
border-right: 1px solid #666;
}...а затем убирать её с последнего элемента...
/* remove border */
.nav li:last-child {
border-right: none;
}...используйте псевдокласс :not(), чтобы добавить только к нужным элементам:
.nav li:not(:last-child) {
border-right: 1px solid #666;
}Селектор CSS определяет границу так, как ее описывает человек.
Вы можете проверить, установлен ли шрифт локально, прежде чем извлекать его удаленно, что также является хорошим показателем производительности.
@font-face {
font-family: "Dank Mono";
src:
/* Full name */
local("Dank Mono"),
/* Postscript name */ local("Dank-Mono"),
/* Otherwise, download it! */ url("//...a.server/fonts/DankMono.woff");
}
code {
font-family: "Dank Mono", system-ui-monospace;
}Шляпный совет Адаму Аргайлу за то, что он поделился этим опытом и примером.
Вам вовсе не требуется добавлять свойство line-height к каждому <р>, <h*>, и т.д.. по отдельности. Вместо этого добавьте его в body:
body {
line-height: 1.5;
}Таким образом текстовые элементы легко могут наследовать свойство от body.
Приоритетные пользователи клавиатуры полагаются на фокус, чтобы определить, где события клавиатуры идут на странице. Сделайте фокус для элементов формы выделяющимися и последовательными, а затем реализацией браузера по умолчанию:
a:focus,
button:focus,
input:focus,
select:focus,
textarea:focus {
box-shadow: none;
outline: #000 dotted 2px;
outline-offset: 0.05em;
}Нет, это не чёрная магия, вы действительно можете расположить элементы по центру по вертикали:
html,
body {
height: 100%;
margin: 0;
}
body {
-webkit-align-items: center;
-ms-flex-align: center;
align-items: center;
display: -webkit-flex;
display: flex;
}...а также с помощью CSS Grid:
body {
display: grid;
height: 100vh;
margin: 0;
place-items: center center;
}Хотите разместить по центру что-то еще? Вертикально, горизонтально...что угодно, в любое время и в любом месте? У нас есть хорошая статья которая научит всему этому.
Используйте aspect-ratio вместо задания ширины, высотыhttps://onelove-agency.ru/web/october2024
Свойство aspect-ratio позволяет легко изменять размеры элементов и поддерживать постоянное соотношение ширины и высоты. Это невероятно полезно в отзывчивом веб-дизайне для предотвращения смещения макета. Используйте object-fit вместе с ним, чтобы не нарушить верстку при изменении значений высоты/ширины изображений.
img {
aspect-ratio: 16 / 9; /* ширина / высота */
object-fit: cover;
}Подробнее о свойстве aspect-ratio читайте в этой статье web.dev post.
Сделайте список похожим на настоящий, разделенный запятыми список:
ul > li:not(:last-child)::after {
content: ",";
}Используйте псевдокласс :not() чтобы не добавлять запятую к последнему пункту.
Примечание: Этот совет не всегда даёт лучший результат, например, могут возникнуть проблемы у экранного диктора. Да и копирование / вставка из браузера не всегда работают со сгенерированным CSS контентом. Следует быть осторожным.
Используйте отрицательные значения в nth-child в CSS для выбора элементов с 1 по n.
li {
display: none;
}
/* выбирает и отображает элементы с 1 по 3 */
li:nth-child(-n + 3) {
display: block;
}Или, так как вы уже немного познакомились с :not(), попробуйте:
/* выберите все элементы, кроме первых 3, и покажите их */
li:not(:nth-child(-n + 3)) {
display: none;
}Что же, это было довольно легко.
Нет ни одной причины, чтобы не использовать SVG для значков:
.logo {
background: url("logo.svg");
}SVG хорошо масштабируется для всех разрешений и поддерживается во всех браузерах включая IE9 и выше. Так выбросите же ваши .png, .jpg или .gif-jif-что-угодно файлы.
Примечание: Если у вас есть кнопки, содержащие только SVG пиктограммы, и SVG не удается загрузить, то это поможет сохранить доступность кнопки:
.no-svg .icon-only::after {
content: attr(aria-label);
}Название, безусловно, странное, но используя универсальный селектор (*) с соседним селектором (+), мы получаем мощное правило CSS:
* + * {
margin-top: 1.5em;
}В этом примере все элементы в потоке документа, которые следуют другие элементы получат margin-top: 1.5em.
Более подробную информацию о селекторе "Лоботомированная сова", можно найти в статье Heydon Pickering на A List Apart.
Реализация ползунков на чистом CSS с помощью max-height и overflow hidden:
.slider {
max-height: 200px;
overflow-y: hidden;
width: 300px;
}
.slider:hover {
max-height: 600px;
overflow-y: scroll;
}При наведении элемент расширяется до значения max-height, а всё что не влезло, можно прокрутить.
Иногда работа с таблицами приносит боль, в таких случаях попробуйте задать table-layout: fixed чтобы ячейки были одинаковой ширины:
.calendar {
table-layout: fixed;
}Даешь макеты таблиц без боли!
При работе с пробелами между колонок вы можете избавиться от псевдоклассов nth, first- и last-child воспользовавшись свойством flexbox space-between:
.list {
display: flex;
justify-content: space-between;
}
.list .person {
flex-basis: 23%;
}Теперь пробелы между колонками будут одного размера.
Отображайте ссылки, когда элемент <a> пустой, но есть ссылка в атрибуте href:
a[href^="http"]:empty::before {
content: attr(href);
}Это очень удобно.
Псевдокласс :is() используется для одновременного обращения к нескольким селекторам, что уменьшает избыточность и улучшает читаемость кода. Это невероятно полезно для написания больших селекторов в более компактной форме.
:is(section, article, aside, nav) :is(h1, h2, h3, h4, h5, h6) {
color: green;
}Приведённый выше набор правил эквивалентен следующим правилам селектора чисел...
section h1,
section h2,
section h3,
section h4,
section h5,
section h6,
article h1,
article h2,
article h3,
article h4,
article h5,
article h6,
aside h1,
aside h2,
aside h3,
aside h4,
aside h5,
aside h6,
nav h1,
nav h2,
nav h3,
nav h4,
nav h5,
nav h6 {
color: green;
}Добавьте для ссылок стиль "по умолчанию":
a[href]:not([class]) {
color: #008000;
text-decoration: underline;
}Теперь ссылки, вставленные через CMS, которые, как правило, не имеют атрибута class, будут иметь отличительный признак без влияния на каскад.
Чтобы создать блок с собственным отношением сторон, все, что вам нужно сделать, это добавить верхний или нижний padding к DIV:
.container {
height: 0;
padding-bottom: 20%;
position: relative;
}
.container div {
border: 2px dashed #ddd;
height: 100%;
left: 0;
position: absolute;
top: 0;
width: 100%;
}Использование padding 20% делает высоту параллелепипеда равной 20% от его ширины. Независимо от ширины окна, дочерний DIV будет сохранять соотношение сторон (100% / 20% = 5:1).
Сделайте поломанные изображения эстетически приятнее с CSS:
img {
display: block;
font-family: sans-serif;
font-weight: 300;
height: auto;
line-height: 2;
position: relative;
text-align: center;
width: 100%;
}Теперь добавьте правила псевдо-элементов для отображения сообщения пользователю и URL-ссылки поломаного изображения:
img:before {
content: "Упс, изображение ниже поломалось :(";
display: block;
margin-bottom: 10px;
}
img::after {
content: "(url: " attr(src) ")";
display: block;
font-size: 12px;
}Подробнее об этой модели в исходной статье Ire Aderinokun.
После установки базового размера шрифта всего проекта (html { font-size: 100%; }), установите размер шрифта для текстовых элементов через em:
h2 {
font-size: 2em;
}
p {
font-size: 1em;
}Затем установите размер шрифта для модулей через rem:
article {
font-size: 1.25rem;
}
aside .module {
font-size: 0.9rem;
}Теперь каждый модуль становится разобщенным и проще в настройке, более легким в обслуживании и гибче.
Это отличный трюк для пользовательских стилей. Избегайте раздражения пользователя звуком из видео, которое воспроизводится автоматически при загрузке страницы. Если звук не приглушен, то не показывайте видео:
video[autoplay]:not([muted]) {
display: none;
}И снова мы воспользовались помощью псевдокласса :not().
Размер шрифта должен подстраиваться под каждый возможный размер экрана. Вы можете рассчитывать размер шрифта, основываясь на высоте и ширине экрана с помощью :root:
:root {
font-size: calc(1vw + 1vh + 0.5vmin);
}Теперь вы можете использовать единицу root em на основе значения, рассчитанного с помощью :root:
body {
font: 1rem/1.6 sans-serif;
}Чтобы избежать масштабирования мобильными браузерами (iOS Safari, и др.) элементов HTML формы, когда раскрывающийся список <select> нажат, добавьте font-size правило селектору:
input[type="text"],
input[type="number"],
select,
textarea {
font-size: 16px;
}💃
События указателя позволяют указать, как мышь взаимодействует с элементом, который он трогает. Чтобы отключить событие указателя по умолчанию на кнопке, например:
button:disabled {
opacity: 0.5;
pointer-events: none;
}Это так просто.
Как отметил Гарри Робертс, это может помочь пользователям CMS использовать дополнительные разрывы строк для пробелов:
br + br {
display: none;
}Если у вас есть HTML элементы, которые пусты, то есть их контент ещё не установлен ни CMS, ни динамической вставкой (например, <p class="error-message"></p>) и вам не нравится, что они занимают пространство вашего макета, используйте псевдо-класс :empty, чтобы скрыть их.
:empty {
display: none;
}Примечание: Имейте в виду, что элементы с пробельными символами не считаются пустыми, например <p class="error-message"> </p>.
Текущие версии Chrome, Firefox, Safari, и Edge.