- PVSM.RU - https://www.pvsm.ru -
Все верстальщики в своих проектах используют div.container для центрирования контента и этот способ имеет некоторые особенности, от которых можно избавиться. Прочитав эту статью, Вы узнаете про способ, который позволит полностью отказаться от контейнера. Я попытаюсь рассказать о плюсах и минусах использования контейнера и альтернативного способа центрирования контента средствами только лишь css.
P.S. Надеюсь качество GIF'ок позволяет что-то разглядеть.
Навигация:
CSS:
.container {
max-width: 1170px;
margin: auto;
height: 1000px;
}
Изображение выше и код наглядно показывают как работает стандартный контейнер в типовой вёрстке сайта. Наверное все знают, что обычно создается тег section, в него помещается div.container и уже в него помещают различный контент. Он занимает всю ширину экрана, например, до 1170px и когда экран становится больше, то играет роль обёртки и фиксирует контент в центре страницы, не давая ему «разбежаться» в стороны.
Так почему бы сразу не задать эти стили для контента? Если задать эти стили для секции без контейнера, то вроде бы всё смотрится нормально.
HTML:
<section class="main-section">
<h1 class="main-title">Заголовок страницы</h1>
<p class="main-subtitle">Lorem ipsum dolor.</p>
<div class="cards">
...
</div>
</section>
Но как только требуется задать фон для секции, ситуация сразу выходит из под контроля:
Если задать для секции фон, внутрь секции положить контейнер с его стилями, а в него уже контент, то всё заработает так, как надо:
HTML:
<section class="main-section">
<div class="container">
<h1 class="main-title">Заголовок страницы</h1>
<p class="main-subtitle">Lorem ipsum dolor.</p>
<div class="cards">
...
</div>
</div>
</section>
Самый очевидный минус контейнера — создание лишних блоков в разметке, которое ведет к увеличению цепочки вложенностей элементов и понижению читаемости кода.
Также создание контейнера может вызвать сложности в названиях классов (иногда нужно придумать дополнительный класс для обёртки внутри контейнера). Это всё просто увеличивает код.
Выше мы рассмотрели самый простой пример. Но если на сайте 15 секций или больше? Это 15 лишних блоков. А если нам внутри контейнера нужно разделить секцию еще на две части и сделать их flex-элементами? Нужно создать div-обёртку, это еще по одному блоку в контейнер. И уже +2 лишних блока на секцию! Как я уже сказал выше — эти div'ные вложенности «мусорят» в разметке. Но возможности css позволяют нам обойтись и без них.
Я не так давно в веб-разработке, но уже нашел способ адекватно работать с контейнером и в итоге вообще избавился от него. Я так понимаю .container «родился» в bootstrap [9] и теперь его используют абсолютно везде.
Взяв за основу сетку bootstrap [10] можно значительно упростить себе работу с css медиа-запросами, используя следующий код:
CSS:
.container {
padding: 0 15px;
}
@media (min-width: 575.98px){
.container {
max-width: 540px;
margin: auto;
padding: 0;
}
}
@media (min-width: 767.98px){
.container {
max-width: 720px;
}
}
@media (min-width: 991.98px) {
.container {
max-width: 960px;
}
}
@media (min-width: 1199.98px){
.container {
max-width: 1140px;
}
}
Что он делает? Если кратко, то держит контент всегда в центре и меняет его размеры на разных экранах:
Такая система сетки даёт явные преимущества:
Использовать такую настройку медиа-запросов с контейнером очень удобно. Если еще не используете, то попробуйте и вы обязательно согласитесь. В конце концов в Twitter же не дураки сидят, не просто так придумали именно такую сетку размеров экрана.
На рисунке ниже изображена работа .container в связке с медиа-запросами, которые я подсмотрел у bootstrap.
Наконец-то мы подошли к самому интересному. Так как же заменить .container? Для начала разберемся что нам нужно сделать. Нам нужно две вещи:
Что может отодвинуть контент в центр секции и при этом фон останется везде внутри? Ответ оказался прост: задаём для секции внутренние отступы — padding. Но padding не простой. Но для примера давайте сначала попробуем задать простой padding.
Допустим нам нужна ширина контента 1180px, значит 1920 — 1180 = 740 / 2 = 370px — будут боковые отступы в нашей секции. Смотрим:
HTML:
<section>
<div class="content">
content
</div>
</section>
CSS:
section {
background-color: pink;
height: 1000px;
padding: 0 370px;
}
Да уж. При уменьшении экрана, наши отступы сжимают контент. Не годится. Может возможно сделать отступы динамическими? Возможно! И ресурсами одного лишь css!
Для этого воспользуемся функцией calc() [11]. На данный момент css-функция calc() поддерживается на 96.5% [12], что всего на 1% меньше, чем flexbox, а это значит, что её можно смело использовать. Для динамических внутренних отступов нужно выполнить одну математическую операцию.
Давайте уже скорее посмотрим на пример:
Мне нравится! Без всяких дополнительных блоков наша секция ведёт себя ровно так же, как с .container. С уменьшением экрана уменьшаются padding, а контент остается фиксированным по ширине. И это всего лишь одно css-свойство:
CSS:
section {
padding: 0 calc(50% - 590px);
}
UPD: Упросил формулу. Спасибо Metotron0 [13].
Таким образом мы задаём боковые внутренние отступы с помощью функции calc(), которая при любом разрешении экрана высчитывает эти отступы так, чтобы контент был 1180px! Вы только попробуйте.
Можно поиграться с корректирующим значением 590px и сделать контент 1140px или 1170px, как угодно!
Посмотрите сравнение [6] этого метода с контейнером прямо сейчас!
Было бы очень хорошо встроить это в сетку от bootstrap, чтобы легче было адаптировать сайт.
Давайте попробуем:
CSS:
section{
padding: 0 15px;
}
@media (min-width: 575.98px){
section {
padding: 0 calc(50% + 270px);
}
}
@media (min-width: 767.98px){
section {
padding: 0 calc(50% + 360px);
}
}
@media (min-width: 991.98px) {
section {
padding: 0 calc(50% + 480px);
}
}
@media (min-width: 1199.98px){
section {
padding: 0 calc(50% + 590px);
}
}
Результат:
Итого на разных размерах экранов мы имеем:
Это же абсолютно тоже самое, что и с div.container! Только без лишних блоков.
Всё еще не видите пользы от метода с динамическими отступами? Тогда давайте взглянем на пример из реальной практики. Надевайте очки разработчика — есть следующая секция (кликабельно):
Какие мысли? Есть секция, в ней два отдельных блока, чтобы разбросать их по сторонам, хорошо бы задать для секции display: flex и jcsb. Но если использовать .container, то придётся оборачивать два этих блока в ещё один и ему уже задавать df. Разве это удобно? Пробуем:
HTML:
<section class="brif-section">
<div class="container">
<div class="brif-wrapper">
<div class="brif-text-block">
....
</div>
<form action="#" class="brif-form">
....
</form>
</div>
</div>
</section>
CSS:
.brif-section {
background: background;
}
.container {
max-width: 1180px;
margin: auto;
}
.brif-wrapper {
display: flex;
justify-content: space-between;
}
А теперь посмотрите как это выглядит если использовать динамические отступы:
HTML:
<section class="brif-section">
<div class="brif-text-block">
....
</div>
<form action="#" class="brif-form">
....
</form>
</section>
CSS:
.brif-section {
display: flex;
justify-content: space-between;
padding: 0 calc(50% + 590px);
background: background;
}
Только посмотрите как уменьшился код, он стал чище, читать его стало легче. Получилась секция, которая содержит блок с текстом и форму — ничего лишнего! И это всего лишь одна секция. Повторюсь: а если на сайте 15 секций?
Итак, начинаем подводить итоги:
Плюсы .container:,
Минусы .container:
Плюсы padding (относительно .container):
Минусы padding:
То есть не:
section {
padding: 50px 0;
}
А вот так:
section {
padding-top: 50px;
padding-bottom: 50px;
}
Иначе они перезапишут динамические отступы.
Мне нравится метод с динамическими внутренними отступами. Попробуйте его вместо привычной «контейнерной» вёрстки и вы быстро заметите как повысилась чистота вашего кода. Если есть какие-то сомнения в этом методе, то пишите их в комментарии — обсудим!
Рекомендую использовать не %, а vw. Чтобы ширина считалась не от родителя, а от ширины области промотора браузера. Так просто надёжнее. Поддержка vw — 96% тут [15].
CSS:
section {
padding: 0 calc(50vw + 590px);
}
Создайте свой шаблон этих стилей с медиа-запросами, например:
section, header, footer {
padding: 0 15px;
}
@media (min-width: 575.98px){
section, header, footer {
padding: 0 calc(50vw + 270px);
}
}
@media (min-width: 767.98px){
section, header, footer {
padding: 0 calc(50vw + 360px);
}
}
@media (min-width: 991.98px) {
section, header, footer {
padding: 0 calc(50vw + 480px);
}
}
@media (min-width: 1199.98px){
section, header, footer {
padding: 0 calc(50vw + 590px);
}
}
Метод с динамическими отступами выполняет ту же функцию, что и div.container, но полностью лишён всех его недостатков. Возможно этот метод имеет какие-то подводные камни, но я пока их не встретил. Пока всё работает абсолютно так же, как с контейнером.
Не бойтесь чего-то нового. Просто начните применять этот метод и в скором времени вы почувствуете некоторое облегчение. Используйте css на полную катушку!
P.S. Если во время использования этого метода всплывут какие-то подводные камни — опишите их в комментариях! Будем разбираться.
Автор: Alexander Kurnosov
Источник [16]
Сайт-источник PVSM.RU: https://www.pvsm.ru
Путь до страницы источника: https://www.pvsm.ru/html/327313
Ссылки в тексте:
[1] Немного о стандартном .container: #1
[2] Минусы .container: #2
[3] Работа с .container и медиа-запросами: #3
[4] Замена .container одним css-свойством: #4
[5] Комбинация с медиа-запросами: #5
[6] Пример из реальной практики, сравнение методов: #6
[7] Рекомендации: #7
[8] Заключение: #8
[9] bootstrap: https://getbootstrap.com/
[10] сетку bootstrap: https://getbootstrap.com/docs/4.3/layout/grid/#grid-options
[11] calc(): https://webref.ru/css/value/calc
[12] поддерживается на 96.5%: https://caniuse.com/#feat=calc
[13] Metotron0: https://habr.com/ru/users/metotron0/
[14] Image: https://habrastorage.org/webt/--/bo/ue/--boueuz463zmnpyrntlxgpuom0.jpeg
[15] тут: https://caniuse.com/#feat=viewport-units
[16] Источник: https://habr.com/ru/post/463923/?utm_source=habrahabr&utm_medium=rss&utm_campaign=463923
Нажмите здесь для печати.