Просунуті вертикальні відступи CSS — магдіпи

313

Від автора: про те, як суміжний селектор вирішує складні вимоги до дизайну, зберігаючи CSS-код в читаному вигляді. Це одна з тих завдань в веб-розробці, які починаються просто, але в процесі стають складніше: як всередині статті, наприклад, поста в блозі використовувати вертикальні відступи CSS магдіп’и на елементах, коли сама стаття складається з складної markdown-розмітки.

Здебільшого вам доведеться працювати з винятками і залежностями. Між заголовком і зображенням повинен бути великий відступ, однак між двома йдуть підряд зображеннями відступ повинен бути невеликим. Відступ між h2 і h3 повинен бути більше, ніж між h2 і параграфом. І т. д.

Пару років тому на початку моєї кар’єри в якості веб-розробника всі ці винятки і залежно заплутували код, робили його візуально непослідовним, що призводило до несподіваного поведінки. Я реально гугл не один раз «чому не працює margin-top».

Нижче я опишу техніку, якої я дотримуюся вже на протязі довгого часу. Техніка дозволяє уникнути схлопування магдіп’ов, забезпечує хорошу читаність і дозволяє створювати складні залежності.

Крок 1

Проста стаття виглядає наступним чином:

Hello World

Lorem ipsum dolor sit amet

Lorem ipsum dolor sit amet

Просунуті вертикальні відступи CSS — магдіпи

Lorem ipsum dolor sit amet

  • Lorem
  • Ipsum
  • Dolor

Зазвичай я беру два параграфа і налаштовую між ними вертикальний margin так, щоб це виглядало красиво. Потім я використовую це значення в якості базового для всіх елементів.

.article > * + * {
margin-top: 1.5 rem;
}

Це правило додає margin-top до всіх прямим дочірнім елементів .article, у яких є суміжний тег. Застосовуючи margin-top тільки до прямих дочірнім елементам, я уникаю певного небажаного поведінки. Наприклад, ul у коді вище отримає margin-top, а його li вже немає.

У CodePen демо нижче показаний приклад:

Крок 2

На другому етапі я додаю більше певних правил, наприклад:

.article > img + * {
margin-top: 3rem;
}

Всі елементи після img отримують margin-top. Принцип схожий з застосуванням margin-bottom до img безпосередньо. Однак у суміжного селектора і margin-top є дві переваги: не потрібно видаляти margin-bottom :last-child і уникати схлопування магдіп’ов.

У CodePen нижче показаний розширений приклад:

Крок 3

На цьому етапі я додають правила до певних елементів, наприклад:

.article > * + h2 {
margin-top: 4rem;
}
.article > * + img {
margin-top: 3rem;
}

Якщо у h2 є суміжний тег, він отримає margin-top. Те ж саме буде з зображенням.

Приклад CodePen:

Крок 4

На останньому етапі я працюю з певними залежностями:

.article > img + img {
margin-top: 1rem;
}

Якщо після зображення випливає інше зображення, то інтервал між ними повинен бути дуже маленьким.

Приклад CodePen:

Якщо хочеться, можна зробити ще більш специфічний код. Наприклад:

.article > img + img + img + h2 {
margin-top: 5rem;
}

Якщо перед h2 йде три зображення поспіль, то заголовок отримає margin-top. На щастя, це крайній випадок. Однак корисно знати, що суміжний селектор може вирішувати такі складні залежності.

Сучасне використання

Щоб поліпшити читаність, я використовую (SCSS) вкладеність і пишу кожне правило на одному рядку. Також я не групую селектори з однаковим значенням, так як CSSO сам подбає про це в задачі по збірці.

.article {
> * + * { margin-top: 1.5 rem }
> h2 + * { margin-top: 1rem }
> img + * { margin-top: 3rem }
> * + h2 { margin-top: 4rem }
> * + h3 { margin-top: 3.5 rem }
> * + img { margin-top: 3rem }
> img + img { margin-top: 1rem }
> h2 + h3 { margin-top: 4.5 rem }
}

Ця техніка добре працює з SASS і CSS-змінними, наприклад, для створення базових сіток. Якщо все магдіп’и обчислюються з однієї базової змінної, то для збільшення або зменшення відступів потрібно всього лише змінити цю змінну.

CodePen приклад на CSS-змінних:

Висновок

Зазвичай на розроблених в нашому агентстві сайтах дуже складні статті. У них присутня не тільки складна markdown-розмітка, але і заголовки категорій, вступний текст і вкладені макети.

Суміжний селектор і margin-top дозволяють мені вирішувати складні вимоги до дизайну, зберігаючи читаність CSS-правил. Особливо якщо мені знадобиться пізніше додати або змінити правила.