«Внутренняя» проблема

Предположим, что вам нужен контейнер на всю ширину окна. И все потому, что коде используется свойство background-color, растягивающее макет. Но содержимое страницы не обязательно должно растягиваться. Вам нужно добиться следующих результатов:

  1. Ограничить ширину (для больших экранов).
  2. Добавить отступы по краям.
  3. Отцентрировать содержимое.

Это не сложно реализовать…

Классическим решением является внешний и внутренний контейнеры

Предположим, что к элементу <body> применено свойство background-color , а также заданы отступы справа и слева. Внутренний контейнер (inside) ограничивает содержимое по ширине и высоте.

<footer>
  <div class="inside">
    Content
  </div>
</footer>
footer {
  --contentWidth: 400px;
  background: lightcoral;
  padding: 2rem 1rem;
}

.inside {
  max-width: var(--contentWidth);
  margin: 0 auto;
}

Кажется, что этот элемент (inside) лучше не использовать. Так как его нужно каждый раз добавлять его в разметку, когда используется такой шаблон. Но он выполняет ряд важных задач.

Что делать, если нужно использовать только один элемент?

Если у вас есть только один элемент, то свойство padding работает. Но для этого нужно использовать функцию calc(), чтобы вычесть половину максимальной ширины содержимого из 100%.

<footer>
  Content
</footer>
footer {
  --contentWidth: 600px;
  
  background: lightcoral;
  padding: 2rem calc((100% - var(--contentWidth)) / 2);
}

Но это не решает проблему касания краев. Может быть, стоило выбрать элементы внутри  и добавить к ним отступы с помощью селектора footer? Или  задать отступы для более «высоких» элементов. Например, <body>. Но это не сработает, потому что цвет фона должен охватывать всю область веб-страницы.

Что, если вы ограничены контейнером, который не можете контролировать, а из него нужно вырваться?

Тогда используйте следующее решение. Оно будет работать в центрированном контейнере любой ширины.

.full-width {
  width: 100vw;
  margin-left: 50%;
  transform: translateX(-50%);
}

Но это также растягивает содержимое контейнера на всю ширину. Поэтому нужно снова обратиться к внутреннему элементу.

Кроме этого, как только у вас появится вертикальная полоса прокрутки, значение 100vw приведет к добавлению горизонтального скроллбара. Чтобы избавиться от него, используйте свойство overflow-x:

body { overflow-x: hidden; }

Иначе придется явно установить ширину полосы прокрутки, а затем вычесть ее из 100vw.

body {
  scrollbar-width: 20px; /* способ в соответствии с будущими стандартами */
}

body::-webkit-scrollbar { /* способ webkit */
  width: 20px;
}

.full-width {
  width: calc(100vw - 20px);
}

Но тогда контейнер не вмещается в область просмотра по ширине, если нет вертикальной прокрутки. В CSS должен быть более приемлемый способ решения всех этих проблем.

Например, чтобы отобразить контейнер по ширине, можно вставить по края дополнительные поля. Но это не решит проблем, связанных с полосой прокрутки.

Если убрать overflow-x из родительского элемента, тогда отрицательное поле и положительный отступ могут помочь решить проблему

В этой версии реализации задействуются только классические свойства CSS.

Могут ли здесь помочь CSS Grid или Flexbox?

Не особо. Конечно, можно создать сетку из трех столбцов, и поместить содержимое в центральный столбец, используя внешние столбцы в качестве отступов. Но данный подход более сложен в реализации.

«Подкраска» краев

Необязательно использовать только свойство background-color. Вы всегда можете «подделать» левую и правую стороны, задав огромный box-shadow или разместив псевдоэлемент.

Пожалуйста, опубликуйте ваши мнения по текущей теме статьи. За комментарии, подписки, отклики, дизлайки, лайки огромное вам спасибо!

Пожалуйста, оставляйте ваши мнения по текущей теме статьи. За комментарии, лайки, дизлайки, подписки, отклики низкий вам поклон!

Вадим Дворниковавтор-переводчик статьи «The “Inside” Problem»