Skip to content

Using CSS Containment Context to Remove a Horizontal Scrollbar

by Christian Praß

When creating website layouts it’s sometimes required to escape the parent element’s boundaries horizontally, while keeping vertical flow consistent. One option to achieve this would be to have the horizontal padding and margin only apply to elements containing text, like paragraphs and lists. Defining the padding on a single root element is often easier.

Sometimes there are multiple layers of padding, margins and borders. Then it can be problematic trying to make a deeply nested element stretch the full width of the viewport. It’d require to know exactly how many pixels the element has to be moved relative to the parent component, to match the document root dimensions.

On this website I used a width of 100vw, combined with negative margin, to make the code blocks stretch the whole window width on smaller screens. Surprisingly, the use of vw lead to an unnecessary horizontal scrollbar appearing.

:root {
    --content-padding: 1rem;
}

.wrapper {
    padding: var(--content-padding);
}

pre {
    margin-left: calc(-1 * var(--content-padding));
    margin-right: calc(-1 * var(--content-padding));
    width: 100vw;
}

Container Queries to the Rescue

All modern browsers support container queries and the related CSS units like cqw (1% of the width of the closest container). Creating a query container can be done by giving an element the value size or inline-size for the container-type attribute. inline-size creates a query container for the inline axis. Using size creates a query container for both inline and block axis. This means that the container element no longer expands with the content on those axes.

With a query container the solution is quite simple. Make the body a query container and then refer to it’s width using cqw.

body {
    container-type: inline-size;
}

pre {
    width: 100cqw;
}

Note: this only works if the body element is the only query container wrapping the pre element. cqw will only use the size related to the closest parent container. There is a proposal for adding a CSS function for each container query unit that allows targeting the query container by name.