Как стать автором
Обновить
237.05
FirstVDS
Виртуальные серверы в ДЦ в Москве

Любопытные CSS фишки 2022 года

Время на прочтение8 мин
Количество просмотров15K

За последнее время в CSS появилось достаточно новых возможностей, которые позволяют нам создавать новые решения для старых задач. Мне захотелось рассказать вам о тех, которые работают в современных браузерах, и их можно использовать прямо сейчас.

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

Функции min() и max()

Я уверен, что периодически вам приходится делать элемент растягивающийся на всю ширину родителя, а также ограничивать его максимальный размер. Часто реализация этой задачи выглядит следующим образом:

.container {
  width: 100%;
  max-width: 1024px;
}

Это надежный фрагмент кода, проверенный временем. Но у меня есть идея, как его сократить до одной строки. Для этого нам нужно использовать математическую функцию min(). Данная функция позволяет браузеру выбрать наименьшее значение из представленных аргументов.

Возвращаясь к нашему примеру, мы хотим, чтобы браузер выбирал всегда значение 100%, пока данное значение не станет больше 1024px. Соответственно, нам остается передать значения 100% и 1024px.

.container {
  width: min(100%, 1024px);
}

Но если мы укажем аргументы в обратном порядке, то проблем не будет, потому что у нас есть возможность указывать их в любом порядке. Так что следующий фрагмент кода даст такой же результат, что и предыдущий.

.container {
  width: min(1024px, 100%);
}

Но лично мне нравится сначала указать ширину, а только потом максимальное значение, поэтому я за первый вариант! Но если вам нравится второй, то тоже все отлично.

Ой! Чуть не забыл рассказать, что кроме функции min(), есть еще функция max(). Данная функция напоминает функцию min(), разница только в том, что вместо минимального значения браузеры выбирают максимальное.

Функцию max() можно использовать для установки минимального размера. Конечно, это требуется реже, чем в случаях с установкой максимального размера, но все же такая задача случается.

Давайте рассмотрим пример, где мы делаем элемент, растягивающийся на всю ширину родителя, но имеющий минимальную ширину 1024px:

.container {
  width: 100%;
  min-width: 1024px;
}

По аналогии с функцией min(), его можно сократить до одной строки с помощью функции max():

.container {
  width: max(100%, 1024px);
}

Класс! Установка размеров теперь может выглядеть так кратко. По этой причине я, недолго думая, перешел на использование функций min() и max().

А еще функции можно комбинировать с CSS Custom Properties, и можно написать вот такой код:

.container {
  width: min(var(--current-width, 100%), var(--max-width, 1024px));
}
.container {
  width: max(var(--current-width, 100%), var(--min-width, 1024px));
}

Но это уже дело вкуса. Просто я люблю использовать CSS Custom Properties, и поэтому поделился с вами этой фишкой. Может быть, кому-то она понравится.

Браузерная поддержка: Edge, Firefox, Chrome, Opera, Safari, iOS Safari, Android Browser, Chrome Android, Samsung Internet по данным Can I use.

Свойство inset

При использовании position: absolute или position: fixed иногда приходится растягивать элемент на всю ширину и высоту. Например, использование свойств top, right, bottom и left — это один из популярных способов решения данной задачи.

.item {
  position: absolute;
  top: 0;
  right: 0;
  bottom: 0;
  left: 0;
}

Если вы фанат этого метода, то для вас у меня хорошие новости. Мы можем сократить этот код до 2 свойств! В этом на поможет свойство inset.

Свойство inset — это шорткат, задающий значение для свойств top, right, bottom и left, с помощью которого значения отступов будут автоматически подстроены в зависимости от направления текста на разных языках. Я не буду вдаваться в подробности, потому что в нашей задаче это излишне.

Самое главное, что свойство поможет нам одновременно задать значение для отступов со всех сторон. В качестве примера я перепишу предыдущий фрагмент кода, где мы задали 0 в качестве значения.

.item {
  position: absolute;
  inset: 0;
}

Представляете, как просто? А для полной картины я хочу показать вам второй способ решения задачи, основанный на том, что нам требуется задать значение 100% для свойств width и height.

.item {
  position: absolute;
  width: 100%;
  height: 100%;
}

Такой фрагмент кода также может быть сокращен до двух строк с помощью свойства inset.

.item {
  position: absolute;
  inset: 0;
}

