Неизвестно полезный CSS

в 9:00, , рубрики: Без рубрики

Неизвестно полезный CSS - 1

CSS не отстаёт от JavaScript. Постоянно развивается. Классно же. Мне особенно радостно видеть, как старые задачи, которые я решал при помощи костылей, теперь можно сделать при помощи одного свойства.

Только многие фишки неизвестны широкому кругу разработчиков. Честно говоря, некоторые я сам узнал недавно. В любом случае так дальше нельзя. Надо исправлять ситуацию!

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

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

▍ Что можно делать со свойством text-decoration

В 2011 году я изучал вёрстку, и, конечно, я узнал про свойство text-decoration. С помощью него я убирал подчёркивание у ссылки, думаю, вы также делаете. А теперь хочу спросить вас. Вы знаете, что сейчас это свойство является краткой формой записи?

Я не знал этого и был в шоке. Оказывается, что text-decoration включается в себя свойства: text-decoration-line, text-decoration-thickness, text-decoration-style и text-decoration-color. С помощью них мы можем определить тип, толщину, вид и цвет линии, как я сделал ниже:

/*
  свойство text-decoration разворачивается в следующие свойства:
  text-decoration-line: underline;
  text-decoration-thickness: 3px;
  text-decoration-style: solid;
  text-decoration-color: tomato;
*/
 
a {
  text-decoration: underline 3px solid tomato;
}

Чёрт, может это, конечно, очевидно для вас. Но я, правда, только недавно узнал об этом. И очень сильно радуюсь свойствам text-decoration-thickness и text-decoration-color. Почему?

Мне всегда попадались макеты, когда требовалось сделать подчёркивание толще, чем оно было по умолчанию в браузерах. А ещё и цвет поменять. И всё это нельзя было сделать с помощью text-decoration. Приходилось обращаться к другим трюкам. А сейчас стало проще. Класс!

Менее важной для меня является свойство text-decoration-line, но у него есть фишечка, которая может быть полезна вам. Мы можем установить несколько значений.

a {
  text-decoration-line: underline line-through;
}

Думаете полезно? Если да, то напишите, пожалуйста, в комментариях, где это может пригодиться.

Теперь вроде всё рассказал. А, нет. Чуть не забыл. Есть свойство text-underline-offset. Оно не входит в краткую форму записи text-decoration, но оно, как мне кажется, очень полезное. С помощью него можно указать позицию подчёркиванию, созданное свойством text-decoration-line, так как мы хотим.

a {
  text-decoration: underline 3px solid tomato;
  text-underline-offset: 5px;
}

Вот смотрю на эту ссылку и ностальгия. Сколько костылей раньше приходилось придумывать. Похожие ощущения у меня были, когда стало возможным использовать свойство border-radius, и отпала необходимость нарезать скруглённые уголки.

▍ Стилизация каждого слова при переносе текста

Однажды я помогал ребятам создавать дизайн-систему. Мы настраивали стили для базовой типографики. Одна из задач заключалась в том, чтобы стилизовать ссылки в тексте с нестандартным подчёркиванием. Сложность заключалась в том, что подчёркивание должно было сохраняться при переносе текста на новую строку, как показано ниже на изображении:

Фрагмент текста. Ссылка Brendan Eich. Brendan на первой строке. Eich на второй

Обратите внимание, что у ссылки есть отступ после последней буквы «n» в слове «Brendan» и перед первой буквой «E» в слове «Eich».

В чём заключается проблема? По умолчанию браузеры воспринимают контент элемента, как единое целое. По этой причине при переносе текста, его стилизация происходит целиком, а не по словам. Таким образом, когда я добавил свойство padding, то браузеры отобразили отступ перед и после ссылки. А это приводило к тому, что подчёркивание резко обрывалось при переносе текста.

Неизвестно полезный CSS - 3

К счастью, это очень легко изменить. Свойство box-decoration-break со значением clone сообщает браузеру, что при переносе текста свойства background, border, border-image, box-shadow, clip-path, margin и padding должны быть применены к каждому слову по отдельности.

В моём примере я добавил свойство к ссылке:

<body>
  <div class="content">
    <p>
      JavaScript (or ECMAScript) is the programming language that powers the web. Created in May 1995 by
      <a href="#0">Brendan Eich</a>,
      it’s found its place...
    </p>
  </div>
</body>

