
Эта статья посвящена всему, что нужно знать о настройке расстояний между элементами и о настройке внутренних пространств элементов. В частности, речь пойдёт о том, в каких ситуациях стоит использовать внутренние отступы (padding), а в каких — внешние (margin).
Виды расстояний в CSS
Расстояния между элементами и их частями, настраиваемые средствами CSS, бывают двух видов. Они, по отношению к элементу, делятся на внутренние и внешние. Представим, что у нас имеется элемент. Если внутри него имеется некое расстояние между какими-то его частями, то это — внутренний отступ. Если же речь идёт о расстоянии между отдельными элементами — то это внешний отступ.

Внутреннее пространство и внешнее пространство
В CSS расстояние между элементами и их составными частями можно настраивать так:
.element { padding: 1rem; margin-bottom: 1rem; }
Свойство padding использовано здесь для настройки внутреннего отступа, а свойство margin — для настройки внешнего отступа. Всё очень просто. Правда? Но настройка расстояний в CSS может серьёзно усложниться в том случае, если работают с компонентами, имеющими множество мелких составных частей и дочерних элементов.
▍Свойство margin — внешний отступ
Свойство margin используется для настройки расстояния между отдельными элементами. Например, в предыдущем примере использовано CSS-свойство margin-bottom: 1rem для добавления вертикального расстояния между двумя элементами, расположенными друг над другом.
Внешний отступ можно настраивать для четырёх сторон элемента (top, right, bottom, left — верхней, правой, нижней, левой). Поэтому, прежде чем переходить к примерам и к обсуждениям разных способов настройки расстояний, важно пролить свет на некоторые базовые концепции.
▍Схлопывание внешних отступов
Если описать понятие «схлопывание внешних отступов» простыми словами, то можно сказать, что это происходит в том случае, если два элемента, расположенных друг над другом, имеют внешние отступы, и при этом отступ одного из них больше, чем отступ другого. В таком случае будет использован больший отступ, а меньший будет проигнорирован.

Побеждает больший отступ
На вышеприведённой схеме у верхнего элемента настроено свойство margin-bottom, а у нижнего — свойство margin-top. Вертикальное расстояние между элементами соответствует большему из этих отступов.
Для того чтобы избежать этой проблемы, рекомендуется настраивать во всех элементах одни и те же отступы (как описано здесь). И вот ещё один интересный факт. Ресурс CSS Tricks устроил голосование по поводу использования свойств margin-bottom и margin-top. Как оказалось, свойство margin-bottom победило, взяв 61% голосов.
Вот как решается эта проблема:
.element:not(:last-child) { margin-bottom: 1rem; }
Использование CSS-селектора :not позволяет легко удалить внешний отступ у последнего дочернего элемента для того чтобы избавиться от ненужного пространства между элементами.
→ Вот демонстрация работы с внешними отступами
Ещё один пример, связанный со схлопыванием внешних отступов, связан с дочерними и родительскими элементами. Предположим, имеется следующий HTML-код:
<div class="parent"> <div class="child">I'm the child element</div> </div>
Вот его стили:
.parent { margin: 50px auto 0 auto; width: 400px; height: 120px; } .child { margin: 50px 0; }
Вот как выглядит результат визуализации всего этого.

Дочерний и родительский элементы
Обратите внимание на то, что дочерний элемент упирается в верхнюю часть родительского элемента. Это — результат схлопывания их внешних отступов. По данным W3C, есть несколько вариантов решения этой проблемы:
- Добавление свойства
borderк родительскому элементу. - Установка свойства
displayдочернего элемента в значениеinline-block.
Более понятным решением этой проблемы будет настройка свойства padding-top родительского элемента.

Настройка верхнего внутреннего отступа родительского элемента
▍Отрицательный внешний отступ
Отрицательное значение можно использовать для любых внешних отступов. В некоторых случаях этот приём оказывается весьма полезным. Взглянем на следующий рисунок.

Результаты настройки свойства padding родительского элемента
У родительского элемента имеется свойство padding: 1rem. Это приводит к тому, что у дочернего элемента появляются смещения сверху, слева и справа. Но дочерний элемент должен прилегать к границам родительского элемента. Добиться этого помогут отрицательные внешние отступы.
.parent { padding: 1rem } .child { margin-left: -1rem; margin-right: -1rem; margin-top: -1rem; }
Вот что получилось в результате такой стилизации.

