CSS Gets a stretch That Finally Ignores Padding

The stretch keyword shipped in Chromium browsers in June 2025. It works with width, height, and their min-/max- variants. What many developers may have missed is that this value is actually a standardization of the non-standard -webkit-fill-available and -moz-available values, the latter of which has been available in Firefox since 2008.

Before the @supports at-rule, there was no clean way to target browser-specific implementations of this behavior, so the early variants got largely forgotten. Now they've returned as a unified, standards-track keyword.

The quick version: 100%, minus padding

The practical effect of stretch is similar to declaring 100%, but it ignores padding when calculating available space. If you've ever needed 100% to genuinely fill a container while also using padding, this is the direct solution:

div {
  padding: 3rem 50vw 3rem 1rem;
  width: 100%; /* 100% + 50vw + 1rem, causing overflow */
  width: stretch; /* 100% including padding, no overflow */
}

Technically, the value sets the element's margin box (not the intrinsic box determined by box-sizing) to the width and height of its containing block. As the box model reminds us, you could get the same result by manually applying box-sizing: border-box — a common reset practice.

*,
::before,
::after {
  box-sizing: border-box;
}

Do we still need box-sizing resets?

The box-sizing: border-box workaround has been so widely adopted that it likely explains why stretch flew under the radar. The problem with that approach is distribution. The universal selector (*) doesn't apply to pseudo-elements, which forces resets to enumerate ::before, ::after, and many others:

*, 
::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;
}

While that's a contrived example, the growing list of pseudo-elements and the rise of declarative HTML components mean more of them will appear in practice. Alternatively, you might want 100% to exclude padding in a particular case — un-resetting a reset can get unwieldy. Using stretch avoids touching box-sizing entirely.

One thing box-sizing can't do: animate

Transitioning between 100% and stretch works, but stretch is a keyword. To animate it, you need to allow keyword interpolation by declaring interpolate-size: allow-keywords, typically on :root for global effect:

:root {
  /* Activate interpolation */
  interpolate-size: allow-keywords;
}

div {
  width: 100%;
  transition: 300ms;

  &:hover {
    width: stretch;
  }
}

calc-size() won't help right now because it lacks support for the non-standard predecessors, and its browser support doesn't align well with stretch. In the future, however, you'll be able to write width: calc-size(stretch, size) to interpolate just that particular value.

Support and a graceful fallback

For now, only Chromium-based browsers support the standard keyword:

  • Opera 122+
  • Chrome and Edge 138+ (140+ on Android)

Since Firefox still relies on its non-standard variants, the @supports at-rule is the path. The cleanest approach is to encapsulate the browser-appropriate value in a custom property, then strip the logic later when support improves:

: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);
}

Once wide support arrives, simply switch to the simplified version:

div {
  width: stretch;
}

It's a subtle quality-of-life improvement rather than a headline feature. The existing box-sizing: border-box reset does the job well, and the choice between approaches will often rest on preference and maintenance overhead. But having options, especially those that better match a particular mental model of the box model, is always a win.