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, то браузеры отобразили отступ перед и после ссылки. А это приводило к тому, что подчёркивание резко обрывалось при переносе текста.



К счастью, это очень легко изменить. Свойство 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; 
}


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


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


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


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

Эх, испортили фото кота. Конечно, здесь можно использовать свойство 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 фишки вы используете, о которых другие могут не знать. Буду ждать их. Спасибо за чтение!


Скидки, итоги розыгрышей и новости о спутнике RUVDS — в нашем Telegram-канале ????

Комментарии (15)


  1. arthurlomakin
    06.12.2023 09:17

    Есть книга Секреты CSS. Идеальные решения ежедневных задач

    В ней есть интересные трюки) Хоть и не самые современные


    1. a-tk
      06.12.2023 09:17
      +9

      CSS: Trick-oriented layout language...

      Почему когда речь заходит про CSS, всегда всё сводится к трюкам и неочевидным решениям?..


      1. Demon416
        06.12.2023 09:17
        -1

        Потому что разработчики css оторванные от реальной верстки идеалисты


      1. ubx7b8
        06.12.2023 09:17
        +8

        Потому что


      1. ImagineTables
        06.12.2023 09:17
        +4

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


        1. Demon416
          06.12.2023 09:17

          Я только за декларативное описание, но

          Отсутствие, до сих пор, не трюковых способов выравнивания блоков, работающего везде min/max-height/width, необходимость применения css reset, и border-box для предсказуемого поведения элементов однозначно говорят что дело не в необходимости магии, а в банальной непродуманности.


  1. NicolaiCherezov
    06.12.2023 09:17
    +12

    overscroll-behavior: none; - позволяют предотвратить прокрутку родительского блока при достижении конца прокрутки текущего элемента

    column-fill: balance; - выравнивает количество контента в столбцах

    user-select: all; - позволяет при клике по элементу выделить весь текст внутри него

    white-space: pre аналогичен тегу <pre> - сохраняет форматирование(пробелы, переносы и тд)

    hyphens: auto - определяет будут ли использованы переносы строк, требует установленного языка через тег lang="ru"


  1. MaxPro33
    06.12.2023 09:17

    Вы упомянули свойства text-decoration-line, text-decoration-thickness, text-decoration-style и text-decoration-color, включенные в text-decoration. Какие другие свойства, на ваш взгляд, часто недооцениваются, и какие возможности они открывают для стилизации текста?


  1. 13werwolf13
    06.12.2023 09:17
    +2

    простите за моё непопулярное ИМХО, но

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

    абсолютно проклятое: элементы сайта всё время мельтешащие перед носом (как например верхняя часть habr с меню) это ненужный бред. ДА ВИДЕЛ Я ТЕБЯ УЖЕ ОТСТАНЬ. перекрыло часть контента, пусть и небольшую, и врятли будет использовано в ближайшее время, зачем... мне не понять. ведь кнопка home на клавиатуре и так есть, ну или просто в углу маленькую кнопку для быстрого скрола вверх сайта ВМЕСТО закреплённой головы а не вместе с ней как на этом же хабре..

    или я просто старый ворчун...


    1. ilekarev
      06.12.2023 09:17

      Как относитесь к панели вкладок и адресной строки? Панель задач?
      Я понимаю что это можно настраивать (скрывать панель задач или полноэкранный режим в браузере, который вы врядли включаете). Но на сайте таких настроек никто делать не будет. Верхняя часть с меню о которой вы пишите, для меня полезна на каких-нибудь сайтах с каталогами (интернет-магазины). То что кнопка home есть на клавиатуре хорошо, но у меня обычно одна рука на мышке, другая отдыхает, может голову подпирает. Маленькая кнопочка не у всех на одном месте находится, поэтому иногда её искать приходится. В случае с хабром я понимаю что она во всю высоту сбоку, но могу этого не знать (или забыть, не сразу сообразить), тогда буду искать, пока не найду её посередине слева.


      1. Desem
        06.12.2023 09:17
        +1

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


      1. 13werwolf13
        06.12.2023 09:17

        Как относитесь к панели вкладок и адресной строки? Панель задач?
        Я понимаю что это можно настраивать

        сам спросил.. сам ответил.. классно. именно что это МОЖНО настраивать, и я МОГУ это настроить.

        Но на сайте таких настроек никто делать не будет

        и именно по этому такие вот "приклеенные" элементы должны умереть

        Верхняя часть с меню о которой вы пишите, для меня полезна на каких-нибудь сайтах с каталогами (интернет-магазины).

        я ж не оспариваю полезность таких вот частей, я оспариваю полезность того что они ВСЕГДА висят на видимой части экрана при том что используются они всего десяток секунд суммарно за пару часов ковыряния в каталоге

        но у меня обычно одна рука на мышке, другая отдыхает, может голову подпирает

        не понял как это связано.. вам кто-то запретил одной рукой касаться клавиатуры?

        Маленькая кнопочка не у всех на одном месте находится, поэтому иногда её искать приходится

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


    1. Psychosynthesis
      06.12.2023 09:17

      Если лично вы ими не пользуетесь, не значит что все остальные не пользуются.

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

      Ну и т.д.


      1. 13werwolf13
        06.12.2023 09:17

        ну вот мы и пришли к очевидному: почему бы не дать пользователю возможность выбрать..


  1. Elborak
    06.12.2023 09:17

    Всё перечисленное использую. Сам недавно узнал про scroll-margin-top. Был немного в шоке, что CSS дошёл до таких глубин.