Отрицательные внешние отступы дочернего элемента помогают добиться желаемого эффекта
→ Вот демонстрация
Если тема отрицательных внешних отступов вам интересна — рекомендую эту статью.
▍Свойство padding — внутренние отступы
Как уже было сказано, свойство padding позволяет управлять пространством внутри элемента. Цель применения этого свойства зависит от того, в какой ситуации оно используется.
Например, его можно использовать для увеличения пространства вокруг ссылок. Это приводит к увеличению кликабельного пространства ссылок.

Зелёным цветом выделен внутренний отступ
▍Ситуации, в которых свойство padding не работает
Важно отметить, что вертикальные внутренние отступы не работают с элементами, имеющими свойство display: inline. Например, это элементы <span> и <a>. Если настроить свойство padding такого элемента, такая настройка на данный элемент не подействует. Это — всего лишь дружеское напоминание о том, что у inline-элементов нужно менять свойство display:
.element span { display: inline-block; padding-top: 1rem; padding-bottom: 1rem; }
Пространство между элементами CSS Grid-макета
В модели CSS Grid можно легко настраивать расстояние между столбцами и строками, используя свойство grid-gap. Это — сокращённое название свойства, задающего расстояния между столбцами и строками.

Расстояния между столбцами и строками
.element { display: grid; grid-template-columns: 1fr 1fr; grid-gap: 16px; /* Добавляет расстояние в 16px для строк и столбцов */ }
Полная запись этих свойств выглядит так:
.element { display: grid; grid-template-columns: 1fr 1fr; grid-row-gap: 24px; grid-column-gap: 16px; }
Пространство между элементами CSS Flexbox-макета
Есть одно свойство, предложенное для Grid- и Flexbox-макетов. Это — свойство gap. В настоящее время его поддерживает лишь Firefox.
.element { display: flex; flex-wrap: wrap; gap: 16px; }
Более того, это свойство нельзя использовать с CSS @supports для определения того, поддерживается ли оно, и для принятия соответствующих решений, основываясь на этом. Если это свойство вам нравится — голосуйте за добавление его в Chrome.
Позиционирование элементов в CSS
Возможно, позиционирование элементов нельзя напрямую отнести к способам настройки расстояния между ними, но в некоторых случаях позиционирование играет определённую роль. Например, если есть абсолютно позиционированный дочерний элемент, который нужно расположить в 16px от левого и верхнего краёв родительского элемента.
Рассмотрим следующий пример. Есть карточка, на которой имеется иконка, которую нужно расположить на некотором расстоянии от верхнего и левого краёв родительского элемента. Для достижения этого эффекта можно воспользоваться следующим стилем:
.category { position: absolute; left: 16px; top: 16px; }

Зелёным выделено расстояние между границами родительского и дочернего элементов
Сценарии использования и практические примеры
В этом разделе мы рассмотрим сценарии использования средств настройки расстояний между элементами. Нечто подобное вполне может встретиться вам в повседневной работе с CSS.
▍Компонент-заголовок

Компонент — заголовок, у которого настроено следующее: отступ слева и справа, пространство вокруг логотипа, пространство вокруг навигационного элемента, расстояние между навигационным элементом и именем пользователя
В данном случае в компоненте-заголовке имеется логотип, область навигации, и область, в которой выводятся сведения о профиле пользователя. Можете догадаться о том, как должен выглядеть код стилизации такого элемента? Вот, чтобы было легче, схематичная разметка такого элемента:
<header class="c-header"> <h1 class="c-logo"><a href="#">Logo</a></h1> <div class="c-header__nav"> <nav class="c-nav"> <ul> <li><a href="#">...</a></li> </ul> </nav> <a href="#" class="c-user"> <span>Ahmad</span> <img class="c-avatar" src="shadeed.jpg" alt=""> </a> </div> </header>

