Как заверстать блок во всю ширину окна внутри блока с произвольной шириной

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

Просто рандомная космическая фотка с Ансплеша. Красивенькая.
Фотка Вила Стюарта из Ансплеша

Ширина основной колонки с контентом при этом абсолютно произвольная и может меняться в зависимости от размеров окна, настроения браузера и фазы луны. Единственное, что про нее достоверно известно — она выровнена по центру:

Самый очевидный способ — прервать блок с контентом, сделать блок без маржинов, затем продолжить контент:

Проблема в том, что посты удобно писать маркдауном, а в маркдауне от такого способа получается адская каша, за которой сложно следить:

<div class="text-content">

# Пост!

Бла бла бла-бла бла. Бла бла? Бла бла-бла...

...бла блабла:

</div>

<div class="fullwidth">
<!-- какая-то демка -->
</div>

<div class="text-content">

Бла блаааа бла бла-бла...

<!-- ...one eternity later -->

</div>

А хочется вот так:

# Пост!

Бла бла бла-бла бла. Бла бла? Бла бла-бла...

...бла блабла:

<div class="fullwidth">
<!-- какая-то демка -->
</div>

Бла блаааа бла бла-бла...

Окей, вставляем блок в контент и даем ему width: 100vw:

Теперь его надо сдвинуть к левому краю окна. Расстояние неизвестно, но у нас есть ширина блока с контентом (100%) и ширина окна (100vw). Сначала двигаем блок направо с помощью margin-left: 50%:

Теперь блок начинается ровно с середины окна. Отнимаем 50vw, чтобы блок уехал к левому краю. Получается margin-left: calc(50% - 50vw), блок встает на нужное место:

Стиль блока выглядит так:

.fullwidth {
width: 100vw;
margin-left: calc(50% - 50vw);
}

Класс, то что надо.

... или нет? А это что за хрень?

Горизонтальный скролл, блин, откуда?

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

А счастье было так близко. Окей, время костылей. Гуглением находится один приемлемый костыль: засунуть в <head> скрипт, который будет класть в css-переменную 1vw здорового человека (то есть без учета ширины скроллбара) и пересчитывать его при ресайзах:

<script>
(function () {
function setVw() {
const vw = document.documentElement.clientWidth / 100;
document.documentElement.style.setProperty('--vw', `${vw}px`);
}

setVw();
window.addEventListener('resize', setVw);
}());
</script>

Теперь у нас есть переменная var(--vw), в которой лежит нужное нам количество пикселей. Но по старой традиции лучше использовать ее с фоллбеком на обычный 1vw, вот так: var(--vw, 1vw).

В результате стиль блока превращается в...

.fullwidth {
width: calc(100 * var(--vw, 1vw));
margin-left: calc(50% - 50 * var(--vw, 1vw));
}

Мде.

Препроцессоры немного сглаживают эту жесть. Я себе сделал переменную $vw: var(--vw, 1vw), мой стиль теперь выглядит как-то так:

.fullwidth
width: calc(100 * $vw)
margin-left: calc(50% - (50 * $vw))

Жить можно.

P.S. Скроллбары на маке

Если вы верстаете на маке, рекомендую включить в настройках системы постоянное отображение скроллбаров: сразу будут видны косяки с горизонтальным (а иногда и с вертикальным) скроллом.

Подавляющее большинство ваших пользователей на винде, где скроллбары всегда видны. Будьте чуть ближе к ним.