Я теперь каждый раз кайфую, когда пишу такой код и вспоминаю, что теперь не надо писать еще три дополнительных строки. Давайте использовать свойство inset чаще.

Браузерная поддержка: Edge, Firefox, Chrome, Opera, Safari, iOS Safari, Android Browser, Chrome Android, Samsung Internet по данным Can I use.

Свойство gap

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

/* решение №1 */
.list {
  display: flex;
}

.list__item {
  margin-right: 16px;
}

.list__item:last-child {
  margin-right: 0;
}
/* решение №2 */
.list {
  display: flex;
}

.list__item:not(:last-child) {
  margin-right: 16px;
}
/* решение №3 */
.list {
  display: flex;
}

.list__item + .list__item {
  margin-left: 16px;
}
/* решение №4 */
.list {
  display: flex;
}

.list__item:nth-child(n+2) {
  margin-left: 16px;
}

Я был фанатом четвертого подхода и спорил со всеми о том, что он лучший. Особенно лучше первого. Но CSS не стоит на месте, и поэтому я хочу предложить еще один подход, который лучший. Да, да.. Вы можете в комментариях пошутить на эту тему. В общем, как вы уже поняли по заголовку раздела, я имею в виду свойство gap.

Свойство gap — это шорткат для записи значений свойств row-gap и column-gap. Первое задает отступ между элементам, а второе — между столбцами. Сначала свойство gap работало только вместе с гридами, а потом стало поддерживаться всеми браузерами для флексбоксов. После этого момента я предлагаю использовать его вместо свойства margin.

Для демонстрации преимущества свойства я с его помощью сокращу код всех предыдущих решений до следующего:

.list {
  display: flex;
  gap: 16px;
}

Вот так лаконично. Так что я больше не могу использовать решения со сложными селекторами и свойством margin. Свойство gap — мой фаворит. А чтобы оно стало и вашим, я покажу еще один пример, где свойство gap прекрасно себя показывает.

Давайте представим, что нам нужно сверстать интерактивный элемент, у которого может быть несколько состояний. Первое состояние — это только текст без иконки, второе — иконка, находящаяся перед текстом, третье — иконка, находящаяся после текста, а четвертое — иконка без текста.

Чтобы учесть все требования, нам нужно создать несколько классов, которые будут задавать отступ между текстом и иконкой, но также они не должны конфликтовать с состояниями «один» и «четыре». Поэтому для состояния «два» мы будем использовать дополнительный класс .button__icon--pos-before, а для состояния «три» — .button__icon--pos-after.

<!-- состояние №1: только текст без иконки -->
<button type="button" class="button">
  <span class="button__text">Перейти</span>
</button>
<!-- состояние №2: иконка находящийся перед текстом -->
<button type="button" class="button">
  <svg class="button__icon button__icon--pos-before" width="16" height="16" viewbox="0 0 24 24">
    <path d="M21.883 12l-7.527 6.235.644.765 9-7.521-9-7.479-.645.764 7.529 6.236h-21.884v1h21.883z"/>
  </svg>
  <span class="button__text">Перейти</span>
</button>
<!-- состояние №3: иконка находящийся после текста -->
<button type="button" class="button">
  <span class="button__text">Перейти</span>
  <svg class="button__icon button__icon--pos-after" width="16" height="16" viewbox="0 0 24 24">
    <path d="M21.883 12l-7.527 6.235.644.765 9-7.521-9-7.479-.645.764 7.529 6.236h-21.884v1h21.883z"/>
  </svg>
</button>
<!-- состояние №4: только иконка -->
<button type="button" class="button" aria-label="Перейти">
  <svg class="button__icon" width="16" height="16" viewbox="0 0 24 24">
    <path d="M21.883 12l-7.527 6.235.644.765 9-7.521-9-7.479-.645.764 7.529 6.236h-21.884v1h21.883z"/>
  </svg>
</button>
.button {
  display: inline-flex;
}

.button__icon--pos-before {
  margin-right: 8px;
}

.button__icon--pos-after {
  margin-left: 8px;
}

Именно так решалась данная задача до появления свойства gap, а теперь можно просто сделать то же самое с помощью него.

<!-- состояние №1: только текст без иконки -->
<button type="button" class="button">
  <span class="button__text">Перейти</span>
