Контейнеры, блоки и другие элементы на всю ширину внутри фиксированного блока
- 18 октября, 2022
- 9:57 пп
- Нет комментариев
Итак, вопрос: как сделать контейнер полноэкранной ширины внутри родительского элемента ограниченной ширины?
Размышления
Если бы мы могли использовать абсолютное позиционирование, мы бы задали контейнеру left: 0;
и width: 100%;
, но мы не можем этого сделать, так как хотим, чтобы контейнер остался в потоке.
Можем ли мы применить отрицательные внешние отступы с каждой стороны, тем самым раздвинув контейнер наружу? В некоторых обстоятельствах можем!
Ширина родительского элемента задана в процентах
Предположим, что ширина родительского элемента 60% и он центрирован. Это значит, что у нас есть по 20% ширины с каждой стороны. Но внешний отступ расчитывается исходя из ширины родительского элемента, а не всей ширины; в нашем случае 20% от ширины экрана это 33% от ширины родительского элемента.
main {
width: 60%;
margin: 0 auto;
/* creates 20% margins on either side */
}
.full-width {
/* 1/3 of 60% = the 20% margin on either side */
margin-left: -33.33%;
margin-right: -33.33%;
}
Ширина родительского элемента задана в пикселях
В большинстве случаев у нас нет достаточной информации о том, насколько надо расширять контейнер до полной ширины при помощи отрицательных внешних отступов.
Хотя…
Мы можем использовать ширину окна браузера в наших расчетах CSS. Расстояние, на которое нам надо расширить контейнер влево и вправо это половина ширины окна браузера плюс половина ширины родительского элемента (мы исходим из того, что родительский элемент центрирован).
Итак, ширина родительского элемента 500 пикселей:
.full-width {
margin-left: calc(-100vw / 2 + 500px / 2);
margin-right: calc(-100vw / 2 + 500px / 2);
}
Фиксированная ширина вроде этой немного тревожит (а что будет на экранах меньшей ширины?), все это стоит обернуть медиа-запросом, чтобы правила срабатывали только на больших экранах:
@media (min-width: 500px) {
main {
width: 500px;
margin: 0 auto;
}
.full-width {
margin-left: calc(-100vw / 2 + 500px / 2);
margin-right: calc(-100vw / 2 + 500px / 2);
}
}
Так как в нашей демонстрации используется изображение, имеет смысл добавить стили и ему, типа .full-width img { width: 100%; }
, чтобы изображение могло занять весь экран.
@media (min-width: $max-width) {
.full-width {
margin-left: calc(50% - 50vw);
margin-right: calc(50% - 50vw);
}
}
Метод с трансформацией
Мы, как правило, не задействуем анимации, но в качестве решения для расширения контейнера можно использовать и свойства трансформации.
@media (min-width: 40em) {
.full-width {
width: 100vw;
transform: translateX(calc((40em - 100vw)/2));
}
}
Директива @supports()
/* See warning below */
@supports (width: 100vw) {
.full-width {
width: 100vw;
}
@media all and (min-width: 40rem) {
.full-width {
transform: translateX(calc((40rem - 100vw)/2));
}
}
}
Метод без использования calc()
Свен Вольферманн последовал идее Джона Нила, с которой нам не нужны расчеты с помощью calc()
:
.full-width {
width: 100vw;
position: relative;
left: 50%;
right: 50%;
margin-left: -50vw;
margin-right: -50vw;
}
А вот сама идея: сдвинуть контейнер в центр браузера с помощью left: 50%;
, а затем вернуть его к левому краю с помощью отрицательного внешнего отступа в -50vw
.
Таким образом вам не нужно вообще никакой информации о родительском элементе. Но запомните: также как и в случае с calc()
, этот вариант также требует центрирования родительского элемента.
Вы можете подумать, а зачем задействовать right
и margin-right
? Действительно, вы можете обойтись без них на обычном сайте, текст которого располагается слева направо, но мы учитываем и вариант с direction: rtl;
, таким образом, делая код пуленепробиваемым.