.content a:not([class]){
  text-decoration: none;
  color: currentColor;
 
  background-image: linear-gradient(#ff7eb2 0, #ff7eb2);
  background-size: 100% .35em;
  background-position: left bottom;
  background-repeat: no-repeat;
 
  padding-inline: 0.25em;
  -webkit-box-decoration-break: clone; 
  box-decoration-break: clone; 
}

Неизвестно полезный CSS - 4

▍ Больше контроля над обрезкой изображения

Отображения изображений — мой ночной кошмар. Я думаю вам знакома ситуация, когда в дизайне изображения одного размера, а перед сдачей проекта изображения заказчика совершенно другого.

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

Фото кота сжато

Эх, испортили фото кота. Конечно, здесь можно использовать свойство object-fit. Значение cover подскажет браузерам, что им нужно адаптировать изображение без нарушения пропорций под всю доступную область.

img {
  display: block;
  width: 350px;
  height: 350px;
  object-fit: cover;
}

И кажется, что всё будет хорошо. Но к сожалению, при адаптации происходит обрезка изображения. Она может пройти совсем неожиданно, потеряв важную часть.

Кот отображается с обрезанной головой

Кот с обрезанным глазом — это непорядок! Надо исправить. Сделать это можно с помощью свойства object-position.

Оно указывает смещение изображения при использовании свойства object-fit. Другими словами, у нас появляется возможность сместить изображение так, чтобы оно обрезалось без потери важной части.

При определении свойства мы можем использовать единицы измерения и ключевые слова в качестве значения свойства. Например, я задам значение right top.

img {
  display: block;
  width: 350px;
  height: 350px;
  object-fit: cover;
  object-position: right top;
}

Кот отображается без искажений слева. Справа много пустого пространства

Вот другое дело. Теперь кот отображается во всю свою красоту. Только теперь моё дизайнерское начало негодует. Кот отображается не в центре! Слишком много пространства справа от него.

Я поэкспериментировал и подобрал значение 80% 0.

img {
  display: block;
  width: 350px;
  height: 350px;
  object-fit: cover;
  object-position: 80% top;
}

Кот отображается в центре

Идеально! Правда, здесь я хочу поделиться находкой. Когда я подбирал значение, я думал, что браузеры вычисляют значения от левой границы родительского элемента. Но, это не так!

Оказывается, сначала они анализируют ширину изображения и контентной области, в котором оно находится. Далее отсчитывают значение 80% от левого края изображения и родительской контентной области. И на последнем этапе смещают изображение так, чтобы точки совпали.

Эх, как по мне, неочевидно. Я лично потратил несколько часов, чтобы понять, почему у меня 80% рассчитываются странно. Но, что поделать. Зато котик красиво отображается. Главное, вы теперь знаете, как работает свойство. Надеюсь, сэкономил ваше время.

▍ Не позволяем браузерам скрыть часть контента после прокрутки страницы

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

Для примера я создал лендинг, где кликнул по ссылке «Experience», а потом блок с навигацией закрыл заголовок.

Блок с меню закрывает заголовок раздела

Раньше нужно было немного шаманить, чтобы решить эту проблему. А сегодня всё просто.

Существует свойство scroll-margin-top. С помощью него мы можем установить отступ между элементом, к которому происходит переход, и вьюпортом. В качестве значения используются такие же единицы измерения, как при привычном свойстве margin.

Перейду теперь к исправлению ошибки в моём примере. Я использую следующую разметку раздела:

<section class="page-section">
  <div class="main-container">
    <h2 class="page-section__heading">
      <span class="page-section__name">Experience</span>
      <span class="page-section__hint">More about my experience</span>
    </h2>
    <div class="page-section__content">
      <!-- здесь находится контент раздела -->
    </div>
</section>

Корректное значение отступа будет рассчитываться, как сумма высоты блока с навигацией (75px) и внутреннего отступа между верхней границей раздела и заголовком (9rem). За суммирование в CSS отвечает функция calc(). Добавлю её к заголовку вместе со свойством scroll-margin-top.

.page-section {
  padding-top: 9rem;
}
 
.page-section__heading {
  scroll-margin-top: calc(9rem + 75px);
}

Блок с меню перестал закрывать заголовок раздела

▍ Заключение

Давайте подведём итог. Сегодня CSS предоставляет нам:

  • Свойства text-decoration-line, text-decoration-thickness, text-decoration-style, text-decoration-color и box-decoration-break для красивых многострочных ссылок с дефолтным подчёркиванием;
  • Свойство object-position для более корректной обрезки изображений;
  • Свойство scroll-margin-top, сохраняющее контент видимым после прокрутки страницы;

Вы же будете использовать их? Или я зря написал эту статью? Пожалуйста, ответьте в комментариях.

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

Автор: Стас Мельников

Источник

* - обязательные к заполнению поля


https://ajax.googleapis.com/ajax/libs/jquery/3.4.1/jquery.min.js