</button>
<!-- состояние №2: иконка находящийся перед текстом -->
<button type="button" class="button">
  <svg class="button__icon" width="16" height="16" viewbox="0 0 24 24">
    <path d="M21.883 12l-7.527 6.235.644.765 9-7.521-9-7.479-.645.764 7.529 6.236h-21.884v1h21.883z"/>
  </svg>
  <span class="button__text">Перейти</span>
</button>
<!-- состояние №3: иконка находящийся после текста -->
<button type="button" class="button">
  <span class="button__text">Перейти</span>
  <svg class="button__icon" width="16" height="16" viewbox="0 0 24 24">
    <path d="M21.883 12l-7.527 6.235.644.765 9-7.521-9-7.479-.645.764 7.529 6.236h-21.884v1h21.883z"/>
  </svg>
</button>
<!-- состояние №4: только иконка -->
<button type="button" class="button" aria-label="Перейти">
  <svg class="button__icon" width="16" height="16" viewbox="0 0 24 24">
    <path d="M21.883 12l-7.527 6.235.644.765 9-7.521-9-7.479-.645.764 7.529 6.236h-21.884v1h21.883z"/>
  </svg>
</button>
.button {
  display: inline-flex;
  gap: 8px;
}

Все! Мы удалили классы .button__icon--pos-before и .button__icon--pos-after, потому что браузер сам установит отступ там, где нужно. А если у нас состояние только с иконкой, то вообще не установит. Нам ничего дополнительно делать не нужно. Красота?!

Браузерная поддержка: Edge, Firefox, Chrome, Opera, Safari, iOS Safari, Android Browser, Chrome Android, Samsung Internet по данным Can I use.

Свойства margin-inline, margin-block, padding-inline и padding-block

При разработке приложений встречаются ситуации, когда приходится использовать 0 для свойств margin и padding, чтобы задать значения сразу для двух сторон. Например, я задам значение 10px сверху и 15px снизу для свойств margin и padding.

.container {
  margin: 10px 0 15px;
  padding: 10px 0 15px;
}

Мне кажется, если вы перфекционист, то где-то в душе вы поймете меня. Каждый раз, когда мне приходилось писать такой код, я был в печали. Ведь задавать 0 нелогично! Мне приходится задавать значение там, где не нужно. Вот такие тараканы бывают у верстальщика после 9 лет верстки. Славу богу, что появились свойства margin-inline, margin-block, padding-inline и padding-block.

По аналогии со свойством inset данные свойства задают внешний и внутренний отступ для элемента в зависимости от направления текста. Для кириллицы и латиницы с помощью свойства margin-inline и padding-inline мы задаем отступы слева и справа, а свойства margin-block и padding-block — сверху и снизу.

Таким образом, предыдущий фрагмент кода можно переписать вот так:

.container {
  margin-block: 10px 15px;
  padding-block: 10px 15px;
}

Ох, вот смотрю на этот код, и мой внутренний перфекционист радуется! Теперь все логично. А еще я не мог упустить момента, чтобы показать, где еще не нужно использовать 0.

Раньше, когда мы создавали блок, который центрирует содержимое страницы, нам приходилось использовать следующий фрагмент кода:

.container {
  max-width: 1024px;
  margin: 0 auto;
  padding: 0 10px;
}

А теперь мы можем заменить его кодом с использованием свойств margin-inline и padding-inline:

.container {
  max-width: 1024px;
  margin-inline: auto;
  padding-inline: 10px;
}

Моя душа спокойна. Если вас также раздражал 0, как и меня, то теперь вы знаете, что с этим делать.

Браузерная поддержка: Edge, Firefox, Chrome, Opera, Safari, iOS Safari, Android Browser, Chrome Android, Samsung Internet по данным Can I use.

Заключение

Хочется верить, что рассказанные мной техники вам понравились, и вы задумаетесь над тем, как их использовать. Если я что-то забыл, то, пожалуйста, напишите об этом. Мне будет интересно почитать!


НЛО прилетело и оставило здесь промокод для читателей нашего блога:

— 15% на все тарифы VDS (кроме тарифа Прогрев) — HABRFIRSTVDS.

Теги:
Хабы:
Всего голосов 15: ↑11 и ↓4+7
Комментарии11

Публикации

Информация

Сайт
firstvds.ru
Дата регистрации
Дата основания
Численность
51–100 человек
Местоположение
Россия
Представитель
FirstJohn