От автора: после неожиданных пустых мест на странице, возможно, самая распространенная проблема в макетах – это перекрытие контента. К счастью, причин, вызывающих такое поведение, очень мало, и есть хорошие способы решения таких проблем.
Причина перекрытия №1: контейнер с заданной высотой
Самая распространенная проблема среди моих учеников заключается в том, что они задают явную высоту контейнера. К примеру:
1 2 3 4 |
<aside> <p>Now, cryin wont help you, prayin wont do you no good,<br> When the levee breaks, mama, you got to move. </aside> |
И CSS:
1 2 3 4 5 |
aside { display: inline-block; border: 1px dotted #000; height: 10px; } |
После чего мы получим:
Рисунок 1: контент вылезает за пределы контейнера из-за явно указанной высоты
Причина этой проблемы очень проста: по умолчанию контейнеры автоматически подстраиваются под высоту контента. Установив явную высоту, вы нарушаете это правило. Еще одно правило состоит в том, что по умолчанию браузеры всегда показывают контент, перекрывающий контейнер. Вот почему вы получили, что получили на рисунке 1.
Как исправить:
Существует несколько возможных решений:
удалить высоту контейнера из стилей и позволить элементу самому подбирать высоту под контент;
удалить рамку (или фон) у элемента: нет рамок — не видно перекрытия!*
Свойство overflow: scroll-y почти никогда не помогает: окно с прокруткой внутри другого окна с прокруткой (браузера) – прямой путь к путанице и разочарованию.
Причина перекрытия №2: слишком широкое изображение
Изображение, помещенное на странице, будет отображаться со своей естественной шириной: у растровых изображений это количество пикселей по горизонтали. У SVG изображений это значение заданных атрибутов height и width. Это правило вызывает перекрытие, если контейнер слишком мал для изображения, как показано на рисунке 2.
Рисунок 2: изображение перекрывает контейнер по горизонтали
Решение
Решение почти всегда одно и то же: необходимо задать ширину изображения в процентах через CSS:
1 |
img { width: 100%; } |
Так изображение всегда будет вписываться в рамки родительского элемента.
Более подробно об этой технике можно почитать в моих статьях о жидких и SVG изображениях. Также вам нужно прочесть про тег picture и атрибут srcset для адаптивных растровых изображений.
Причина перекрытия №3: контейнер с шириной в процентах
Проблема, с которой мы все чаще сталкиваемся в эпоху адаптивного веб-дизайна: контейнеру с текстом задана ширина в процентах:
1 2 3 |
aside { width: 20%; } |
Рисунок 3: текст, вылезающий за пределы контейнера по горизонтали
Этот элемент будет сужаться вместе с окном браузера. Если ничего не делать, в конечном итоге длинные слова начнут вылезать по горизонтали за пределы контейнера, как показано на рисунке 3.
(Для изображений в этом случае подойдет способ решения из второй причины)
Решения
Существует три возможных решения:
Присвойте родительскому блоку свойство min-width, задав таким образом нижний порог ширины окна браузера. Однако обычно это решает только полпроблемы.
Пропишите переносы слов в @media запросах. Это решает только проблему с длинными текстами. Лучше всего перейти к пункту 3.
Измените макет на вертикальный дизайн. Лично мне нравится для этого использовать flexbox.
Причина перекрытия №4: не используется Border-Box
Ширина по умолчанию в CSS – это не то, что представляет себе большинство людей: общая ширина складывается из ширины контента и padding’ов, что зачастую вызывает проблемы с перекрытием.
Решение
Пропишите для всех или почти всех элементов свойство box-sizing: border-box по умолчанию. Очень важно сделать это в начале разработки сайта. Иначе вы будете строить и измерять элементы на основе неправильных представлений, что в итоге заставит вас переделывать все элементы.
Причина перекрытия №5: элементы с обтеканием
Элементы с обтеканием не входят в расчет общей высоты контейнера. Разберем следующий пример:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 |
<div id="levee"> <img src="chicago.jpg" alt="A photograph of the waterfront of Chicago"> <p>Thinkin bout me baby and my happy home<br> Going, gon to chicago,<br> Gon to chicago,<br> Sorry but I cant take you.<br> Going down, going down now, going down. <p>Photograph by <a href="//www.flickr.com/photos/snake_bill/13812951923/"> Yulin Lu</a>, used under a Creative Coommons Attribution-NonCommercial-NoDerivs 2.0 Generic license. </div> |
И CSS:
1 2 3 4 5 6 7 8 |
#levee { border: 2px solid #333; } #levee img { float: left; width: 50%; margin: 2rem; } |
В итоге мы получим то, что на рисунке 4:
Рисунок 4: контент с обтеканием перекрывает контейнер
Решение
Существует множество решений типа «clear floats» и «clearfix». Самый простой и эффективный, но нелогичный способ – использовать overflow: hidden на родительском элементе. На практике свойство делает совсем не то, чего вы ожидаете:
1 2 3 4 |
#levee { border: 2px solid #333; overflow: hidden; } |
Проблема полностью устраняется.
*Конечно, если рамка является неотъемлемой частью дизайна, такой вариант не подходит. Однако удивительно, как часто люди говорят, что это лучший выход, когда отсутствует рамка или фон (следовательно, перекрытие не видно).
Источник: //thenewcode.com/
Редакция: Команда webformyself.