От автора: о том, как смежный селектор решает сложные требования к дизайну, сохраняя CSS-код в читаемом виде. Это одна из тех задач в веб-разработке, которые начинаются просто, но в процессе становятся сложнее: как внутри статьи, например, поста в блоге использовать вертикальные отступы CSS margin’ы на элементах, когда сама статья состоит из сложной markdown-разметки.
По большей части вам придется работать с исключениями и зависимостями. Между заголовком и изображением должен быть большой отступ, однако между двумя идущими подряд изображениями отступ должен быть небольшим. Отступ между h2 и h3 должен быть больше, чем между h2 и параграфом. И т.д.
Пару лет назад в начале моей карьеры в качестве веб-разработчика все эти исключения и зависимости запутывали код, делали его визуально непоследовательным, что приводило к неожиданному поведению. Я реально гуглил ни один раз «почему не работает margin-top».
Ниже я опишу технику, которой я придерживаюсь уже на протяжении долгого времени. Техника позволяет избежать схлопывания margin’ов, обеспечивает хорошую читаемость и позволяет создавать сложные зависимости.
Шаг 1
Простая статья выглядит следующим образом:
1 2 3 4 5 6 7 8 9 10 11 12 |
<article class="article"> <h1>Hello World</h1> <p>Lorem ipsum dolor sit amet</p> <p>Lorem ipsum dolor sit amet</p> <img src="…" alt="…"> <p>Lorem ipsum dolor sit amet</p> <ul> <li>Lorem</li> <li>Ipsum</li> <li>Dolor</li> </ul> </article> |
Обычно я беру два параграфа и настраиваю между ними вертикальный margin так, чтобы это смотрелось красиво. Затем я использую это значение в качестве базового для всех элементов.
1 2 3 |
.article > * + * { margin-top: 1.5rem; } |
Это правило добавляет margin-top ко всем прямым дочерним элементам в .article, у которых есть смежный тег. Применяя margin-top только к прямым дочерним элементам, я избегаю определенного нежелательного поведения. Например, ul в коде выше получит margin-top, а его li уже нет.
В CodePen демо ниже показан пример:
Шаг 2
На втором этапе я добавляю больше определенных правил, например:
1 2 3 |
.article > img + * { margin-top: 3rem; } |
Все элементы после img получают margin-top. Принцип схож с применением margin-bottom к img напрямую. Однако у смежного селектора и margin-top есть два преимущества: не нужно удалять margin-bottom с :last-child и избегать схлопывания margin’ов.
В CodePen ниже показан расширенный пример:
Шаг 3
На этом этапе я добавляют правила к определенным элементам, например:
1 2 3 4 5 6 |
.article > * + h2 { margin-top: 4rem; } .article > * + img { margin-top: 3rem; } |
Если у h2 есть смежный тег, он получит margin-top. То же самое будет с изображением.
Пример CodePen:
Шаг 4
На последнем этапе я работаю с определенными зависимостями:
1 2 3 |
.article > img + img { margin-top: 1rem; } |
Если после изображения следует другое изображение, то отступ между ними должен быть очень маленьким.
Пример CodePen:
Если хочется, можно сделать еще более специфичный код. Например:
1 2 3 |
.article > img + img + img + h2 { margin-top: 5rem; } |
Если перед h2 идет три изображения подряд, то заголовок получит margin-top. К счастью, это крайний случай. Однако полезно знать, что смежный селектор может решать такие сложные зависимости.
Продвинутое использование
Чтобы улучшить читаемость, я использую (SCSS) вложенность и пишу каждое правило на одной строке. Также я не группирую селекторы с одинаковым значением, так как CSSO сам позаботится об этом в задаче по сборке.
1 2 3 4 5 6 7 8 9 10 |
.article { > * + * { margin-top: 1.5rem } > h2 + * { margin-top: 1rem } > img + * { margin-top: 3rem } > * + h2 { margin-top: 4rem } > * + h3 { margin-top: 3.5rem } > * + img { margin-top: 3rem } > img + img { margin-top: 1rem } > h2 + h3 { margin-top: 4.5rem } } |
Эта техника хорошо работает с SASS и CSS-переменными, например, для создания базовых сеток. Если все margin’ы вычисляются из одной базовой переменной, то для увеличения или уменьшения отступов нужно всего лишь изменить эту переменную.
CodePen пример на CSS-переменных:
Заключение
Обычно на разработанных в нашем агентстве сайтах очень сложные статьи. В них присутствует не только сложная markdown-разметка, но и заголовки категорий, вступительный текст и вложенные макеты.
Смежный селектор и margin-top позволяют мне решать сложные требования к дизайну, сохраняя читаемость CSS-правил. Особенно если мне позже понадобится добавить или изменить правила.
Автор: Sebastian Eberlein
Источник: //hackernoon.com/
Редакция: Команда webformyself.