CSS full width div in parent div


i.e. its container is less than screen width

On this page, screen width = viewport width = vw = the part of the display containing pixels. This is essentially about vertical scrollbars on the right of the screen. The issue is that a vertical scrollbar may or may not exist, it is not a precise standard width, and it may or may not form part of the display but float over it and not be counted as part of its width. Plus, obviously, there is no such thing as a standard screen width. What, actually, is full-width? If it wasn't for scrollbars things would be simple.

On a desktop or laptop computer this column of text may seem in the centre of the screen horizontally. It is not, however. It's pushed slightly to the left of centre by the vertical scrollbar on the right. The grey side bands above are exactly the same width but this is not dead centre. It is on a mobile device, because on a mobile device the scrollbar is not part of the width but floats over it and may disappear altogether. The image lower on this page seems full width but is full width minus the width of the scrollbar.

Many websites are 'contained' in a column narrower than the screen width when the screen is at its widest – 1920 pixels wide for example – as the page content needs to be narrower for presentation and the readability of text. As the screen narrows to mobile phone width it matters less because the content needs to fill most of the screen width anyway, but it may matter if you want to be able to display an image at full screen width but the image is in a narrower column.

I have seen various ways to do this but none quite fitted the bill. On desktop computers, either a horizontal scrollbar popped up momentarily or part of a full width image was missing (or the image didn't quite go full width).

So I did it my own way, where .max is a div the full width of the screen minus the width of the scrollbar and half the .max div is half the full width minus half the width of the scrollbar.

The key is the CSS var(--scrollbar-width) which can only be obtained with JavaScript because scrollbar widths may vary. You can't always assume 17px.

<script>
document.body.style.setProperty(
    "--scrollbar-width",
    `${window.innerWidth - document.body.clientWidth}px` // Note the backticks (required)
);
</script>

or

<script>
const setSB = function () {
    let scrollbarWidth = window.innerWidth - document.body.clientWidth;
    document.documentElement.style.setProperty('--scrollbar-width', `${scrollbarWidth}px`); // Note the backticks (required)
}
window.addEventListener('DOMContentLoaded', setSB);
window.addEventListener('resize', setSB);
</script>

The full width <div> CSS class max:

<style>
.max {
    width: calc(100vw - var(--scrollbar-width));
    position: relative;
    left: 50%;
    right: 50%;
    margin-left: calc(-50vw + (var(--scrollbar-width) / 2));
    margin-right: calc(-50vw + (var(--scrollbar-width) / 2));
}
</style>

The width of .max is the calculated full width of the screen less the width of the scrollbar (as calculated with JavaScript). But the starting point of .max is inside a container narrower than the screen – the wrong position, putting .max out to the right from inside its container.

left and right put .max in the centre of the screen including the scrollbar then the margins pull it back out by negative values equal to (half the width of the browser screen minus half the scrollbar width). Because .max has a width equal to the width of the screen minus the scrollbar, it fits the space exactly.

Pixel-perfect accuracy is the thing.

Photo by Patrick Taylor (me)

« W3C discussion here | Technical »


Leave a message for Patrick


—   
Page last modified: 16 August, 2024
Search | Legal | Qwwwik
Patrick Taylor Art

Menu