Прорив дамби: вирішення проблем з перекриттям вмісту

7

Від автора: після несподіваних порожніх місць на сторінці, можливо, найпоширеніша проблема в макетах – це перекриття контенту. На щастя, причин, що викликають таку поведінку, дуже мало, і є хороші способи вирішення таких проблем.

Причина перекриття №1: контейнер із заданою висотою

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

Now, cryin wont help you, prayin wont do you no good,
When the levee breaks, mama, you got to move.

І CSS:

aside {
display: inline-block;
border: 1px dotted #000;
height: 10px;
}

Після чого ми отримаємо:

Прорыв дамбы: решения проблем с перекрытием контента

Малюнок 1: контент вилазить за межі контейнера з-за явно зазначеної висоти

Причина цієї проблеми дуже проста: за замовчуванням контейнери автоматично підлаштовуються під висоту контенту. Встановивши явну висоту, ви порушили це правило. Ще одне правило полягає в тому, що за замовчуванням браузери завжди показують контент, який перекриває контейнер. Ось чому ви отримали те, що отримали на малюнку 1.

Як виправити:

Існує кілька можливих рішень:

видалити висоту контейнера із стилів і дозволити елементу самому підбирати висоту під контент;

видалити рамку або фон) у елемента: немає рамок — не видно перекриття!*

Властивість overflow: scroll-y майже ніколи не допомагає: вікно з прокруткою всередині іншого вікна з прокруткою (браузера) – прямий шлях до плутанини і розчарування.

Причина перекриття №2: занадто широке зображення

Зображення поміщене на сторінці, буде відображатися зі своєї природної шириною: у растрових зображень це кількість пікселів по горизонталі. У SVG-зображень це значення заданих атрибутів height і width. Це правило викликає перекриття, якщо контейнер занадто малий для зображення, як показано на малюнку 2.

Прорыв дамбы: решения проблем с перекрытием контента

Малюнок 2: зображення перекриває контейнер по горизонталі

Рішення

Рішення майже завжди одне і те ж: необхідно задати ширину зображення у відсотках через CSS:

img { width: 100%; }

Так зображення завжди буде вписуватися в рамки батьківського елемента.

Більш докладно про цю техніку можна почитати в моїх статтях про рідких і SVG зображеннях. Також вам потрібно прочитати про тег picture і атрибут srcset для адаптивних растрових зображень.

Причина перекриття №3: контейнер з шириною у відсотках

Проблема, з якою ми все частіше стикаємося в епоху адаптивного веб-дизайну: контейнеру з текстом задана ширина у відсотках:

aside {
width: 20%;
}

Прорыв дамбы: решения проблем с перекрытием контента

Малюнок 3: текст, який транслюється за межі контейнера по горизонталі

Цей елемент буде звужуватися разом з вікном браузера. Якщо нічого не робити, в кінцевому підсумку довгі слова почнуть вилазити по горизонталі за межі контейнера, як показано на малюнку 3.

(Для зображень в цьому випадку підійде спосіб вирішення з другої причини)

Рішення

Існує три можливих рішення:

Назвіть батьківського блоку властивість min-width, задавши таким чином нижній поріг ширини вікна браузера. Проте зазвичай це вирішує тільки полпроблемы.

Пропишіть переноси слів у @media запитах. Це вирішує тільки проблему з довгими текстами. Краще всього перейти до пункту 3.

Змінити макет на вертикальний дизайн. Особисто мені подобається для цього використовувати flexbox.

Причина перекриття №4: не використовується Border-Box

Ширина за замовчуванням в CSS – це не те, що уявляє собі більшість людей: загальна ширина складається з ширини контенту і padding’ов, що часто викликає проблеми з перекриттям.

Рішення

Пропишіть для всіх або майже всіх елементів властивість box-sizing: border-box за замовчуванням. Дуже важливо зробити це до початку розробки сайту. Інакше ви будете будувати і вимірювати елементи на основі неправильних уявлень, що в підсумку змусить вас переробляти всі елементи.

Причина перекриття №5: елементи з обтіканням

Елементи з обтіканням не входять у розрахунок загальної висоти контейнера. Розглянемо наступний приклад:

A photograph of the waterfront
of Chicago

Thinkin bout me and my baby happy home
Going, gon to chicago,
Gon to chicago,
Sorry but I can’t take you.
Going down, going down now, going down.

Photograph by
Yulin Lu, used under a Creative Coommons
Attribution-NonCommercial-NoDerivs 2.0 Generic license.

І CSS:

#levee {
border: 2px solid #333;
}
#levee img {
float: left;
width: 50%;
margin: 2rem;
}

В результаті ми отримаємо те, що на малюнку 4:

Прорыв дамбы: решения проблем с перекрытием контента

Малюнок 4: контент з обтіканням перекриває контейнер

Рішення

Існує безліч рішень типу «clear floats» і «clearfix». Самий простий і ефективний, але нелогічний спосіб – використовувати overflow: hidden на батьківському елементі. На практиці властивість робить зовсім не те, чого ви очікуєте:

#levee {
border: 2px solid #333;
overflow: hidden;
}

Проблема повністю усувається.

*Звичайно, якщо рамка є невід’ємною частиною дизайну, такий варіант не підходить. Однак дивно, як часто люди кажуть, що це найкращий вихід, коли відсутня рамка або фон (отже, перекриття не видно).