Внутренние и внешние отступы
Слева и справа используются внутренние отступы. Их цель заключается в том, чтобы содержимое заголовка не прижималось бы к его краям.
.c-header { padding-left: 16px; padding-right: 16px; }
При настройке навигационных ссылок нужно учитывать то, что у каждой из них должно быть достаточно внутреннего пространства по вертикали и по горизонтали. Благодаря этому их кликабельная область будет достаточно большой, что улучшит доступность проекта.
.c-nav a { display: block; padding: 16px 8px; }
Если же говорить о расстоянии между элементами, то тут можно использовать свойство margin, либо — можно изменить свойство display элементов <li> на inline-block. Благодаря этому добавляется небольшое пространство между элементами, лежащими на одном уровне, из-за того, что такие элементы рассматриваются как символы.
.c-nav li { /* Благодаря этому созданы те пространства, которые видны на макете */ display: inline-block; }
И наконец, у имени пользователя и аватара есть левый внешний отступ.
.c-user img, .c-user span { margin-left: 10px; }
Обратите внимание на то, что если вы создаёте многоязычный сайт, рекомендовано в подобной ситуации использовать логические CSS-свойства:
.c-user img, .c-user span { margin-inline-start: 1rem; }

Расстояния до и после разделителя неодинаковы
Обратите внимание на то, что расстояния до и после разделителя неодинаковы. Причина этого заключается в том, что у навигационного блока не задана ширина. Вместо этого тут настроены лишь внутренние отступы. В результате ширина навигационных элементов зависит от их содержимого. Вот варианты решения этой проблемы:
- Настройка минимальной ширины для навигационных элементов.
- Увеличение горизонтального внутреннего отступа.
- Добавление в левой части разделителя дополнительного внешнего отступа.
Лучше и легче всего воспользоваться третьим способом, который заключается в настройке свойства margin-left:
.c-user { margin-left: 8px; }
→ Вот демонстрация
▍Расстояния в сеточных макетах — CSS Flexbox
Сеточные макеты — это то место, где часто применяются технологии настройки расстояния между элементами. Рассмотрим следующий пример.

Сеточный макет
Нам нужно настроить расстояние между строками и столбцами таблицы. Вот разметка:
<div class="wrapper"> <div class="grid grid--4"> <div class="grid__item"> <article class="card"><!-- Содержимое карточки --></article> </div> <div class="grid__item"> <article class="card"><!-- Содержимое карточки --></article> </div> <!-- И так далее.. --> </div> </div>
Обычно я предпочитаю держать компоненты в инкапсулированном состоянии и избегаю настройки их внешних отступов. По этой причине у меня есть элемент grid_item, в котором будет располагаться элемент-карточка.
.grid--4 { display: flex; flex-wrap: wrap; } .grid__item { flex-basis: 25%; margin-bottom: 16px; }
Благодаря этому CSS-коду в каждой строке будет четыре карточки. Вот один из возможных способов настройки расстояния между ними:
.grid__item { flex-basis: calc(25% - 10px); margin-left: 10px; margin-bottom: 16px; }
Благодаря использованию CSS-функции calc() внешний отступ вычитается из flex-basis. Как видите, это не такое уж и простое решение. Я, на самом деле, предпочитаю следующее:
- Настроить у элемента сетки свойство
padding-left. - Настроить у родительского элемента отрицательный внешний отступ
margin-leftс тем же значением, что и уpadding-left.
Я узнал об этом методе много лет назад, прочитав здесь какую-то статью, название которой уже забыл (если знаете о том, что это за статья — пожалуйста дайте мне знать).
.grid--4 { display: flex; flex-wrap: wrap; margin-left: -10px; } .grid__item { flex-basis: 25%; padding-left: 10px; margin-bottom: 16px; }
Причина, по которой я использовал здесь отрицательное значение для margin-left, заключается в том, что у первой карточки есть свойство padding-left, которое, в реальности, не нужно. В результате я перемещаю элемент-обёртку влево и избавляюсь от ненужного пространства.
→ Вот рабочий пример
Ещё одна похожая идея заключается в использовании внутренних отступов и отрицательных внешних отступов. Вот — пример с сайта Facebook.

