Как стать автором
Обновить
3332.33
RUVDS.com
VDS/VPS-хостинг. Скидка 15% по коду HABR15

Неизвестно полезный CSS. Часть 8

Уровень сложностиСредний
Время на прочтение6 мин
Количество просмотров5.8K


Привет, Хабр. Я продолжаю рассказывать про неизвестные широкому кругу разработчиков CSS фишки. Я отбираю их так, чтобы они были полезны в разного рода проектах. Неважно, верстаете ли вы сайт для малого бизнеса или создаёте супермодное React приложение. Они поддерживаются большинством браузеров. Отдельно отмечу, что я не считаю IE11 современным браузером. По этой причине я не учитывал его.


Сегодня мы рассмотрим:

  • как можно избежать длинных значений для свойства transform;
  • можно ли побороть неоднозначность медиа-запросов;
  • малоизвестное и полезное свойство при работе с «гридами»;
  • какой нюанс вы можете не знать про свойство align-content;
  • древнейшее свойство, помогающее улучшить взаимодействие пользователя клавиатуры с интерфейсом.

Больше не буду затягивать. Давайте посмотрим, что я вам подготовил.


▍ Сегодня можно анимировать трансформацию без длинной цепочки значений


Читатели моих статей периодически просят меня сделать код-ревью их проектов. Проводя его, я заметил один удивительный для меня момент. Многие не знают, что есть отдельные трансформации. Они используют по привычке старое свойство transform.


В итоге у них получается длинная строка из разных значений трансформации. Чаще всего это происходит при создании сценария анимации, как в коде ниже, где используются значения translate и rotate.


.awesome-block::before {
  /* Оставшиеся стили */

  position: absolute;
  top: 50%;
  left: 50%;

  animation: rotating 1500ms alternate infinite both;
}

@keyframes rotating {
  0%, 30% {
    transform: translate(-50%, -50%) rotate(0);
  }
	
  70%, 100% {
    transform: translate(-50%, -50%) rotate(360deg);
  }	
}

Здесь оставшиеся стили
.awesome-block {
  box-sizing: border-box;
  width: 200px;
  height: 200px;
  border: 1px solid;
  position: relative;
}

.awesome-block::before {
  content: "";
  width: 30px;
  height: 30px;
  background-color: lightblue;
}


Такое решение долгое время было вынужденным. Если разработчик использовал translate(-50%, -50%) для центрирования анимированного элемента по горизонтали и по вертикали, то это значение должно использоваться в анимации на каждом шаге. Иначе оно будет переопределено, и элемент будет дёргаться.


Уже давно у нас есть возможность так не делать. Достаточно использовать отдельные свойства трансформации translate, rotate и scale. Например, вот так преобразится наш предыдущий пример.


.awesome-block::before {
  /* Оставшиеся стили */

  position: absolute;
  top: 50%;
  left: 50%;
  translate: -50% -50%; /* тут появилось свойство translate вместо функции translate */

  animation: rotating 1500ms alternate infinite both;
}

@keyframes rotating {
  0%, 30% {
    rotate: 0;
  }
	
  70%, 100% {
    rotate: 360deg;
  }	
}

Здесь оставшиеся стили
.awesome-block {
  box-sizing: border-box;
  width: 200px;
  height: 200px;
  border: 1px solid;
  position: relative;
}

.awesome-block::before {
  content: "";
  width: 30px;
  height: 30px;
  background-color: lightblue;
}


Я заменил значение translate(-50%, -50%) на свойство translate и вынес его в основные стили псевдо-элемента .awesome-block::before. В анимации использую свойство rotate, которое работает также, как функция rotate().


Не надо больше, пожалуйста, писать длинные значения для свойства transform. Вам же самим потом сложно это всё поддерживать. Делайте ваш код простым.


▍ Уже можно использовать более явный синтаксис медиа-запросов


Мы с вами привыкли к определённому синтаксису медиа-запросов. Пишем @media, далее медиа-функция min-width или max-width, а потом граничное значение. Вот типичный пример.


@media (max-width: 1024px) {
  body {
    background-color: lightblue;
  }
}

Только при таком синтаксисе есть проблема. Я столкнулся с ней во времена, когда обучал вёрстке. Очень много людей забывало, включается ли указанное значение медиа-функции в диапазон. Например, значение 1024px будет ли включено в диапазоны от 0 до 1024px?


Конечно, да! Но многие думали, что нет. И не только мои ученики. Эта проблема была масштабной. Хорошо, что появился новый синтаксис медиа-запросов, основанный на математических знаках.


Я сразу перепишу предыдущий пример.


@media (width <= 1024px) {
  body {
    background-color: lightblue;
  }
}

Вот так явно проще понимать! Мы же знаем, что знаки <= означают меньше или равно. Соответственно, указанное значение будет входить в диапазон.


А можно и этот код упростить. Просто использовать знак <. Только нужно в этом случае изменить граничное значение с 1024px на 1025px.


@media (width < 1025px) {
  body {
    background-color: lightblue;
  }
}

Мне кажется, супер классное нововведение. Только есть ложка дёгтя.


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


Признаюсь. Я тоже по привычке использовал старый синтаксис. Но я уже исправляюсь! Надеюсь, вы тоже будете использовать новый синтаксис медиа-запросов. Давайте будем делать наш код более явным.


▍ Какое свойство вы забыли использовать при работе с «гридами»


Общаясь с фронтенд-разработчиками о «гридах» (CSS Grids), я часто замечаю, одно заблуждение. Люди думают, что для расположения элементов в столбец или строку обязательно нужно использовать свойства grid-template-columns или grid-template-rows. Это не так.


