The stretch keyword: a better alternative to width: 100% in CSS?
Certain HTML elements, like a div
or a p
, will stretch to take up the full available width by default. If you give them a horizontal margin
, it won’t cause a horizontal scrollbar. This is an incredibly useful default behaviour. Of course, many other elements aren’t full-width by default. Let’s look at a few instances where width: 100%
comes in handy, before looking at a newer alternative.
The default dimensions of an image are defined by the embedded image’s intrinsic size. It’s necessary to give large images a width
of 100%
to prevent overflow.
Want a button
or a select
element to be full width? You’ll need to apply width: 100%
.
If you add a left or right margin
to any element with a width
set to 100%
, it will cause overflow, leading to a horizontal scrollbar.
This could already be solved by using calc
to subtract the combined value of both margins. So if you had a left and right margin
of 24px
, the following would work:
button {
width: calc(100% - 48px);
margin-inline: 24px;
}
If you later decide to update the visual design by changing the size of the margins, you’d also need to change the value in the calc
function. There’s now a simpler approach that lets you avoid math entirely: the stretch
keyword.
button {
width: stretch;
margin-inline: 24px;
}
This property allows other elements to adopt the auto
behaviour of divs and paragraph elements: stretch to fill the available width while also allowing for the unproblematic use of margins.
The stretch
keyword is also specced to work when specifying height
and flex-basis
.
Browser support
stretch
is one of the few CSS properties that still requires a vendor prefix. The following code should work in all browsers:
width: -webkit-fill-available;
width: -moz-available;
width: stretch;
This property is finally being standardised and should be available unprefixed soon.
For now, only width
is supported by all browsers. Using -moz-available
or -webkit-fill-available
for min-width
or max-width
is not supported by Firefox or Safari. -moz-available
does not work for height
in Firefox. Chrome doesn’t support -webkit-fill-available
as a value for flex-basis
.
Sidenote on width: auto
If you’ve ever struggled to understand what width: auto
meant, understanding stretch
gets you half way there. auto
will map to fit-content
for elements like form controls and will map to stretch
for elements like divs.