Внутренние и внешние отступы
Вот CSS-код, иллюстрирующий эту идею:
.wrapper { margin-left: -4px; margin-right: -4px; } .story { padding-left: 4px; padding-right: 4px; }
▍Расстояния в сеточных макетах — CSS Grid
А теперь — самое приятное! В макетах, основанных на CSS Grid, расстояния между элементами очень удобно настраивать, используя свойство grid-gap. Кроме того, можно не беспокоиться о ширине элементов и о нижних внешних границах. CSS Grid-макет берёт на себя заботы обо всём этом.
.grid--4 { display: grid; grid-template-columns: 1fr 1fr 1fr; grid-gap: 1rem; }
Вот и всё. Полагаю, никто не станет спорить с тем, что настройка Grid-макетов легче и понятнее, чем настройка Flexbox-макетов.
▍Настройка расстояния между элементами только тогда, когда это необходимо
В Grid-макетах мне чрезвычайно нравится то, что свойство grid-gap применяется лишь в том случае, когда между элементами должно быть некое расстояние. Взглянем на следующий макет.

Макет сетки, в которой элементы в мобильной среде расположены вертикально, а в настольной — горизонтально
Есть раздел сайта с двумя карточками. Мне нужно, чтобы они были бы разделены и в мобильной среде, при вертикальном расположении карточек, и в настольной, при горизонтальном их расположении. Без CSS Grid такой гибкости макета достичь невозможно. Взгляните на следующий код:
.card:not(:last-child) { margin-bottom: 16px; } @media (min-width: 700px) { .card:not(:last-child) { margin-bottom: 0; margin-left: 1rem; } }
Не очень-то удобно. Правда? А как насчёт следующего стиля?
.card-wrapper { display: grid; grid-template-columns: 1fr; grid-gap: 1rem; } @media (min-width: 700px) { .card-wrapper { grid-template-columns: 1fr 1fr; } }
Дело сделано! И устроено всё значительно проще.
▍Работа с нижним внешним отступом
Предположим, что у нас имеются следующие компоненты, расположенные друг над другом. У каждого из них настроен нижний внешний отступ.

Набор компонентов, расположенных горизонтально
Обратите внимание на то, что нижний внешний отступ имеется и у последнего элемента. А это неправильно, так как отступы должны присутствовать лишь между элементами.
Исправить эту проблему можно, прибегнув к одному из решений, которые мы сейчас разберём.
Решение №1: CSS-селектор :not
.element:not(:last-child) { margin-bottom: 16px; }
Решение №2: комбинация соседних элементов одного уровня
.element + .element { margin-top: 16px; }
Анализ решений
Хотя решение №1 кажется более привлекательным, у него есть следующие недостатки:
- Оно приводит к проблемам с CSS-специфичностью. Его нельзя переопределить до тех пор, пока используется селектор
:not. - Оно неприменимо в случаях, когда имеется более чем один столбец элементов. Это проиллюстрировано ниже.

Два столбца элементов и проблема решения №1
Если говорить о решении №2, то его применение не приводит к возникновению проблем со специфичностью. Правда, это решение тоже подходит лишь в тех случаях, когда речь идёт об одном столбце элементов.
В этой ситуации лучше всего прибегнуть к решению по удалению ненужного пространства путём добавления отрицательного внешнего отступа к родительскому элементу:
.wrapper { margin-bottom: -16px; }
Здесь происходит следующее. Благодаря такой настройке элемент смещается вниз на расстояние, равное заданному внешнему отступу. Но тут следует проявлять осторожность и не задать такой внешний отступ при использовании которого элементы бы перекрылись.
▍Компонент-карточка
Теперь хочу подробно обсудить настройки компонентов-карточек. Возможно, в итоге у меня получится целая книга об этом. Здесь же я рассмотрю универсальный паттерн настройки карточек и расскажу о том, как ими управлять.

Компонент-карточка (если вам захотелось есть — извиняюсь)
Подумайте о том, где именно в этой карточке используется настройка расстояний между элементами и их частями. Вот мой ответ на этот вопрос.