Я сразу перейду к примеру. Давайте посмотрим, что будет после объявления контейнеру с элементами свойства display со значением grid.


4 элемента расположились в столбец внутри родительского элемента

Элементы выстраиваются друг под другом. Это стандартное поведение, потому что после объявления значения grid к элементу автоматически применяется ряд свойств. Одним из них является свойство grid-auto-flow. Оно будет добавлено со значением row.


В инструментах разработчиков видно значение row для свойства grid-auto-flow

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


Элементы выстроились в строку внутри родительского элемента

Видите, как всё просто? И такой подход абсолютно корректный. Я встречал мнение, что «гриды» надо использовать только для сеток. Это не так. Они подходят для огромного числа задач. Свойство grid-auto-flow поможет вам.


▍ Что вы не знали про свойство align-content


Свойству align-content более десяти лет. Казалось бы, уже всё про него известно. Только это не так. Сейчас покажу одну фишечку.


Я буду использовать пример, в котором есть два элемента. Один вложен в другой. Для родительского элемента я добавлю свойство align-content.


<body>
  <div class="awesome-container">
    <div class="awesome-block">Великолепный текст</div>
  </div>
</body>

.awesome-container {
  box-sizing: border-box;
  width: 300px;
  height: 300px;
  border: 2px solid;

  align-content: center;
}

.awesome-block {
  background-color: lightblue;
}

Раньше я думал, что браузеры просто проигнорируют свойство. А теперь откроем браузер и увидим, что элемент с классом .awesome-block находится по центру по вертикальной оси.


Элемент располагается по центру по вертикальной оси родительского элемента

Да, это не баг. С прошлого года свойство align-content работает для элемента, у которого установлено свойство display со значением block. Просто пишем его, и оно работает.


Это означает, что у нас теперь есть способ выровнять элемент по вертикали с помощью одного свойства. Ура!


▍ Пользователи клавиатуры скажут вам спасибо за использование этого свойства


Продумывая эту статью, я сомневался, стоит ли включать свойство outline-offset. Оно настолько древнее, что я был уверен, что все про него знают. В общем, отправил я опрос в свой канал. Оказывается, половина моих подписчиков его не знает. Значит, надо рассказывать. Знакомьтесь, свойство outline-offset.


Чтобы понять смысл свойства, я напомню про свойство outline. С помощью него мы можем создать обводку вокруг элемента. По умолчанию она будет отображена по границам. Например, я создал обводку прям впритык к свойству border.


.awesome-link {
  display: inline-flex;
  padding: 0.75rem 1.25rem;
  border: 5px solid;
  background-color: pink;
  color: #222;
}

.awesome-link:focus-visible {
  outline: 4px solid tomato;
}

Отображается красная обводка вокруг границ ссылки

Свойство outline-offset может сместить эту обводку. Можно задать положительное и отрицательное значение. В первом случае браузеры будут отдалять обводку от границ элемента. Например, я задам значение 10px.


.awesome-link {
  display: inline-flex;
  padding: 0.75rem 1.25rem;
  border: 5px solid;
  background-color: pink;
  color: #222;
}

.awesome-link:focus-visible {
  outline: 4px solid tomato;
  outline-offset: 10px;
}

Красная обводка отображается на расстоянии от границ ссылки

При использовании отрицательного значения, обводка будет смещена внутрь на площадь элемента. Так, задавая значение -10px, я сместил обводку внутрь элемента на расстояние 10 пикселей от границ элемента.


.awesome-link {
  display: inline-flex;
  padding: 0.75rem 1.25rem;
  border: 5px solid;
  background-color: pink;
  color: #222;
}

.awesome-link:focus-visible {
  outline: 4px solid tomato;
  outline-offset: -10px;
}

Красная обводка отображается внутри ссылки прямо после ее границ

Это вся функция свойства outline-offset. Да, она очень простая, но, несмотря на свою простоту, очень важная. Здесь мне хочется ответить на вопрос: «А зачем нужно смещать обводку?»


В большинстве случаев я пользуюсь только клавиатурой. Одна из моих проблем — это незаметная обводка вокруг элементов. Хорошо, что крупные проекты хотя бы перестали её убирать. Но мне часто приходится думать: «А где это я сейчас?». Хорошо заметный текущий элемент — очень важная часть моего пользовательского опыта.


Вот такая «мелочь» может упростить мне жизнь. Пожалуйста, учтите это в своих интерфейсах.


▍ Заключение


Давайте подведём итог. В этой статье мы рассмотрели:

  • отдельные свойства трансформации translate, rotate и scale, помогающие избегать длинных значений для свойства transform;
  • новый синтаксис медиа-запросов;
  • упущенное из общего внимания свойство grid-auto-flow, позволяющее легко отобразить элементы в столбец или в строку;
  • свойство align-content работает внутри элемента с установленным свойством display со значением block;
  • свойство outline-offset, с помощью которого можно улучшить опыт пользователей клавиатуры.

Также, пожалуйста, напишите в комментариях, какие CSS фишки вы используете, о которых другие могут не знать. Буду ждать их. Спасибо за чтение!


P.S. Помогаю больше узнать про CSS в своём ТГ-канале CSS isn't magic. Присоединяйтесь. Ссылка в профиле.


P.S.S. Другие статьи из серии можно найти по тегу «sm909_unknown_css».



© 2025 ООО «МТ ФИНАНС»

Telegram-канал со скидками, розыгрышами призов и новостями IT 💻
Теги:
Хабы:
+57
Комментарии7

Публикации

Информация

Сайт
ruvds.com
Дата регистрации
Дата основания
Численность
11–30 человек
Местоположение
Россия
Представитель
ruvds