A front-end developer discusses the imperfections of the classic CSS full-bleed utility class and presents modern fixes using CSS containment and container units to avoid scrollbar-related clipping issues.
# Fixing full-bleed CSS
Source: [https://dbushell.com/2026/07/03/fixing-full-bleed-css/](https://dbushell.com/2026/07/03/fixing-full-bleed-css/)
Friday 3Jul2026
I’m a front\-end developer not a medical practitioner\. If you’re bleeding IRL visit the hospital and stop googling medical issues\!
The[full\-bleed layout](https://www.joshwcomeau.com/css/full-bleed/)— as described there by Josh Comeau — can be done with CSS grid \([and subgrid](https://dbushell.com/2026/04/02/css-subgrid-is-super-good/)\)\. Sometimes you can’t grid the entire page\.
That’s where[Andy Bell’s utility class](https://piccalil.li/blog/creating-a-full-bleed-css-utility/)is useful\.
```
.full-bleed {
width: 100vw;
margin-left: calc(50% - 50vw);
}
```
But it ain’t perfect\. The issue is that viewport units don’t solve the[classic scrollbar problem](https://www.smashingmagazine.com/2023/12/new-css-viewport-units-not-solve-classic-scrollbar-problem/)\. If you’re on macOS or a fancy OS that has fancy scrollbars, test on Windows\!`100vw`can be wider than the viewport\. Because why would browsers do anything sensible?
It’s hard to see in[Andy’s CodePen](https://codepen.io/piccalilli/pen/vYOJjNw)but a few pixels can be cropped either side\. Add something like a border or shadow and it’s easier to see\.
```
.full-bleed {
box-shadow: inset 0 0 0 10px yellow;
}
```
Yellow border is slightly clipped either side\.
Ignore the pink left border that’s my blog style\.This is not always a problem but it can lead to subtle alignment issues\. By the way, macOS has a scrollbar setting*“Show scroll bars \> Always”*that’ll let you test the issue\.
macOS scrollbar settings on the appearance tab\.
Andy solves this partially by hiding horizontal overflow on the`<body\>`element\.
```
body {
overflow-x: hidden;
}
```
An alternative fix is to always reserve space for the classic scrollbar\.
```
html {
scrollbar-gutter: stable;
}
```
That can look weird if there is no vertical scroll necessary\.
## Modern solution
The “modern” approach is to use[CSS containment](https://developer.mozilla.org/en-US/docs/Web/CSS/Guides/Containment)\. Turn the`<body\>`element \(or any 100% width child\) into a container\. Then replace the viewport units with container units\.
```
body {
container: body / inline-size;
overflow-x: clip;
}
.full-bleed {
inline-size: 100cqi;
margin-inline-start: calc(50% - 50cqi);
}
```
Now hiding overflow is not strictly necessary\. I prefer`clip`— see[Overflow Clip guide](https://ishadeed.com/article/overflow-clip/)by Ahmad Shadeed\. I clip out of caution because[I make dumb things\.](https://dbushell.com/2026/07/02/the-modern-app/)I also use[logical properties and values](https://dbushell.com/2021/02/02/changing-css-for-good-logical-properties-and-values/)to support right\-to\-left \(RTL\) text direction\. Ahmad has an excellent[RTL Styling 101](https://rtlstyling.com/)too\.
But wait\!
Using`cqi`units assumes`body`is the parent container of the`\.full\-bleed`element\. What if we have nested containers? Check this out\.[I’ve forked Andy’s CodePen](https://codepen.io/dbushell/pen/rajYvPj)to add another`\.inside`container that is**not**the full viewport width\.
Inspecting CSS container layout using Chromium dev tools to show that the inside container is smaller\.
This alone would usually break the new`\.full\-bleed`class and ruin the fun\.
But we can fix that\!
```
@property --body-size {
syntax: "<length> | <percentage>";
inherits: true;
initial-value: 100%;
}
body {
container: body / inline-size;
}
.inside {
--body-size: 100cqi;
container: inside / inline-size;
}
.full-bleed {
inline-size: var(--body-size);
margin-inline-start: calc(50% - (0.5 * var(--body-size))); /* † */
}
```
What is that[`@property`magic?](https://developer.mozilla.org/en-US/docs/Web/CSS/Reference/At-rules/@property)
To be honest I struggle to wrap my smooth brain around this\!
Let me try to explain it to myself\. Without the at\-rule the value of`\-\-body\-size`is calculated at the time of use, i\.e\. within`\.full\-bleed`and therefore relative to the`inside`container\. By explicitly defining a`@property`the value is now calculated when it’s set within`\.inside`\. There`100cqi`refers to the parent`body`container and`\.full\-bleed`inherits that value\.
But what if you have more containers?
\(╯°□°\)╯︵ ┻━┻
*Gosh\!*Stop being so difficult\!
I would have a direct child of`<body\>`like`<main\>`set the`\-\-body\-size`value\.
```
<body>
<main>
<!-- blah -->
</main>
</body>
```
†I’m multiplying by 0\.5 because division is for chumps\.
## Next\-gen solution
What CSS needs is a way to reference a container when using container units\.
[Ideas have been proposed](https://github.com/w3c/csswg-drafts/issues/7858)for example:
```
.full-bleed {
inline-size: 100cqi(body);
inline-size: calc(100 * cqi(body));
inline-size: calc(100 * container(cqi, body));
}
```
Cancel[Interop 2026](https://wpt.fyi/interop-2026)and make this happen\!
A personal blog post by a non-web developer discusses the unavoidable bad parts of CSS, including layout challenges, browser defaults, and wrapper overuse, while highlighting a learnable subset for simple tasks.
The article discusses implementing vertical rhythm in web design using CSS, specifically leveraging the `rlh` unit for text alignment and providing a JavaScript workaround for responsive images to maintain consistent spacing.
The author reflects on migrating from Tailwind CSS to vanilla CSS with semantic HTML, sharing insights on structuring CSS using systems like resets, components, and utility classes learned from Tailwind.