Внутренние и внешние отступы
Вот разметка:
<article class="card"> <a href="#"> <div class="card__thumb"><img src="food.jpg" alt=""></div> <div class="card__content"> <h3 class="card__title">Cinnamon Rolls</font></h3> <p class="card__author">Chef Ahmad</p> <div class="card__rating"><span>4.9</span></div> <div class="card__meta"><!-- --></div> </div> </a> </article>
Вот стиль класса card__content:
.card__content { padding: 10px; }
Благодаря установленному здесь внутреннему отступу будет настроено смещение для всех дочерних элементов. Затем настраиваем внешние отступы:
.card__title, .card__author, .card__rating { margin-bottom: 10px; }
Настраивая разделение оценки и сведений, я использовал границу:
.card__meta { padding-top: 10px; border-top: 1px solid #e9e9e9; }
Но тут мы сталкиваемся с проблемой! Граница не привязана к краям, что происходит из-за того, что у родительского элемента с классом card__content настроен внутренний отступ.

Разделитель не привязан к краю
Вы, пожалуй, уже догадались о том, что нам тут помогут отрицательные отступы:
.card__meta { padding-top: 10px; border-top: 1px solid #e9e9e9; margin: 0 -10px; }
Но и тут снова что-то пошло не так. Теперь текст прилип к краю карточки.

Разделитель в норме, но содержимое карточки расположено неправильно
Для того чтобы решить эту проблему, нужно настроить левый и правый внутренние отступы для содержимого карточки.
.card__meta { padding: 10px 10px 0 10px; border-top: 1px solid #e9e9e9; margin: 0 -10px; }

Карточка настроена так, как нужно
→ Вот пример
▍Содержимое статей
Я уверен в том, что то, о чём мы будем тут говорить, представляет собой очень и очень сильно распространённую ситуацию. Дело тут в том, что содержимое статей обычно поступает на страницы из CMS (Content Management System — система управления контентом), или генерируется автоматически на основе Markdown-файлов. Здесь нельзя указывать классы элементов.
Рассмотрим следующий пример, в котором представлена разметка, содержащая смесь из заголовков, абзацев и изображений.
<div class="wrapper"> <h1>Spacing Elements in CSS</h1> <p><!-- content --></p> <h2><font color="#3AC1EF">Types of Spacing</font></h2> <img src="spacing-1.png" alt=""> <p><!-- content --></p> <p><!-- content --></p> <h2><font color="#3AC1EF">Use Cases</font></h2> <p><!-- content --></p> <h3><font color="#3AC1EF">▍Card Component</font></h3> <img src="use-case-card-2.png" alt=""> </div>
Для того чтобы привести это всё к приличному виду, расстояния между элементами должны быть единообразными и должны использоваться ответственно. Работая над данным примером я позаимствовал некоторые стили с type-scale.com.
h1, h2, h3, h4, h5 { margin: 2.75rem 0 1.05rem; } h1 { margin-top: 0; } img { margin-bottom: 0.5rem; }
Вот схема страницы с текстом статьи.

Схема страницы и применение свойств margin-top и margin-bottom
Если за элементом <p> следует заголовок, например — заголовок Types of Spacing, то свойство margin-bottom элемента <p> будет проигнорировано. Это, как вы можете догадаться, является следствием схлопывания внешних отступов.
→ Вот пример
▍Внешние отступы, применяемые в зависимости от обстоятельств
Взгляните на следующий макет.

Элементы в нормальном состоянии и в ситуации нехватки места
Элементы не очень хорошо выглядят в том случае, когда они находятся друг к другу слишком близко. Я создал этот макет с использованием Flexbox. Эта методика называется «Alignment Shifting Wrapping» (Выравнивание Сдвиг Перенос). Я узнал о её названии отсюда.
.element { display: flex; flex-wrap: wrap; }
В результате применения этой методики осуществляется перенос строк в том случае, если область просмотра меньше определённого предела. Вот как это выглядит.

Дочерние элементы находятся на новых строках
Здесь нужно разобраться с промежуточной ситуацией, в которой два элемента всё ещё находятся рядом друг с другом, но расстояние между ними равно нулю. В таком случае я предпочитаю прибегать к свойству margin-right, что не даёт элементам касаться друг друга и ускоряет срабатывание flex-wrap.

Элементы не касаются друг друга
▍CSS-свойство writing-mode
Сначала процитируем MDN: «Свойство writing-mode устанавливает горизонтальное или вертикальное положение текста, а также — направление блока».
Размышляли когда-нибудь о том, как должны вести себя внешние отступы в том случае, когда они используются с элементом, свойство writing-mode которого отличается от стандартного? Рассмотрим следующий пример.

Карточка с вертикальным заголовком
Вот стили:
.wrapper { /* Для того чтобы заголовок и карточка рецепта были бы расположены на одной строке */ display: flex; } .title { writing-mode: vertical-lr; margin-right: 16px; }
Заголовок повёрнут на 90 градусов. Между ним и изображением должно быть пустое пространство. Как оказалось, свойство margin-right отлично показывает себя при разных значениях свойства writing-mode.
→ Вот пример
Полагаю, мы рассмотрели достаточно сценариев использования отступов. Теперь рассмотрим некоторые интересные концепции.
Инкапсуляция компонентов
В больших дизайн-системах содержится множество компонентов. Логично ли будет настраивать их внешние отступы?
Рассмотрим следующий пример.

Кнопки
<button class="button">Save Changes</button> <button class="button button-outline">Discard</button>
Где нужно настраивать расстояния между кнопками? Нужно ли настраивать какие-то свойства левой или правой кнопки? Может, можно воспользоваться комбинацией соседних элементов одного уровня?
.button + .button { margin-left: 1rem; }
Ничего хорошего в этом нет. А что если имеется лишь одна кнопка? А как это будет работать на мобильном устройстве, в том случае, когда кнопки расположены по вертикали, а не по горизонтали? В общем, тут перед нами встаёт множество сложных вопросов.
▍Использование абстрагированных компонентов
Решением вышеозначенных проблем является применение абстрагированных компонентов, которые используются для размещения в них других компонентов. Это, как сказано здесь, что-то вроде перемещения ответственности за управление отступами на родительский элемент. Переосмыслим предыдущий пример в свете этой идеи.

Родительские и дочерние компоненты
<div class="list"> <div class="list__item"> <button class="button">Save Changes</button> </div> <div class="list__item"> <button class="button button-outline">Discard</button> </div> </div>
Обратите внимание на то, что тут присутствуют элементы-обёртки. Каждая кнопка обладает собственной обёрткой.
.list { display: flex; align-items: center; margin-left: -1rem; /* Убирает левый внешний отступ первого элемента */ } .list__item { margin-left: 1rem; }
Вот и всё! И более того — эту концепцию легко применить к любому JavaScript-фреймворку. Например:
<List> <Button>Save Changes</Button> <Button outline>Discard</Button> </List>
А используемый JS-инструмент должен поместить каждый элемент в собственную обёртку.
Компоненты, используемые в качестве разделителей
Если вы сомневаетесь в том, что прочли заголовок правильно — не сомневайтесь. Речь идёт о компонентах, используемых в качестве разделителей. В частности, тут я ссылаюсь на эту статью, в которой обсуждается концепция, в соответствии с которой избегают использования внешних отступов и применяют вместо них компоненты-разделители.
Представим, что в некоем разделе сайта нужен левый внешний отступ размером 24px. При этом к отступу выдвигаются следующие требования:
- Внешний отступ не должен настраиваться непосредственно у компонента, так как он является частью уже созданной дизайн-системы.
- Отступ должен быть гибким. На одной странице он может иметь размер
X, а на другой — размерY.
Я впервые заметил этот приём, исследуя новый дизайн Facebook.

Элемент-разделитель в дизайне Facebook
Здесь в качестве элемента-разделителя используется <div> с встроенным стилем width: 16px. Его единственная цель — добавление пустого пространства между левым элементом и элементом-контейнером.
Вот цитата из данной методички по React: «Но в реальном мире мы нуждаемся в пространствах, задаваемых за пределами компонентов, для компоновки компонентов в страницы и сцены. Именно здесь настройки внешних отступов и пробираются в код компонентов для настройки расстояний между компонентами при их компоновке».
Я с этим согласен. В большой дизайн-системе нерациональным будет добавление к компонентам внешних отступов. Это, в результате, приведёт к не очень хорошо выглядящему коду.
▍Проблемы компонентов-разделителей
Теперь, когда вы ознакомились с идеей компонентов-разделителей, давайте поговорим о некоторых проблемах, вполне ожидаемых, которые могут возникнуть при работе с ними. Вот вопросы об этом, над которыми я размышлял:
- Как компонент-разделитель занимает место в родительском компоненте? Как он ведёт себя в горизонтальных и вертикальных макетах? Например — как такой компонент разделит компоненты, расположенные вертикально и горизонтально?
- Нужно ли стилизовать эти компоненты, основываясь на свойстве
displayкомпонента-родителя (Flexbox, Grid)?
Разберём эти вопросы.
▍Размеры компонентов-разделителей
Можно создать компонент-разделитель, принимающий различные параметры. Я — не JavaScript-разработчик, но думаю, что это то, что называется «свойствами» (props). Рассмотрим следующий пример, взятый отсюда.
Имеется компонент-разделитель, расположенный между компонентами Header и Section.
<Header /> <Spacer mb={4} /> <Section />
А вот — несколько иная ситуация. Тут разделитель используется для создания автоматически настраиваемого расстояния между логотипом (компонентом Logo) и областью навигации, представленной компонентами Link.
<Flex> <Logo /> <Spacer m="auto" /> <Link>Beep</Link> <Link>Boop</Link> </Flex>
Может показаться, что реализовать такой разделитель средствами CSS очень просто, и что для этого достаточно воспользоваться конструкцией justify-content: space-between. Но что если дизайн понадобится поменять? В таком случае придётся менять стилизацию.
Взгляните на следующий пример. Выглядит ли этот код гибким?
<Flex> <Logo /> <Link>Beep</Link> <Link>Boop</Link> <Spacer m="auto" /> <Link>Boop</Link> </Flex>
В этом случае стилизация нуждается в изменении.
В том, что касается размеров, можно сказать, что размер разделителя может быть настроен на основе размеров родительского элемента. В вышеприведённом случае, возможно, есть смысл создать свойство grow, которое в CSS устанавливается в значение flex-grow: 1.
<Flex> <Spacer grow="1" /> </Flex>
▍Использование псевдоэлементов
Ещё одна идея, которая пришла мне в голову, заключается в использовании псевдоэлементов для создания разделителей.
.element:after { content: ""; display: block; height: 32px; }
Может быть, у нас есть возможность сделать разделителем псевдоэлемент, а не использовать для этого отдельный элемент? Например:
<Header spacer="below" type="pseudo" length="32"> <Logo /> <Link>Home</Link> <Link>About</Link> <Link>Contact</Link> </Header>
До сих пор я не пользовался компонентами-разделителями в своих проектах. Но я ищу сценарии, в которых они могли бы мне пригодиться.
Математические CSS-функции min(), max(), clamp()
Можно ли сделать отступы динамическими? Например, можно ли воспользоваться таким отступом, минимальный и максимальный размер которого зависит от ширины области просмотра? Я могу ответить на этот вопрос положительно. CSS-функции, в соответствии с данными CanIUse, поддерживаются всеми ведущими браузерами.
Вспомним о Grid-макетах и поговорим о том, как в них может использоваться динамическая настройка отступов.
.wrapper { display: grid; grid-template-columns: repeat(3, 1fr); grid-gap: min(2vmax, 32px); }
Конструкция min(2vmax, 32px) означает следующее: использовать расстояние, равное 2vmax, но не превышающее 32px.
→ Вот видеодемонстрация такого макета
→ Вот пример.
Такая гибкость поистине удивительна. Она даёт нам множество возможностей по созданию динамических и гибких макетов веб-страниц.
Итоги
В этом материале мы рассмотрели особенности настройки расстояний между элементами веб-страниц с использованием CSS и поговорили об управлении внутренним пространством элементов. Надеемся, вам пригодится то, о чём вы сегодня узнали.
Уважаемые читатели! Какими средствами для настройки расстояния между элементами веб-страниц вы пользуетесь чаще всего?
ссылка на оригинал статьи https://habr.com/ru/company/ruvds/blog/499120/

Добавить комментарий