
We Completely Missed width/height: stretch
We Completely Missed width/height: stretch êŽë š
The stretch keyword, which you can use with width and height (as well as min-width, max-width, min-height, and max-height, of course), was shipped in Chromium web browsers back in June 2025. But the value is actually a unification of the non-standard -webkit-fill-available and -moz-available values, the latter of which has been available to use in Firefox since 2008. The issue was that, before the @supports at-rule, there was no nice way to implement the right value for the right web browser, and I suppose we just forgot about it after that until, whoops, one day I see Dave Rupert casually put it out there on Bluesky a month ago:

Layout pro Miriam Suzanne recorded an explainer shortly thereafter. Itâs worth giving this value a closer look.
What does stretch do?
The quick answer is that stretch does the same thing as declaring 100%, but ignores padding when looking at the available space. In short, if youâve ever wanted 100% to actually mean 100% (when using padding), stretch is what youâre looking for:
div {
  padding: 3rem 50vw 3rem 1rem;
  width: 100%; /* 100% + 50vw + 1rem, causing overflow */
  width: stretch; /* 100% including padding, no overflow */
}
CodePen Embed Fallback https://codepen.io/mrdanielschwarz/pen/VYewxej width: stretch demo
The more technical answer is that the stretch value sets the width or height of the elementâs margin box (rather than the box determined by box-sizing) to match the width/height of its containing block.
Note
Itâs never a bad idea to revisit the CSS Box Model for a refresher on different box sizings.
And on that note â yes â we can achieve the same result by declaring box-sizing: border-box, something that many of us do, as a CSS reset in fact.
*,
::before,
::after {
  box-sizing: border-box;
}
I suppose that itâs because of this solution that we forgot all about the non-standard values and didnât pay any attention to stretch when it shipped, but I actually rather like stretch and donât touch box-sizing at all now.
Yay stretch, nay box-sizing
There isnât an especially compelling reason to switch to stretch, but there are several small ones. Firstly, the Universal selector (*) doesnât apply to pseudo-elements, which is why the CSS reset typically includes ::before and ::after, and not only are there way more pseudo-elements than we might think, but the rise in declarative HTML components means that weâll be seeing more of them. Do you really want to maintain something like the following?
*, 
::after,
::backdrop,
::before,
::column,
::checkmark,
::cue (and ::cue()),
::details-content,
::file-selector-button,
::first-letter,
::first-line,
::grammar-error,
::highlight(),
::marker,
::part(),
::picker(),
::picker-icon,
::placeholder,
::scroll-button(),
::scroll-marker,
::scroll-marker-group,
::selection,
::slotted(),
::spelling-error,
::target-text,
::view-transition,
::view-transition-image-pair(),
::view-transition-group(),
::view-transition-new(),
::view-transition-old() {
  box-sizing: border-box;
}
Okay, Iâm being dramatic. Or maybe Iâm not? I donât know. Iâve actually used quite a few of these and having to maintain a list like this sounds dreadful, although Iâve certainly seen crazier CSS resets. Besides, you might want 100% to exclude padding, and if youâre a fussy coder like me you wonât enjoy un-resetting CSS resets.
Animating to and from stretch
Opinions aside, thereâs one thing that box-sizing certainly isnât and thatâs animatable. If you didnât catch it the first time, we do transition to and from 100% and stretch:
CodePen Embed Fallback https://codepen.io/mrdanielschwarz/pen/VYewxej width: stretch demo
Because stretch is a keyword though, youâll need to interpolate its size, and you can only do that by declaring interpolate-size: allow-keywords (on the :root if you want to activate interpolation globally):
:root {
  /* Activate interpolation */
  interpolate-size: allow-keywords;
}
div {
  width: 100%;
  transition: 300ms;
  &:hover {
    width: stretch;
  }
}
The calc-size() function wouldnât be useful here due to the web browser support of stretch and the fact that calc-size() doesnât support its non-standard alternatives. In the future though, youâll be able to use width: calc-size(stretch, size) in the example above to interpolate just that specific width.
Web browser support
Web browser support is limited to Chromium browsers for now:
- Opera 122+
 - Chrome and Edge 138+ (140+ on Android)
 
Luckily though, because we have those non-standard values, we can use the @supports at-rule to implement the right value for the right browser. The best way to do that (and strip away the @supports logic later) is to save the right value as a custom property:
:root {
  /* Firefox */
  @supports (width: -moz-available) {
    --stretch: -moz-available;
  }
  /* Safari */
  @supports (width: -webkit-fill-available) {
    --stretch: -webkit-fill-available;
  }
  /* Chromium */
  @supports (width: stretch) {
    --stretch: stretch;
  }
}
div {
  width: var(--stretch);
}
Then later, once stretch is widely supported, switch to:
div {
  width: stretch;
}
In a nutshell
While this might not exactly win Feature of the Year awards (I havenât heard a whisper about it), quality-of-life improvements like this are some of my favorite features. If youâd rather use box-sizing: border-box, thatâs totally fine â it works really well. Either way, more ways to write and organize code is never a bad thing, especially if certain ways donât align with your mental model.
Plus, using a brand new feature in production is just too tempting to resist. Irrational, but tempting and satisfying!