Лучший способ реализовать «обёртки» в CSS
Иногда первое, что мы пишем на странице — это элемент, оборачивающий всё остальное на странице. Термин «Обёртка» типичен для этого. Мы задаём ему класс, отвечающий за инкапсуляцию всех визуальных элементов на странице.
Я всегда боролся за то, чтобы найти лучший способ реализовать его. Я нашёл соответствующую тему на StackOverflow с более чем 250000 просмотров, что говорит о её огромной популярности. В этой статье я подытожу свои мысли.
Перед тем, как пойти дальше, сначала рассмотрим разницу между «обёрткой» (wrapper) и «контейнером» (container).
«Обёртка» против «Контейнера»
Я вижу разницу между элементом-обёрткой и элементом-контейнером.
В языках программирования слово «контейнер» обычно используется для структуры, содержащей более одного элемента. «Обёртка» же — это нечто, что оборачивается вокруг одного объекта, чтобы предоставить интерфейс к нему и расширить его функциональность.
Так что, мне кажется, есть смысл оставить два названия, поскольку они предполагают разные функции.
Обёртка ассоциируется с , который содержит весь остальной HTML в документе. Уверен, что многие помнят то время, когда мы устанавливали для ширину 960px и центрировали основной контент. Обёртки так же были полезны, чтобы прижать футер.
Контейнер, напротив, обычно предполагает другой вид содержимого. То, которое иногда необходимо для реализации поведения или оформления множественных компонентов. Он служит задаче группировки семантических и визуальных элементов. Например, у бутстрапа есть «классы контейнера», которые содержат их систему сеток или другие различные компоненты.
Термины «Обёртка» и «Контейнер» также могут означать одно и то же в зависимости от разработчика и его целей. Могут быть и другие соглашения, так что лучший совет, как правило — делать так, как вам самим логичнее. Но помните, что наименование — одна из наиглавнейших фундаментальных вещей в практике разработчика. Система наименования делает код читабельнее и предсказуемее. Выбирайте тщательнее!
Вот пример общей обёртки страницы:
/** * 1. Центрируем содержимое. Да, это немножко вкусовщина. * 2. См. раздел «width против max-width» * 3. См. раздел «Дополнительные внутренние отступы» */ .wrapper < margin-right: auto; /* 1 */ margin-left: auto; /* 1 */ max-width: 960px; /* 2 */ padding-right: 10px; /* 3 */ padding-left: 10px; /* 3 */ >
width против max-width
После установки ширины блочному элементу он больше не сможет растягиваться на всю ширину своего контейнера (полезно для комфортной длины строк). Следовательно, элемент-обёртка займёт указанную ширину. Но если окно браузера Уже указанной ширины обёртки, то появится нежелательный горизонтальный скролл.
Поэтому для окон поуже лучше использовать max-width . Это важно при оптимизации сайтов под мобильные устройства с маленьким экраном. Вот неплохой пример, который демонстрирует эту проблему.
С точки зрения отзывчивости max-width лучший выбор!
Дополнительные внутренние отступы
Я видел, как многие разработчики забывали один граничный случай. Допустим, есть обёртка с max-width: 980px. Этот граничный случай проявляется при экране устройства 980px. Поэтому, её содержимое прилипнет точно к краям экрана, не оставляя «воздуха».
Эта проблема нехватки «воздуха»
Обычно нам нужны отступы по краям. Вот почему, когда мне нужна обёртка шириной 980px, я делаю так:
.wrapper < max-width: 960px; /* на 20px меньше, чтобы уместить отступы по краям. */ padding-right: 10px; padding-left: 10px; /* . */ >
Вот почему добавление padding-left и padding-right к обёртке будет хорошей идеей, особенно на мобильных устройствах.
Или подумайте о box-sizing, чтобы отступы вообще не влияли на общую ширину.
Какой HTML-элемент выбрать
У обёртки нет семантики. В ней просто находятся все визуальные элементы и контент на странице. Он всего лишь просто контейнер. С точки зрения семантики, — лучший выбор. У тоже нет семантического значения, это просто контейнер
Невольно возникает вопрос, а может ли для этой цели подойти элемент . Однако, спецификация W3C говорит вот что:
Элемент не замена общему элементу-контейнеру. Если элемент нужен чисто для оформительских целей или как вспомогательное средство для скриптов, то рекомендуется использовать . Общее правило таково: элемент раздела подходит в случае, когда содержимое элемента явно указано в схеме документа.
Элемент несёт в себе собственную семантику. Он подходит для тематической группировки контента. В каждом разделе должен быть заголовок (элемент h1-h6) в качестве дочернего элемента (прим. перев.: это не строгое правило, но крайне желательно соблюдать его).
Примерами разделов могут служить главы, различные вкладки в диалоговом окне или пронумерованные разделы диссертации. Домашнюю страницу можно разбить на разделы для введения, новостей и контактной информации.
Сходу это может показаться неочевидным. Но да, старый добрый лучше всего подходит для обёртки!
Тег против дополнительного
Следует отметить, что в качестве обёртки иногда может подойти . Вот такая реализация отлично работает:
body
И в результате у вас в разметке будет одним элементом меньше, поскольку удалён ненужный обёрточный .
Однако, лучше этого не делать ради гибкости и устойчивости к изменениям. Представьте любой из этих сценариев на поздней стадии проекта:
- Вам нужно «прибить» футер к концу документа (к низу окна, если документ короткий). И если даже воспользоваться flexbox в качестве современного способа, всё равно не обойтись без обёрточного (прим. перев.: на самом деле можно задать display: flex самому body , тем более в примере по ссылке так и сделано).
- Вам требуется установить background-color целой странице. Поскольку у body есть max-width , то его нельзя использовать. Но тогда можно установить фон тегу . Но тут я сомневаюсь. После прочтения статьи HTML vs Body in CSS это звучит для меня немного необычно. Однако, я не слышал каких-то проблем или трудностей с применением цвета фона для элемента . Но это по-прежнему звучит немного странно, да? (Прим. перев.: проблема с фоновым цветом преувеличена, поскольку по стандарту CSS любой фон, указанный для , и так применяется ко всему , если тому явно не задан собственный фон. Но могут быть другие проблемы, например, со сторонними скриптами, позиционирующими всплывающие окна и т.п. именно относительно )
Лично я склоняюсь к тому, что для реализации обёртки всё же лучше использовать дополнительный . Таким образом, если требования спецификации позже изменятся, то потом не придётся добавлять обёртку и переписывать стили. В конце концов, речь же об одном-единственном добавочном DOM-элементе.
P.S. Это тоже может быть интересно:
- Псевдокласс :has() — не только «родительский селектор»
- Тёмная сторона CSS: выходим за рамки и взрываем звезды с border-image и градиентами
- CSS-выражения от контейнера для дизайнеров
Если вам понравилась статья, поделитесь ей!
Для чего теги «оборачивают» Wrapper’ом?
Для чего теги «оборачивают» Wrapper’ом и почему у Wrappera часто ставят position:relative ? Что вообще дает использование wrapper’а?
Отслеживать
51.4k 87 87 золотых знаков 267 267 серебряных знаков 508 508 бронзовых знаков
задан 17 апр 2016 в 18:36
41 1 1 золотой знак 1 1 серебряный знак 4 4 бронзовых знака
В текущем виде на ваш вопрос невозможно дать лаконичный ответ. Для получения ответа поясните, в чем именно вы видите проблему, какие технологии используете и что хотите видеть в ответе.
17 апр 2016 в 18:41
@Grundy, видимо, идентификатор #wrapper имеется в виду, и участник не знает, что можно задавать любые значения атрибутом id и class , а wrapper приводится только для примера. Berty, для чего wrapper , например, как в этом примере Вы хотели узнать? Спасибо.
17 апр 2016 в 18:59
@Саша Черных,я тут первый раз,так что,извиняюсь за неточную формулировку)Да,я бы хотел узнать.
17 апр 2016 в 19:29
Когда понадобится, сам поймёшь.
27 фев 2018 в 22:39
4 ответа 4
Сортировка: Сброс на вариант по умолчанию
Это может быть связано с position:absolute для вложенного элемента. Дело в том, что без обёртки с position:relative координаты такого элемента будут отсчитываться относительно всего документа, а с обёрткой — относительно обёрточного элемента.
Отслеживать
ответ дан 17 апр 2016 в 18:58
6,904 2 2 золотых знака 27 27 серебряных знаков 57 57 бронзовых знаков
Это всего лишь контейнер для удобства, заключая блоки в обертку проще центрировать, задавать общую ширину. и т.д. Релейтив ставят если собираются абсолютно позиционировать внутренние блоки.
Отслеживать
ответ дан 17 апр 2016 в 19:36
1,087 3 3 золотых знака 15 15 серебряных знаков 41 41 бронзовый знак
В целом, wrapper используют для удобства позиционирования. Самому wrapper , присваивают минимум свойств.
А иногда вообще оставляют его без них. Почему просто не оставлять див без класса? Во первых, противоречит некоторым методологиям (например БЭМ). Во вторых, слово «wrapper» переводится как «обертка» и дает понять, тем кто будет работать с кодом после вас, зачем этот div нужен (при беглом просмотре). Также, он может послужить прослойкой для функционирования различных скриптов.
Класс wrapper в html зачем он нужен?
Я не могу понять зачем в процессе верстки все оборачивать в div с классом «wrapper» в html.
Ну вот зачем? Сложно все назначить на body?
- Вопрос задан более трёх лет назад
- 23631 просмотр
1 комментарий
Простой 1 комментарий
WapSter @wapster92 Куратор тега Вёрстка
Ну если тебе не нужно не оборачивай.
Решения вопроса 1
Stalker_RED @Stalker_RED
Вот так без стилей совершенно непонятно зачем. Откроойте css, посмотрте какие стили применяются к wrapper-у, и станет понятно. Может на body они не применяются в принципе, или на body одни, а на wrapper-е другие.
Вот на тостере, например, вместо wrapper-а layout. Не позволяет растягиваться контенту на больших мониторах.
Ответ написан более трёх лет назад
Нравится 3 3 комментария
Root Wood @Root_Wood Автор вопроса
Я в том смысле, вот я начинаю новый проект. Какие могут быть у меня причины обернуть все в wrapper, зачем мне это делать?
Для ширины только? Ну а разве сложно у body выставить ширину?
Ну а разве сложно у body выставить ширину?
https://css-live.ru/articles/luchshij-sposob-reali. Прочтите раздел Тег против дополнительного
WapSter @wapster92 Куратор тега Вёрстка
Root_Wood, у боди вообще не стоит ничего указывать кроме параметров шрифта, и может быть ещё фона и то перед этим задав body какой-нибудь класс.
Wrapper css что это
Обертки бывают двух типов:
- Про расположение блока относительно других блоков
- Про лейаут внутри блока
Когда сталкиваетесь с первым случаем, чаще всего подойдет микс (либо с элементом родителя, либо с элементом сетки). Например:
Еще можно не экономить на лишних DOM-узлах и делать так:
Примером из реальной жизни для этого случая будет позиционирование универсальной кнопки, которая ничего не должна знать об отступах от границ какой-нибудь конкретной шапки.
Как делать не стоит: создавать модификаторы для кнопки, задающие margin и т.п. свойства. Такое позиционирование по смыслу не является частью универсального блока, а лишь его конкретного места использования. Да и модификаторов на всех не напасешься.
Если же обертка относится именно к данному блоку (скажем, позиционирование иконки внутри той самой универсальной кнопки или ограничитель по max-width для контента страницы), то это будет внутренний элемент inner :
Блок или элемент с названием wrap не имеет особого смысла, потому что на самом деле примерно никогда не нужно заворачивать конкретный блок в абстрактную обертку.
Комментарии: 23
9 years ago
9 years ago
Но чем по сути блок button__inner отличается от блока-враппера, обертки? Это же и есть обертка. Просто ей придумали «красивое» название. Нет?
9 years ago
Т.е. разница в том что мы договариваемся считать их элементами блока, а не отдельными блоками (связанными названием или не связанными, тк получилось придумать логичное имя)?
VS .block > .h-block , VS .l-block > b-block и т.д.
9 years ago
Давай еще раз: h- и l- блоки — это как раз случай, когда есть некая внешняя сущность, отвечающая за лейаут. В моем примере — это блок grid . Это работает, когда позиционирование является абстрактным в вакууме. Например, у нас есть шаг сетки и он всегда такой во всех случаях использования.
А есть ситуации, когда позиционирование является очень конкретным, связанным с данным конкретным блоком и только с ним. Тогда это очевидно элемент блока и отдельная дополнительная сущность не имеет смысла.
При этом важно понимать, что это не блок logo (и даже не logo_type_header ) имеет отступ 20 пикселей от границ шапки, а элемент шапки header__logo . Тогда logo можно будет использовать повторно где-то еще на странице и не перебивать каждый раз отступы, т.е. получится тот самый независимый универсальный блок.
9 years ago
Для внутреннего позиционирования — понятно, используем элементы-врапперы, придумывая им красивые названия. Но проблема с придумыванием имен для позиционирования внешнего — там бывает просто не знаешь что выдумать, а .l-block , .b-block — здорово выручают с неймингом. И бонусом получаем понимание смысла блока видимое из названия (то о чем пишет Гарри Робертс: http://csswizardry.com/2015/03/more-transparent-ui-code-with-namespaces/)
9 years ago
Я в посте написал буквально следующее: «на самом деле примерно никогда не нужно заворачивать конкретный блок в абстрактную обертку».
Можешь привести примеры макетов из реальной жизни, когда появляется необходимость в абстрактной внешней обертке не являющейся каким-либо аналогом сетки?
9 years ago
@tadatuta я тоже не понимаю о чем вещает @delka и какие кейсы он решает. По опыту примеры Вовы должны решать большенство кейсов
9 years ago
Вопрос про внутреннее позиционирование: что делать если надо разместить обертку внутри элемента, а не блока? И как правильно именовать эту обертку?
9 years ago
@alex-milovanov Ничего не меняется: