Если несколько элементов веб-страницы расположены близко друг к другу, то у пользователей возникает такое ощущение, что у этих элементов есть что-то общее. Группировка элементов помогает пользователю понять их взаимосвязь благодаря оценке расстояния между ними. Если бы все элементы были бы расположены на одинаковом расстоянии друг от друга, пользователю сложно было бы, просматривая страницу, узнать о том, какие из них связаны друг с другом, а какие — нет.
Эта статья посвящена всему, что нужно знать о настройке расстояний между элементами и о настройке внутренних пространств элементов. В частности, речь пойдёт о том, в каких ситуациях стоит использовать внутренние отступы (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 и поговорили об управлении внутренним пространством элементов. Надеемся, вам пригодится то, о чём вы сегодня узнали.
Уважаемые читатели! Какими средствами для настройки расстояния между элементами веб-страниц вы пользуетесь чаще всего?
Свойство CSS margin-right устанавливает внешний отступ справа от элемента. Положительное значение увеличивает расстояние между соседними элементами, тогда как отрицательное — сокращает.
Интерактивный пример
Вертикальные внешние отступы двух соседних блоков могут схлопнуться. Это называется схлопыванием внешних отступов.
Синтаксис
/* <lenght> значение */
margin-right: 20px; /* абсолютная длина */
margin-right: 1em; /* относительно размера текста */
margin-right: 5%; /* относительно ширины родительского блока */
/* Значения-ключевые слова */
margin-right: auto;
/* Глобальные значения */
margin-right: inherit;
margin-right: initial;
margin-right: unset;
Свойство margin-right может быть выражено как ключевое слово auto, как <число>, или как <процент>. Значение может быть положительным, нулевым или отрицательным.
Значения
<length>- : Размер отступа — фиксированная величина.
<percentage>- : Размер отступа в процентах — размер относительно длины родительского блока.
auto-
: Внешний отступ слева получает долю неиспользованного горизонтального пространства, определяется в основном выбранным способом разметки. Если значения margin-leftиmargin-rightодновременно установлены какauto, расчётное пространство распределяется равномерно. Эта таблица кратко излагает различные:Значение displayЗначение floatЗначение positionРасчётное значение autoКомментарий inline,inline-block,inline-tableлюбое staticилиrelative0Строчный способ разметки block,inline,inline-block,block,table,inline-table,list-item,table-captionлюбое staticилиrelative0, кроме случаев, когдаmargin-leftиmargin-rightустановлены какauto. В этом случае устанавливается значение, центрирующее элемент внутри его родителяБлочный способ разметки block,inline,inline-block,block,table,inline-table,list-item,table-captionleftилиrightstaticилиrelative0Блочный способ разметки (плавающие элементы) любое table-*, кромеtable-captionлюбое любое 0Внутренние table-*элементы не имеют отступов, вместо этого используйтеborder-spacing(en-US)любое, кроме flex,inline-flex, илиtable-*любое fixedилиabsolute0, кроме случаев, когдаmargin-leftиmargin-rightустановлены какauto. В этом случае, устанавливается значение центрирующее границы области внутри доступнойwidth(ширины), если значение фиксировано.Способ разметки абсолютным позиционированием flex,inline-flexлюбое любое 0, кроме случаев, когда есть положительное горизонтальное свободное пространство. В этом случае, распределяется равномерно по всем горизонтальнымautoотступам.Способ разметки с помощью flexbox
-
Формальный синтаксис
margin-right =
<length-percentage> | (en-US)
auto<length-percentage> =
<length> | (en-US)
<percentage>
Примеры
.content { margin-right: 5%; }
.sidebox { margin-right: 10px; }
.logo { margin-right: -5px; }
Спецификации
| Specification |
|---|
| CSS Box Model Module Level 3 # margin-physical |
| Начальное значение | 0 |
|---|---|
| Применяется к | все элементы, кроме элементов с табличным типом display, отличным от table-caption, table и inline-table. Это также применяется к ::first-letter и ::first-line. |
| Наследуется | нет |
| Проценты | ссылается на ширину содержащего блока |
| Обработка значения | процент, как указан, или абсолютная длина |
| Animation type | длина |
Поддержка браузерами
BCD tables only load in the browser
Сегодня мы поговорим с вами немного о принципах верстки, а именно – о способах организации отступа на вашем сайте у определенных элементов.
В качестве рассматриваемого элемента, у которого необходимо сделать отступ, может быть текст, изображение, таблица или любой другой HTML-элемент. Главное – это следовать некоторым важным правилам, о которых я сейчас расскажу.
Если вы еще только создаете свой сайт, то я рекомендую вам в верх вашего главного файла стилей вставить следующие свойства:
* {
-webkit-box-sizing: border-box;
-moz-box-sizing: border-box;
box-sizing: border-box;
}
*:before, *:after {
-webkit-box-sizing: border-box;
-moz-box-sizing: border-box;
box-sizing: border-box;
}
Зачем это нужно, спросите вы? Отвечаю на ваш вопрос наглядным примером.
Допустим, у вас есть такой элемент верстки:
<div style="width: 250px;border: 1px solid;padding: 20px;">
Hello, world!
</div>
Так будет выглядеть вариант без использования описанных выше свойств (верхний элемент) и с их использованием (нижний элемент):
Что здесь видно? Что ширина элемента в первом варианте (без использования свойств) стала больше указанной за счет добавленных отступов, что является не совсем удобным и правильным в плане верстки.
Вариант со свойствами куда более эстетичнее, но использовать его стоить осознанно, ведь при добавлении их в уже готовый сайт вы рискуете получить поехавший дизайн и «головную боль» в виде приведения всего этого в должный вид. Все проекты, которые мне довелось вести с нуля, не обошлись без этих свойств.
А теперь, собственно, поговорим о вариантах организации отступов у элементов на вашем сайте с наглядными примерами.
Внутренний отступ с помощью CSS-свойства «padding»
Чтобы вы понимали всю логику вещей, возьмем для примера следующий фрагмент верстки:
<div class="test_div">
Hello, world!
</div>
<div class="test_div">
Hello, world!
</div>
со своими стилями:
.test_div {
width: 250px;
border: 1px solid;
}
Визуальный вариант получается таким:
Что из себя представляет свойство «padding»? Оно помогает организовать внутренний отступ в указанных элементах. Добавим к нашей верстке внутренний отступ, равный 10px:
.test_div {
width: 250px;
border: 1px solid;
padding: 10px; // Внутренний отступ 10px
}
Визуально это получается так:
Число 10 в свойстве говорит о том, что внутри указанных элементов с каждой из их четырех сторон необходимо добавить отступ, равный 10px. Пиксели (px) могут быть заменены на проценты или другую поддерживаемую в CSS величину.
Всего существует два варианта указания сторон, с которых необходимо сделать отступы.
Первый – это с явным указанием сторон:
padding-top: 10px; // Внутренний отступ 10px сверху
padding-right: 10px; // Внутренний отступ 10px справа
padding-bottom: 10px; // Внутренний отступ 10px снизу
padding-left: 10px; // Внутренний отступ 10px слева
В таком случае для каждой стороны используется свое свойство. И второй:
padding: 10px 0 0 0; // Внутренний отступ 10px сверху, все остальное - 0px
padding: 10px 0; // Внутренний отступ 10px сверху и снизу, а по бокам - 0px
padding: 0 10px; // Внутренний отступ 0px сверху и сниз, а по бокам - 10px
Здесь идет простое перечисление значений, каждое из которых соответствует своей стороне. Стороны задаются так: первое значение – верх, второе – право, третье – низ и четвертое – лево, то есть все по часовой стрелке.
Если значения два[/b] (верх и право), то это значит, что зеркально эти же значения уходят вниз и влево и только так. Вроде бы все понятно. Если для какой-то из сторон вам не нужно задавать отступ – значение для этой стороны выставляете «0». Этот вариант мне нравится больше, так как он более компактный, но в своих начинаниях я использовал именно первый вариант.
Этот тип отступов хорошо подходит для разделения текста, содержания ячеек таблиц и прочей текстовой информации. Для разделения же самих элементов, подобных тем, что в примере выше, существует другое свойство.
Внешний отступ с помощью CSS-свойства «margin»
Отличительная особенность свойства «margin» – это то, что отступ добавляется вне элемента, то есть внешний.
Вариантов добавления здесь также два.
Первый – с явным указанием стороны:
margin-top: 10px; // Внешний отступ 10px сверху
margin-right: 10px; // Внешний отступ 10px справа
margin-bottom: 10px; // Внешний отступ 10px снизу
margin-left: 10px; // Внешний отступ 10px слева
Второй – с перечислением значений, каждое из которых соответствует своей стороне:
margin: 10px 0 0 0; // Внешний отступ 10px сверху, все остальное - 0px
margin: 10px 0; // Внешний отступ 10px сверху и снизу, а по бокам - 0px
margin: 0 10px; // Внешний отступ 0px сверху и сниз, а по бокам - 10px
Здесь описывать все нюансы работы с правилами я не буду, все так же, как и о свойстве «padding», о нем написано выше.
Используем margin со следующим значением:
.test_div {
width: 250px;
border: 1px solid;
margin: 10px; // Внешний отступ 10px
}
Визуально это будет выглядеть так:
Как видно из примера, в таком случае добавляется внешний отступ, разделяющий между собой указанные элементы.
Важная особенность: если вы внимательно смотрели на результат, то могли заметить, что соседние отступы у элементов не суммируются. То есть если первый элемент имеет внешний нижний отступ, равный 10px, а второй – внешний верхний отступ с этим же значением, то общее расстояние между ними будет равно также 10px. Если 10 и 15 соответственно, то общее – 15 и так далее.
Этот вариант отступов часто используется в тексте, а именно в оформлении параграфов, а также в элементах, которые имеют видимые границы.
Но оба свойства не ограничиваются лишь этими элементами. Варианты их использования вы выбираете сами, я лишь постарался преподнести вам основу о них.
В этой статье пойдёт речь о двух CSS свойствах: margin и padding. Оба они задают отступ. Но в одном случае это внешний отступ от других элементов, а во втором — внутренний отступ от содержимого. Эти свойства являются одними из наиболее часто используемых при создании сайтов. Разберём каждое по отдельности.
Внешний отступ (margin)
Для демонстрации отступа нам потребуется два блока div. Создадим их:
<div style="width: 200px;">
<div style="height: 100px;"></div>
</div>
Как можно догадаться, внешний блок ограничивает ширину внутреннего. А внутренний ограничивает высоту внешнего.
Чтобы различать блоки, подкрасим их рамки: внутренний будет красным, внешний синим. Получится такой результат:
Как видно из примера, рамки совпадают, потому что нет отступов. Теперь сделаем внешний отступ в 10px для внутреннего, красного, элемента так:
<div style="width: 200px;">
<div style="height: 100px; margin: 10px;"></div>
</div>
На странице браузера получится такой результат:
Существует возможность задать отступ для каждой стороны отдельно. Для этого используйте свойства:
- margin-left — отступ слева
- margin-right — отступ справа
- margin-top — отступ сверху
- margin-bottom — отступ снизу
Аналогично это можно сделать через свойство margin, передав ему сразу четыре значения. К примеру так: «margin: 10px 20px 30px 40px«. В таком случае отступы будут: сверху — 10px, справа — 20px, снизу — 30px, сверху — 40px. попробуем это на практике:
<div style="width: 200px;">
<div style="height: 100px; margin: 10px 20px 30px 40px;"></div>
</div>
Получится такой результат:
Как и с другими универсальными свойствами, которым можно передавать сразу 4 значения для 4 сторон (или углов), свойству margin можно передать 2 значения. К примеру так: «margin: 10px 20px«. Тогда верхний и нижний отступ будут равны 10px, а правый и левый будут равны 20px. А если передать 3 значения «margin: 10px 20px 30px«, то соответственно верхний отступ получится 10px, правый и левый — 20px, а нижний 20px.
Свойство margin может принимать ещё и значние «auto«. Это значение центрирует элемент по горизонтали.
С помощью значения auto у margin можно центрировать только блочные элементы. Для строчных используйте text-align: center.
Попробуем продемонстрировать эту центровку:
<div style="width: 200px;">
<div style="width: 100px; height: 100px; margin: 10px auto;"></div>
</div>
В результате внутренний элемент будет иметь отступ сверху и снизу в 10px и находиться по центру родительского:
Этот приём центрирования используется практически на всех сайтах, на которых контент расположен в центре экрана.
Внутренний отступ (padding)
Внутренний отступ можно сделать через CSS свойство padding. Оно принимает значения аналогично свойству margin. Можно указать от одного до четырёх значений, чтобы задать разные отступы для разных сторон. Для демонстрации результатов работы этого свойства используем текст с выравниванием во всю ширину контейнера (text-align: justify;)
<div style="
width: 200px;
text-align: justify;
padding: 10px 30px 10px 20px;
">
Тише, мыши, кот на крыше,
а котята ещё выше.
Кот пошёл за молоком,
а котята кувырком.
Кот пришёл без молока,
а котята ха-ха-ха.
</div>
Результат будет таким:
Тише, мыши, кот на крыше, а котята ещё выше. Кот пошёл за молоком, а котята кувырком. Кот пришёл без молока, а котята ха-ха-ха.
Существует возможность задать отступ для каждой стороны отдельно. Для этого используйте свойства:
- padding-left — отступ слева
- padding-right — отступ справа
- padding-top — отступ сверху
- padding-bottom — отступ снизу
Проблема расширения (box-sizing)
У свойства padding существует проблема. Это свойство расширяет элемент на величину отступа. Для наглядности создадим два одинаковых по ширине элемента «width: 200px;«, но у одного установим свойство padding:
<div style="width: 200px;">
Без отступа
</div>
<div style="width: 200px; padding: 10px 30px;">
С отступом
</div>
В браузере получится такой результат:
Без отступа
С отступом
Оба элемента имеют одинаковую ширину «width: 200px;«. Но нижний на 60 пикселей шире из-за того, что слева и справа есть отступ padding (по 30 px каждый), который расширяет этот элемент.
Чтобы такого не происходило, необходимо задать элементу свойство box-sizing в значении border-box (по умолчанию оно в значении content-box):
<div style="width: 200px;">
Без отступа
</div>
<div style="width: 200px; padding: 10px 30px; box-sizing: border-box;">
С отступом
</div>
Тогда вместо того, чтобы раздвигать границы элемента, будет сужаться область внутри него.
Без отступа
С отступом
Расширение элементов из-за внутреннего отступа padding иногда сильно мешает. Особенно при создании мобильных версий сайтов. Из-за них чаще всего на мобильных устройствах появляется горизонтальная прокрутка. Поэтому заранее убедитесь, что поставили свойство box-sizing в значение border-box для самых больших элементов на странице .
Здравствуйте, уважаемые читатели блога webcodius.ru! Сегодня мы продолжим изучение каскадных таблиц стилей или CSS. В прошлых статьях мы уже рассмотрели в общих чертах блочную верстку сайта. В результате у нас стали получаться вполне профессиональные web-страницы, но чего-то им не хватает. А не хватает им скорей всего отступов и рамок. Сегодня мы и займемся рассмотрением стилевых правил margin, padding и border, которые позволяют задавать отступы и рамки для html-элементов.
Параметры отступов в CSS
С помощью каскадных таблиц стилей существует возможность задавать отступы двух видов.
1. Внутренний отступ — это расстояние от воображаемой границы элемента до его содержимого. Величина расстояния задается с помощью параметра padding. Такой отступ принадлежит самому элементу и находится внутри него.
2. Внешний отступ — расстояние между границей текущего элемента веб-страницы и границами соседних элементов, либо родительского элемента. Размер расстояния регулируется свойством margin. Такой отступ находится вне элемента.
Для наглядности картинка:
Например, рассмотрим ячейку html таблицы заполненную текстом. Тогда внутренний отступ это расстояние между воображаемой границей ячейки и содержащимся в ней текстом. А внешний отступ это расстояние между границами соседних ячеек. Начнем с внутренних отступов.
Внутренние отступы в CSS с помощью padding (top, bottom, left, right)
Свойства стиля padding-left, padding-top, padding-right и padding-bottom позволяют задать величины внутренних отступов, соответственно, слева, сверху, справа и снизу элемента web-страницы:
padding-top | padding-right | padding-bottom | padding-left: значение | проценты | inherit
Величину отступа можно указывать в пикселах (px), процентах (%) или других допустимых для CSS единицах. При указании процентов, значение считается от ширины элемента. Значение inherit указывает, что оно наследуется от родителя.
Например, для текущего абзаца я применил правило стиля, задающий левый отступ 20 пикселей, верхний отступ 5 пикселей, справа отступ 35 пикселей и снизу 10 пикселей. Запись правила в файле каскадных таблиц стилей будет выглядеть следующим образом:
p.test{
padding-left:20px;
padding-top:5px;
padding-right:35px;
padding-bottom:10px
}
Сборное правило padding позволяет указать отступы сразу со всех сторон элемента веб-страницы:
padding: <отступ 1> [<отступ 2> [<отступ 3> [<отступ 4>]]]
В сборном правиле разрешается использовать одно, два, три или четыре значения, разделяя их между собой пробелом. В этом случае эффект зависит от количества значений:
- если указать одно значение, то оно установит величину отступа со всех сторон элемента страницы;
- если указать два значения, то первое задаст величину отступа сверху и снизу, а второе — слева и справа;
- если указать три значения, то первое определит величину отступа сверху, второе — слева и справа, а третье — снизу;
- если указаны четыре значения, то первое установит величину отступа сверху, второе — справа, третье — снизу, а четвертое — слева.
Таким образом правило CSS приведенное выше можно максимально сократить и записать следующим образом:
p.test{ padding:5px 35px 10px 20px}
Свойство margin или внешние отступы в CSS
Атрибуты стиля margin-left, margin-top, margin-right и margin-bottom позволяют задать величины внешних отступов, соответственно, слева, сверху, справа и снизу:
margin-top | margin-right | margin-bottom | margin-left: <значение>|auto|inherit
Как уже упоминалось выше внешним отступом является расстояние от границы текущего элемента до границы соседнего элемента, либо, если соседних элементов нет, до внутренней границы родительского контейнера.
Величину отступа можно указывать в пикселах (px), процентах (%) или других допустимых для CSS единицах:
p {
margin-left: 20px;
}
h1{
margin-right:15%;
}
Значение auto означает, что размер отступов будет автоматически рассчитан браузером. В случае использования процентной записи, то отступы рассчитываются в зависимости от ширины родительского контейнера. Причем это относится не только к margin-left и margin-right, но и для margin-top и margin-bottom отступы в процентах будут рассчитываться в зависимости от ширины, а не высоты контейнера.
В качестве значений внешних отступов допустимо применять отрицательные величины:
p{
margin-left:-20px;
}
Если при положительных значениях отступов соседние элементы отодвигаются, то при отрицательном значении соседний блок наедет на элемент для которого мы задали такой отрицательных отступ.
Внешние отступы мы также можем указать с помощью атрибута стиля margin. Он задает величины отступа одновременно со всех сторон элемента web-страницы:
margin: <отступ 1> [<отступ 2> [<отступ 3> [<отступ 4>]]]
Данное свойство в случае задания одного, двух, трех или четырех значений отступов подчиняется тем же законам, что и правило padding.
Параметры рамки с помощью свойства border
При настройке рамок существует три типа параметров:
- border-width — толщина рамки;
- border-color — цвет рамки;
- border-style — тип линии с помощью которой будет нарисована рамка.
Начнем с параметра толщины рамки:
border-width: [значение | thin | medium | thick] {1,4} | inherit
Толщину рамки можно задавать в пикселях, либо в других доступных в css единицах. Переменные thin, medium и thick задают толщину рамки в 2, 4 и 6 пикселей соответственно:
border-width:medium;
Как и для свойств padding и margin, для параметра border-width разрешается использовать одно, два, три или четыре значения, задавая таким образом толщину рамки для всех сторон сразу или для каждой по отдельности:
border-width: 5px 3px 5px 3px
Для текущего абзаца сделаем толщину верхней рамки 1px, правой 2px, нижней 3px, а левой 4px с помощью правила {border-width: 1px 2px 3px 4px;}
С помощью атрибутов стиля border-left-width, border-top-width, border-right-width и border-bottom-width можно задавать толщину, соответственно, левой, верхней, правой и нижней сторон рамки:
border-left-width|border-top-width|border-right-width|border-bottom-width: thin|medium|thick|<толщина>|inherit
Следующий параметр border-color с помощью которого можно управлять цветом рамки:
border-color: [цвет | transparent] {1,4} | inherit
Свойство позволяет задать цвет рамки сразу для всех сторон элемента или только для указанных. В качестве значения можно использовать принятые в html для цветов способы их задания: шестнадцатеричный код, ключевые слова и т.д.:
p {border-width: 2px; border-color: red}
Значение transparent устанавливает прозрачный цвет рамки, а inherit наследует значение родителя. По умолчанию, если цвет рамки не задан, то будет использоваться тот, который используется для шрифта внутри данного элемента.
С помощью атрибутов стиля border-left-color, border-top-color, border-right-color и border-bottom-color можно задать цвет, соответственно, левой, верхней, правой и нижней сторон рамки:
border-left-color|border-top-color|border-right-color|border-bottom-color: transparent|<цвет>|inherit
И последний параметр border-style задает тип рамки:
border-style: [none | hidden | dotted | dashed | solid | double | groove | ridge | inset | outset] {1,4} | inherit
Тип рамки можно указывать сразу для всех сторон элемента или только для указанных. В качестве значений можно использовать несколько ключевых слов. Вид будет зависеть от используемого браузера и толщины рамки. Значение none используется по умолчанию и не отображает рамку и ее толщина задается нулевой. Значение hidden имеет тот же эффект. Получаемая рамка для остальных значений в зависимости от толщины приведена в таблице ниже:
| 1 пиксел | 3 пиксела | 5 пикселов |
|---|---|---|
|
dotted |
dotted |
dotted |
|
dashed |
dashed |
dashed |
|
solid |
solid |
solid |
|
double |
double |
double |
|
groove |
groove |
groove |
|
ridge |
ridge |
ridge |
|
inset |
inset |
inset |
|
outset |
outset |
outset |
Атрибуты стиля border-left-style, border-top-style, border-right-style и border-bottom-style задают стиль линий, которыми будет нарисована, соответственно, левая, верхняя, правая и нижняя сторона рамки:
border-left-style|border-top-style|border-right-style|border-bottom-style: none|hidden|dotted|dashed|solid|double|groove|ridge|inset|outset|inherit
Как и для параметров внешних и внутренних отступов, для рамки существует универсальное свойство border. Оно позволяет одновременно установить толщину, стиль и цвет границы вокруг элемента:
border: [border-width border-style border-color] | inherit
Значения могут идти в любом порядке, разделяясь пробелами:
td {border: 1px solid yellow}
Для установки границы только на определенных сторонах элемента существуют свойства border-top, border-bottom, border-left, border-right, которые позволяют задать параметры соответственно для верхней, нижней, левой и правой стороны рамок.
Осталось только подвести итоги:
- для задания внутренних отступов пользуемся свойством padding;
- для настройки внешних отступов существует правило margin;
- параметры рамок задаются с помощью атрибута border.
Отмечу, что все эти css свойства увеличивают размеры элемента web-страницы. Поэтому, если мы изменяем толщину рамки или размер отступов у блочных контейнеров, формирующих дизайн web-страницы, то должны будем соответственно изменить размеры этих контейнеров, иначе они могут сместиться, и дизайн будет нарушен.
На этом все, до новых встреч!
Цель урока: Знакомство со свойствами, задающими отступы и границы элемента CSS; свойства margin, padding, border и outline
Элемент в html — это прямоугольник, для которого можно указать величины внутренних и внешних отступов, а также границу, которая разделяет их.
Отступы в CSS устанавливаются, например, для блочных элементов и таблиц. Рассмотрим основные свойства CSS для установки отступов:
Внешние отступы
Внешние отступы в CSS задаются при помощи свойства margin, которое устанавливает величину отступа от границ текущего элемента до внутренней границы его родительского элемента.
Свойство:
margin-bottom(нижний отступ)margin-left(отступ слева)margin-right(отступ справа)margin-top(верхний отступ)
Значения:
auto- величина:
pxилиem %
Краткая запись:
margin:margin-top margin-right margin-bottom margin-left; margin:10px 20px 20px 30px;
Пример:
...
<style type="text/css">
p{ border:5px solid red; /* красная рамка */ margin:20px; } div{ border:5px solid green; /* зеленая рамка */ }
</style></head> <body> <div> Агния Барто - стихи <p> Я на уроке в первый раз.<br/> Теперь я ученица.<br/> Вошла учительница в класс,-<br/> Вставать или садиться?<br/> </p> ...
Результат:
Агния Барто — стихи
Я на уроке в первый раз.
Теперь я ученица.
Вошла учительница в класс,-
Вставать или садиться?
Внутренние отступы
Внутренние отступы в css создаются при помощи свойства padding, которое устанавливает значение полей от внутреннего края рамки элемента до воображаемого прямоугольника, ограничивающего его содержимое.
Свойства:
padding-bottom(нижний отступ)padding-left(отступ слева)padding-right(отступ справа)padding-top(верхний отступ)
Значения:
auto- величина:
pxилиem %
Краткая запись:
padding:padding-top padding-right padding-bottom padding-left; padding:10px 20px 20px 30px;
Пример:
...
<style type="text/css">
p{ border:5px solid red; /* красная рамка */ padding:20px; /* внутренний отступ */ }
</style></head> <body> <p> Я на уроке в первый раз.<br/> Теперь я ученица.<br/> Вошла учительница в класс,-<br/> Вставать или садиться?<br/> </p> ...
Результат:
Я на уроке в первый раз.
Теперь я ученица.
Вошла учительница в класс,-
Вставать или садиться?
Граница элемента (рамка)
Граница элемента в CSS устанавливается при помощи свойства border.
border-style (стиль границы)
Значения:
none(без границы)dotted(из точек)dashed(пунктирная)solid(сплошная)double(двойная)groove(трехмерная)ridge(трехмерная)inset(трехмерная с тенью)outset(трехмерная с тенью)
Пример:
none
dotted
dashed
solid
border-width (ширина границы)
Значения:
thin(тонкая)medium(средняя)thick(толстая)- значение
Пример:
p.one{ border-style:solid; border-width:5px; } p.two{ border-style:solid; border-width:medium; }
</style></head> <body> <p class="one"> Я на уроке в первый раз.<br/> Теперь я ученица.<br/> Вошла учительница в класс,-<br/> Вставать или садиться?<br/> </p> <p class="two"> Как надо парту открывать,<br/> Не знала я сначала,<br/> И я не знала, как вставать,<br/> Чтоб парта не стучала.<br/> </p>
Результат:
Я на уроке в первый раз.
Теперь я ученица.
Вошла учительница в класс,-
Вставать или садиться?
Как надо парту открывать,
Не знала я сначала,
И я не знала, как вставать,
Чтоб парта не стучала.
border-color (цвет границы)
Значения:
red(цвет)rgb(255,0,0)(в системе rgb)#ff0000(в шестнадцатиричной системе)transparent(прозрачная)
Для каждой стороны границы можно задать свой стиль:
p{ border-top-style:solid; border-right-style:dotted; border-bottom-style:dashed; border-left-style:none; border-top-color:#0f0; border-right-color:#f00; }
Результат:
Я на уроке в первый раз.
Теперь я ученица.
Вошла учительница в класс,-
Вставать или садиться?
Краткая запись:
border:border-width border-style border-color; border: 1px solid #000;
Внешние границы (outline)
Внешние границы в CSS создаются при помощи свойства outline, одновременно устанавливающее цвет, стиль и толщину внешней границы на всех четырех сторонах элемента. В отличие от линии, задаваемой через border, свойство outline не влияет на положение блока и его ширину.
outline-color (цвет)
Значения:
red(цвет)rgb(255,0,0)(в системе rgb)#ff0000(в шестнадцатеричной системе)invert(инвертированный, противоположный)
outline-width (ширина)
Значения:
thin(тонкая)medium(средняя)thick(толстая)- значение
outline-style (стиль границы)
Значения:
none(без границы)dotted(из точек)dashed(пунктирная)solid(сплошная)double(двойная)groove(трехмерная)ridge(трехмерная)inset(трехмерная с тенью)outset(трехмерная с тенью)
Краткая запись:
outline:outline-color outline-style outline-width; outline: #0f0 solid thick;
Некоторые приемы с границей
Рамка вокруг изображения
Пример:
img{ padding:20px; /* Поля вокруг изображения */ margin-right:10px; /* отступ справа */ margin-bottom:10px; /* отступ снизу */ outline:1px solid #666; /* параметры границы */ background:#f0f0f0; /* цвет фона */ }
Результат:

Двойная рамка с использованием CSS
Пример:
p{ border:5px solid red; outline:6px solid orange; }
Результат:
Путь осилит идущий,
И поэтому я иду.
Через горы и пущи,
Через радость мою и беду.
Эффектные рамки для изображений
Пример:
... .photo { width : 150px; padding : 10px 10px 20px 10px; border : 1px solid #BFBFBF; background-color : white; -webkit-box-shadow : 2px 2px 3px rgba(135, 139, 144, 0.4); -moz-box-shadow : 2px 2px 3px rgba(135, 139, 144, 0.4); box-shadow : 2px 2px 3px rgba(135, 139, 144, 0.4); }
</style></head> <body> <div class="photo"> <img src="2.JPG" width="150" alt=""> <p>Не ешь меня!!!</p> </div> ...
Результат:

Здравствуйте, уважаемые читатели блога KtoNaNovenkogo.ru. Сегодня я хочу продолжить тему изучения CSS (каскадных таблиц стилей) и рассмотреть те стилевые правила, которые позволяют задать отступы и границы для Html элементов: border, margin и padding.
До этого мы успели изучить довольно-таки простые свойства, которые управляли шрифтами (Font Weight, Family, Size, Style), текстом (text-decoration, vertical-align, text-align) и рассмотрели модель формирования фона в CSS через background.
Да, еще мы и принципы использования селекторов успели рассмотреть во всех подробностях (растянувшихся на несколько статей). Теперь пора переходить к правилам, которые составляют основу построения документов (вебстраниц), и начнем мы именно с блочной модели (взаимоотношения Html элементов).
В общих чертах я уже писал про блочную Div верстку и современную верстку сайта, ну, а сегодня будет уже чистая конкретика. Если вы захотите ознакомиться с предыдущими публикациями по теме, то милости прошу в справочник.
Блочная модель в CSS — padding, margin и border
Для браузера Firefox есть замечательный плагин под названием Фаербаг, о котором я уже довольно давно и подробно писал.
При просмотре информации о любом Html теге веб страницы, этот плагин на вкладке «Макет» позволяет увидеть очень наглядное представление отступов и границ данного элемента относительно родительского и тех тегов (или же содержимого), которые заключены внутри оного (матрешка такая получается):
На этой схеме четко видно, что для любого Html элемента в CSS можно четко задать размеры четырех прямоугольных областей. Внутри всей конструкции лежит, собственно, содержимое этого тега (например, текст или изображение), которое может в свою очередь включать в себя и другие вложенные элементы (например, таблица с ячейками и их содержимым).
Если начинать рассматривать эту матрешку изнутри, начиная с содержимого, то дальше идет область внутреннего отступа от этого содержимого до рамки этого тега. Размер области задается с помощью CSS правила Padding, а ширину рамки можно задать с помощью Border.
Следуя из центра к периферии, мы после рамки должны будем задать область внешнего отступа с помощью Margin. Оно позволяет регулировать взаимоотношения с границами других блоками. Например, с помощью задания отрицательных отступов в CSS правиле мерджин, можно добиваться наложения одних блоков веб страницы на другие соседние блоки этой же страницы.
Сразу оговорюсь, что вы можете задавать Padding и Margin, а также размеры рамки Border отдельно для каждой из сторон блока (прямоугольной области), которые определяются как:
- top (верх) — например, padding-top, margi-top, border-top
- bottom (низ)
- left (слева)
- right (справа)
Ну и для примера посмотрим, что именно будут обозначать border, margin и padding применительно к каким-то конкретным сторонам блочной модели:
Вообще для ее понимания нужно прежде всего понять, что любой Html элемент лежит внутри какой-то области. Эту область в CSS принято называть контейнер, и обычно контейнером для блока является область контента его родительского элемента.
На приведенном чуть выше скриншоте граница внешнего контейнера обозначена черной внешней рамочкой, ну а для заключенных внутри этого родительского элемента тегов (если таковые имеют место быть) контейнером уже будет являться внутренняя область, окрашенная в желтоватый цвет. Поясняющий скриншот:
Получилось слегка запутано, но так оно всегда бывает поначалу. Со временем у вас все в голове устаканится и блочная модель примет ясные и стройные очертания. Иначе и быть не может.
Margin (top, bottom, left, right) — внешние отступы в CSS
Давайте начнем рассмотрение CSS свойств для задания отступов и границ с Margin. Понятно, что это правило может быть написано отдельно для каждой из сторон блочной модели и в нем допустимо использовать следующие значения:
Наш элемент, для которого мы прописывает данное правило, взаимодействует с границами своего контейнера и с границами соседних блоков, которые в коде расположены рядом с ним. Соответственно, существуют четыре CSS правила для каждой из имеющихся границ: margin-top,right, bottom и left. Что можно использовать в качестве значений для них?
Ну, во-первых, это волшебное Auto, которое отдает на откуп браузеру расчет этих самых внешних отступов. Понятно, что браузеры для расчетов используют какие-то значения, и тут все далеко не тривиально. Пока отметим для себя, что margin Auto предполагает самостоятельный расчет этих значений браузером.
Во-вторых, в качестве значений для margin-top, right, bottom и left можно использовать размерные величины Em, Ex или Px.
В-третьих, могут использоваться проценты. От чего же они считаются? Оказывается, что от ширины контейнера (то есть от области контента родительского элемента). Причем, это относится не только к margin-right и left, что было бы логично, но и для margin-top и bottom проценты будут рассчитываться именно от ширины (а не высоты) контейнера.
Надо отметить, говоря про задание размерных значений, что Margin может быть еще и отрицательным. Т.е. при задании положительного значения для внешнего отступа мы отодвигаем соседний элемент на указанное расстояние, а в случае указания отрицательного — соседний блок просто-напросто заедет на тот, для которого мы этот отрицательный отступ задали. И это очень часто используется в CSS.
Ну и само собой разумеется, что существует сборное CSS правило Margin, которое во многих случаях позволяет сократить размер кода используемого для задания требуемых внешних отступов. Порядок следования значений в нем строго регламентируется (они прописываются через пробельный символ) и должно соответствовать образцу:
Т.е. перечисление начинается с верхнего (top) и продолжается по часовой стрелке вплоть до завершения круга правым отступом (right). Выглядеть это может примерно так:
margin:20px 10px 40px 30px;
И это будет означать, что браузер сверху от нашего блока должен сделать отступ в 20 пикселей, справа — в 10, снизу — в 40, а слева — в 30. Т.е. эта запись будет эквивалентна такой:
margin-top:20px; margin-right:10px; margin-bottom:40px; margin-left:30px;
Сокращение CSS кода видно невооруженным глазом. Но и это еще не предел. Вполне допустимо использовать в сборном правиле не только четыре, но и три, два и даже всего одно значение. Что еще больше поможет уменьшить размер кода. Однако, уменьшать количество значений можно будет только в определенных случаях:
- Если величины внешних отступов слева и справа будет одинаковыми, например, так:
margin:20px 30px 40px 30px;
То последнее можно будет опустить:
margin:20px 30px 40px;
Эти две записи сборного правила делают одно и то же. Поэтому, если вы видите запись с тремя величинами в Margin, то величину четвертого (справа) можно будет подсмотреть во втором (слева).
В случае равенства отступов сверху и снизу такой фокус уже не пройдет, ибо по логике можно уменьшать структуру записи сборного правила, лишь отсекая дублирующее значения с ее конца (а значение нижнего отступа будет стоять предпоследним).
- Если кроме равенства внешних отступов слева и справа имеет место быть равенство их величин сверху и снизу:
margin:20px 30px 20px 30px;
или, что то же самое (в силу пункта 1):
margin:20px 30px 20px;
То такое сборное правило можно записать всего с двумя значениями, отбросив последнее, которое совпадает с первым:
margin:20px 30px;
В этом случае первая величина описывает внешние отступы по вертикали, а вторая — по горизонтали.
- Ну и, наконец, если все значения в сборном правиле будут одинаковыми:
margin:20px 20px 20px 20px;
или, что то же самое (в силу пункта 2):
margin:20px 20px;
То можно будет использовать максимально сокращенный тип записи (отбросив последнее значение совпадающее с первым):
margin:20px;
Что будет означать одинаковый внешний отступ со всех сторон от нашего Html элемента.
Говоря про внешние отступы, стоит упомянуть про такую схему как «Margin-colloapse» или, по другому, «схлопывание марджинов». В двух словах суть этого явления заключается в следующем.
Если у нас есть два блока расположенные друг под другом (схлопывание марджинов может происходить только по вертикали) и для них обоих заданы встречные внешние отступы (например, нижний для верхнего элемента и верхний отступ для нижнего), то большее значение Margin поглотит в себе меньшее.
Например, если для верхнего блока задано следующее:
margin:20px 20px 200px 20px;
А для нижнего:
margin:100px 20px 20px 20px;
То нижний марджин верхнего блока (200px) поглотит в себе верхний марджин нижнего (100px, да и даже если он станет равен 199px ничего не изменится) и результирующий внешний отступ между этими двумя блоками все равно будет равен 200px. Т.е. в расчет принимается только лишь больший по модулю Margin, и он никак не складывается со встречным значением соседнего по вертикали элемента.
Такая вот заковыка, которая работает исключительно по вертикали, а по горизонтали встречные размеры Margin будут просто плюсоваться друг к дружке. Но это только касаемо марджинов с одинаковым знаком, а вот если они будут с разными знаками, то их числа просто сложатся и блоки будут отстоять друг от друга на результирующую величину.
Например, в этом случае:
Верхний margin:20px 20px -20px 20px;
Нижний margin:10px 20px 20px 20px;
Результирующий отступ между блоками будет равен -10px, т.е. нижний на 10px наедет на верхний Html элемент.
Еще одной особенностью использования правила Margin в CSS является то, что прописанное значение по вертикали для строчных элементов игнорируется. Задав:
margin:20px;
Например, для гиперссылки, которая является строчным элементом, мы реально увидим только отступы по горизонтали, а по вертикали никаких изменений не произойдет.
Забегая чуть вперед скажу, что Padding у строчных тегов по вертикали сработает, но увеличившийся внутренний отступ никак не скажется на его общем положении относительно других соседних элементов.
В случае блочного тега (заголовки, абзацы) увеличившийся по вертикали Padding подвинул бы этот элемент относительно других соседних блоков.
Ну и рамка (Border), а точнее ее ширина, тоже не сможет отодвинуть по вертикали от строчного тега другие соседние блоки. Для строчных элементов движуха возможна только в одном направлении — по горизонтали и все.
Padding и border — внутренние отступы и рамки
Давайте теперь перейдем к заданию внутренних отступов с помощью правила Padding и посмотрим, какие именно значения оно может принимать:
Как вы можете видеть, тут нет упоминания Auto, а также это CSS правило не допускает использование отрицательных значений (они могут быть только положительными — от нуля и выше). Т.е. с помощью Padding контент за пределы рамки выдвинуть никак не получится. Максимум что можно сделать, это контент вплотную приблизить к рамке.
Проценты в нем считаются точно так же, как в Margin — относительно ширины контейнера (области контента родительского элемента), в котором заключен наш элемент. Сборное правило Padding в Css формируется и подчиняется тем же законам, что и рассмотренное чуть выше:
padding:20px 10px 40px 30px;
В этом правиле мы, начиная с верха, описываем все четыре стороны. Если в нем нужно будет чего-то сократить (до трех, двух или даже одного значения), то использовать нужно будет описанные чуть выше принципы сокращения для внешних отступов, которые ровно с таким же успехом будут работать и для внутренних.
И последнее, что сегодня я хотел бы рассмотреть — это рамки, которые задаются с помощью Border. У них есть три типа параметров:
- Border-width — задает толщину рамки
- Border-color — задает ее цвет
- Border-style — тип рамки или же тип линии, которой она будет отрисована
У всех этих трех CSS правил имеется допустимый набор значений:
Ширина линии для рамки (Border-width) может задаваться как с помощью цифр в Em, Ex или Px, так и словами:
- Thin — тонкая линия;
- Medium — средняя (данное значение используется по умолчанию);
- Thick — толстая.
border-width:2px;
В качестве значения для цвета рамки (Border-color) можно использовать принятые для цветов в Html способы их задания (шестнадцатеричный код, слова и т.д.):
border-color:red;
По умолчанию, если цвет для рамки явно не задан, то будет использоваться тот, который используется для шрифта внутри данного элемента.
CSS свойство Border-style позволяет задать словами тип рамки:
- None — без рамки (используется по умолчанию)
- Dotted — линия отрисовывается точками
- Dashed — пунктиром
- Solid — сплошной линией
- Double — двойной линией
- Groove — вдавленная рамка
- Ridge — выпирающая
- Inset и outset — игры с тенью
Естественно, что раз есть четыре стороны любого блока, то можно использовать как общие правила, так и отдельные для каждой из сторон:
Тоже самое будет касаться и сборного правила Border — оно может быть прописано как для всех сторон одновременно (Border), так и для каждой из сторон в отдельности (Border-top, left, bottom и right). Порядок следования значений не важен:
border:1px solid red;
Если что-то пропустить, то вместо него будет использоваться значение по умолчанию.

Хочешь знать больше про веб?
Подпишись на наш телеграм-канал TechRocks WEB-разработка?
Подписаться
×
Перевод статьи
«How to Understand and Work With CSS Margins».
CSS имеет дурную привычку вести себя
не так, как ожидается. И одна из вещей,
которые больше всего сбивают людей с
толку, это внешние отступы (margin). Кажется,
что здесь все должно быть довольно
просто, но эти отступы способны приводить
к очень странным проблемам.
Для людей, лишь начинающих работать
с CSS, свойство margin легко становится одной
из вещей, заставляющих думать, что «это
идиотский, бессмысленный язык!».
Я ежедневно сталкиваюсь с подобным,
как в классе, где мои ученики пытаются
разобраться в проблемах с отступами,
так и в разделе комментариев на
моем YouTube-канале.
Внешние отступы это в определенном
смысле модель всего CSS. CSS кажется
настолько простым с его парами «свойство:
значение», но по мере того как вы
углубляетесь в него, вы начинаете
понимать, что все гораздо сложнее.
Отступы тоже кажутся простой вещью.
Вы добавляете какой-нибудь margin и таким
образом добавляете пустое пространство
вокруг элемента. Но внезапно этот код
начинает вести себя немного по-разному
в разных ситуациях. Или вот, скажем,
добавляете вы свойство margin-top
элементу-потомку, а в результате
родительский элемент ползет вниз.
Это раздражает.
В этой статье я надеюсь пролить свет
на некоторые вопросы работы margin-ов. Мы
рассмотрим несколько распространенных
проблем, возникающих при применении
этого свойства, а также простые решения
этих проблем.
Что такое margin?
Прежде чем двинуться дальше, я хотел
бы удостовериться, что все мы знаем, что
из себя представляют эти самые margin-ы!
Я предположу, что все знают, что внешние
отступы это часть блочной модели. В этой
модели margin это то, что находится снаружи,
т. е., идет после контента, внутреннего
отступа (padding) и границы (border).
MDN очень хорошо объясняет, что такое
margin:
«Margin это самый внешний слой, окружающий
контент, padding и border. Это пустое пространство
между блоком, к которому margin относится,
и другими элементами. Размер этого
пространства контролируется свойством
margin и его значениями».
Другими словами, это пустое пространство,
которое можно использовать для создания
отступов между блоками в макете.
Стили браузера (user-agent
stylesheets)
Браузеры по умолчанию имеют удивительно
большое количество CSS, т. н. user-agent
stylesheets. Именно благодаря этим стилям
элемент <h1> будет отображаться
крупнее, чем <h2>, даже если в нашем
документе никакого CSS не будет. И именно
этим стилям мы обязаны тем, что у элемента
<body> есть свойство margin, которое нам
приходится постоянно удалять.
Эти стили имеют большое значение, но
при этом их наличие приводит к одной из
самых больших проблем в использовании
внешних отступов. Дело в том, что по
умолчанию не все наши элементы имеют
нулевые margin-ы, и, как мы вскоре узнаем,
это приводит к разнообразным и странным
проблемам.
Списки, цитаты, абзацы и заголовки —
все они имеют внешние отступы (и у других
элементов отступы тоже есть). И хотя
порой это доставляет лишь небольшие
неудобства, установленный по умолчанию
margin абзацев и заголовков — одна из
основных причин проблем с блоками.
По умолчанию для левого и правого
внешнего отступа текстового элемента
установлено нулевое значение, а вот
для margin-top и margin-bottom — нет.
Я часто говорю людям, что эти дефолтные
значения сверху и снизу, если брать
грубо, такие же, как font-size элемента. Это
верно для абзацев, а также заголовков
от <h3> до <h6>. Для <h1> это 0.67em, а
для <h2> — 0.83em.
Все вышесказанное означает, что между
нашими элементами на странице существует
пустое пространство, даже если явно мы
отступов не задавали.
К дефолтным значениям мы еще вернемся.
Схлопывание внешних отступов
Схлопывание отступов часто бывает
причиной головной боли.
Когда у двух элементов есть вертикальные
внешние отступы, соприкасающиеся друг
с другом, они комбинируются в единый
отступ.
Это само по себе странное поведение,
но добавьте к этому еще и тот факт, что
речь идет исключительно о вертикальных
отступах (верхнем и нижнем). Это часто
путает и раздражает людей.
Увидеть все это в действии можно на
следующем примере:
p {
font-size: 18px;
margin-bottom: 40px;
}
.links {
margin-top: 40px;
}
Чтобы проиллюстрировать происходящее,
в нашем примере класс .links добавлен к
последнему абзацу (<p class=»links»>),
который содержит в себе две ссылки.
Когда люди делают что-то подобное, они
ожидают, что отступ между средним абзацем
и ссылками будет равен 80px (40px + 40px), но в
итоге оказывается, что он равен 40px. Два
внешних отступа соприкасаются, а потому
комбинируются в один отступ (схлопываются).

Чтобы эффект стал еще заметнее, давайте
установим значение margin-bottom элемента
<p> в 100px:
p {
font-size: 18px;
margin-bottom: 100px;
}
.links {
margin-top: 40px;
}
Опять же, два отступа не просто
складываются, они схлопываются в один
отступ шириной в 100px.

И это хорошо
В подобных случаях, на самом деле,
схлопывание это положительный момент.
Если у вас несколько элементов с разными
внешними отступами, нет необходимости
складывать их, чтобы понять, насколько
широким будет расстояние между элементами.
Мы можем рассчитывать на тот факт, что
всегда побеждает больший отступ.
Мы часто даже не задумываемся над
этим, ведь эта особенность всегда
работает именно таким образом.
Но хорошо это не всегда
Но схлопывание отступов приводит к
путанице, когда margin-top первого потомка
внутри элемента схлопывается с
родительским margin-top.
Давайте еще раз посмотрим на наш
скриншот:

Между верхом зоны просмотра и черным
блоком есть пробел. И это не из-за body
(потому что пробел гораздо больше отступа
в 8px, который обычно бывает у body).
Угадайте, откуда появился этот отступ?
На самом деле это отступ элемента <h1>
вверху черного блока.
Помните, я говорил, что стили браузера
способны приводить к странным проблемам?
Чтобы пояснить, что конкретно здесь происходит, давайте зададим существенно больший margin-top заголовку h1.
.card {
background: #000;
color: white;
width: 560px;
margin: 0 auto;
}
h1 {
font-size: 24px;
margin-top: 100px;
}
p {
font-size: 18px;
margin-bottom: 100px;
}
.links {
margin-top: 10px;
}
Я постоянно вижу, как люди пытаются
опустить заголовок внутри его
родителя. Но вместо ожидаемого поведения
мы получаем гигантский отступ сверху
всего блока!

Это происходит потому, что margin-top
заголовка <h1> схлопывается с margin-top
родительского элемента.
В этом случае ничто не разделяет верх
элемента-потомка и элемента-родителя.
Поэтому, когда мы добавляем margin-top
элементу-потомку, он соприкасается с
родительским margin-top. А как мы уже знаем,
соприкасающиеся внешние отступы
комбинируются в один отступ.
Таким образом, когда мы задаем margin
элементу-потомку, он применяется к
родительскому элементу.
Вот почему люди ненавидят CSS.
Аналогично, в приведенном выше коде
мы задали всем абзацам margin-bottom. Этот
отступ у элементов p.link соприкасается
с margin-bottom элемента .card, а значит, отступы
комбинируются, и margin влияет не на ссылки,
а на элемент .card.

Хотя в настоящее время это не приводит
ни к каким проблемам на созданном нами
сайте, они могут возникнуть в будущем,
когда мы решим добавить другие элементы
на страницу.
Дело в использовании margin не
по назначению
Если мне нужно пространство между
элементом .card и потомками внутри него,
мне, прежде всего, вообще не стоит
использовать margin.
Новички часто путают margin и padding. У меня
есть правило на этот случай. Если вам
нужно пустое пространство, используйте
margin. Если вам нужно больше фона, используйте
padding.
В нашем случае мы хотим, чтобы у элемента
.card было больше фона. Поэтому нам не
следует добавлять margin для потомка.
Вместо этого нам нужно добавить padding
для самого элемента .card.

На картинке хорошо видно, где padding, а
где margin. У заголовка <h1> сверху
по-прежнему есть margin, но он больше не
сливается с отступом .card, потому что в
качестве буфера добавлен padding. Это не
дает внешним отступам .card и <h1>
соприкоснуться.
Поскольку padding дает достаточное
расстояние между абзацами <p> и
заголовками <h1>, мы можем удалить
добавленные ранее внешние отступы.

Внешние отступы схлопываются
не всегда
В схлопывании внешних отступов есть
исключения. Прямые потомки родителей
grid и flex не имеют схлопывающихся отступов.
/Закатывает глаза/
Но есть возможность это обойти — и мы
возвращаемся к стилям браузера, а которых
уже говорили ранее.
Есть простой способ вообще
забыть о схлопывании внешних отступов
Прежде всего, напомню о своем правиле
выбора между внешним и внутренним
отступом:
- Если вам нужно пустое пространство,
используйте margin. - Если вам нужно больше фона, используйте
padding.
Это правило в большинстве случаев
поможет вам избежать проблем. Но давайте
добавим еще одно правило (оно даже еще
полезнее):
- Старайтесь вообще не использовать
margin-top, за исключением случаев, когда
это действительно необходимо.
Это правило немного конфликтует со
стилями браузера, которые устанавливают
margin-top и margin-bottom целому ряду элементов.
Вот поэтому я часто делаю так:
h1,
h2,
h3,
h4,
h5,
h6,
p,
ul,
ol {
margin: 0 0 1em 0;
}
Это устраняет большое количество
проблем, связанных с самовольным
схлопыванием внешних отступов, а также
с различиями в макете, когда где-то
используется flex или grid, а где-то — нет.
(Примечание: если вы проверите код на
freeCodeCamp, вы увидите, что они тоже поступают
подобным образом!)
Это не идеальное решение, кроме того, я часто использую маленький margin-top для отдельных подзаголовков в определенных ситуациях. Но я делаю это намеренно, а не просто позволяю стилям браузера вести себя непредсказуемым образом.





















































