Boxes That Fill Height (Or More) (and Don’t Squish)
It’s hard to sum up all the awesome that is flexbox in a little ol’ blog post. Although we gave it a shot here. Here, let’s just try and focus on one thing that flexbox solves very nicely: the ability to have an arbitrary set of boxes fill up all the available height of a parent box. And not only that, but expand beyond that if needed (not squish them to fit). By “box”, I just mean block level element. Div, section, article, whatever. By default those boxes height is determined by the content inside them. They will stack on top of each other. Their parent boxes height might also be determined by their height combined, but it could be different (e.g. it’s set explicitly or it’s something variable like the browser window). If the parent box has a larger height, there will just be empty space below. Can’t we force the boxes to split up the space evenly amongst that space? We can with flexbox. Say the HTML is like:
With just that, it will look no different than it did if we did nothing. But now we apply the flex property to the children and they will fill the space:
Annnnd done =). As a detail here, flex: 1; is the same as saying flex: 1 1 auto; It is shorthand for three different properties:
flex-grow: 1; flex-shrink: 1; flex-basis: auto;
Just so happens that giving them the ability to grow on an equal basis the most common need so flex: 1; is a nice way to write that. One of the nice things about flexbox is this will work with an arbitrary number of boxes. Could be a single box! Could be 100 boxes! Doesn’t matter. If there is extra room, the space will be divided and filled. If not, no big deal. In a pre-flexbox world, we might have tried to know/find out how many boxes there were, and then set their heights with percentages. That works to fill extra space, but if there were too many boxes, you’d get squished. That’s another nice thing about flexbox, it won’t squish those boxes to the point of them not being able to fit their content. So… If we wanted to take this a step further, we could use flexbox to center the content within those boxes too (!). This is where people get mad at CSS though. Vertical centering is kinda hard. Even with flexbox here, we’ll need to make each of those flex item children we have into flex containers as well. Then use an internal wrapper which becomes the flex item we center. So yeah, an extra element still. To center it, we make the direction up-and-down again (column) and use another flexbox property, justify-content , to center it.
This is where the reference guide comes in handy… finding out which property does what quickly. Then we get this: See the Pen Boxes That Fill Height (or more) by Chris Coyier (@chriscoyier) on CodePen.
I’ve only used the latest syntax here in this post. Current versions of Chrome, Opera support it just like that. Near-future versions of Firefox and Android will be supporting it just like that as well. Safari and iOS support the new syntax, just with -webkit- prefixes. Can I Use has the whole story. IE is weird. IE 10 supports the tweener version of flexbox (e.g. display: -ms-flexbox;). IE 11 supports the latest flexbox. With this particular demo though, something is broken. While the height of .fill-height-or-more renders at full height by using min-height , the boxes are squished. If you use height instead of the flex container, it “works” – but the point here was using min-height to avoid squishing. Seems like an implementation bug to me. UPDATE: Nirav Zaveri wrote to tell me that in IE (I tested v11), flex: 1 isn’t the same as flex: 1 1 auto , even though it should be (?). If you set the later, it works. It’s understandable that you might need to go back a bit further with browser support. Firefox 27, iOS 6, and Safari 6 are pretty legit browser support targets and all those use some variation of the older syntax, sometimes prefixed and sometimes not. Just our little example looks like this when as fleshed out as it can be for support:
.fill-height-or-more < display: -webkit-box; display: -webkit-flex; display: -moz-box; display: -ms-flexbox; display: flex; -webkit-box-orient: vertical; -webkit-box-direction: normal; -webkit-flex-direction: column; -moz-box-orient: vertical; -moz-box-direction: normal; -ms-flex-direction: column; flex-direction: column; >.fill-height-or-more > div
Yeesh. My recommendation? Write it in the modern syntax like I have above and let Autoprefixer deal with it, which not only deals with the prefixing but the older syntax as well.
Might as well hey? I published it here and I’ll embed it also:
Oh and just for the record, the real-world scenario that brought this on for me was this page.object-fit
The object-fit CSS property sets how the content of a replaced element, such as an or , should be resized to fit its container.
You can alter the alignment of the replaced element’s content object within the element’s box using the object-position property.
Try it
Syntax
object-fit: contain; object-fit: cover; object-fit: fill; object-fit: none; object-fit: scale-down; /* Global values */ object-fit: inherit; object-fit: initial; object-fit: revert; object-fit: revert-layer; object-fit: unset;
The object-fit property is specified as a single keyword chosen from the list of values below.
Values
The replaced content is scaled to maintain its aspect ratio while fitting within the element’s content box. The entire object is made to fill the box, while preserving its aspect ratio, so the object will be «letterboxed» if its aspect ratio does not match the aspect ratio of the box.
The replaced content is sized to maintain its aspect ratio while filling the element’s entire content box. If the object’s aspect ratio does not match the aspect ratio of its box, then the object will be clipped to fit.
The replaced content is sized to fill the element’s content box. The entire object will completely fill the box. If the object’s aspect ratio does not match the aspect ratio of its box, then the object will be stretched to fit.
The replaced content is not resized.
The content is sized as if none or contain were specified, whichever would result in a smaller concrete object size.
Formal definition
Formal syntax
object-fit =
fill |
contain |
cover |
none |
scale-down
Examples
Setting object-fit for an image
HTML
section> h2>object-fit: fillh2> img class="fill" src="mdn_logo_only_color.png" alt="MDN Logo" /> img class="fill narrow" src="mdn_logo_only_color.png" alt="MDN Logo" /> h2>object-fit: containh2> img class="contain" src="mdn_logo_only_color.png" alt="MDN Logo" /> img class="contain narrow" src="mdn_logo_only_color.png" alt="MDN Logo" /> h2>object-fit: coverh2> img class="cover" src="mdn_logo_only_color.png" alt="MDN Logo" /> img class="cover narrow" src="mdn_logo_only_color.png" alt="MDN Logo" /> h2>object-fit: noneh2> img class="none" src="mdn_logo_only_color.png" alt="MDN Logo" /> img class="none narrow" src="mdn_logo_only_color.png" alt="MDN Logo" /> h2>object-fit: scale-downh2> img class="scale-down" src="mdn_logo_only_color.png" alt="MDN Logo" /> img class="scale-down narrow" src="mdn_logo_only_color.png" alt="MDN Logo" /> section>
CSS
h2 font-family: Courier New, monospace; font-size: 1em; margin: 1em 0 0.3em; > img width: 150px; height: 100px; border: 1px solid #000; margin: 10px 0; > .narrow width: 100px; height: 150px; > .fill object-fit: fill; > .contain object-fit: contain; > .cover object-fit: cover; > .none object-fit: none; > .scale-down object-fit: scale-down; >
Result
Specifications
Browser compatibility
BCD tables only load in the browser
See also
Found a content problem with this page?
This page was last modified on Jul 7, 2023 by MDN contributors.
Your blueprint for a better internet.
MDN
Support
Our communities
Developers
Visit Mozilla Corporation’s not-for-profit parent, the Mozilla Foundation.
Portions of this content are ©1998– 2023 by individual mozilla.org contributors. Content available under a Creative Commons license.
Box Sizing
The box-sizing property can make building CSS layouts easier and a lot more intuitive. It’s such a boon for developers that here at CSS-Tricks we observe International Box-Sizing Awareness Day in February. But, how is it so helpful and beloved that it deserves its own internet holiday? Time for a little bit of CSS history.
Since the dawn of CSS, the box model has worked like this by default: width + padding + border = actual visible/rendered width of an element’s box height + padding + border = actual visible/rendered height of an element’s box This can be a little counter-intuitive, since the width and height you set for an element both go out the window as soon as you start adding padding and borders to the element. Back in the old days of web design, early versions of Internet Explorer (
Those wishes were granted when the box-sizing property was introduced in CSS3. Though box-sizing has three possible values ( content-box , padding-box , and border-box ), the most popular value is border-box . Today, the current versions of all browsers use the original “width or height + padding + border = actual width or height” box model. With box-sizing: border-box; , we can change the box model to what was once the “quirky” way, where an element’s specified width and height aren’t affected by padding or borders. This has proven so useful in responsive design that it’s found its way into reset styles. At this point you may be asking yourself, “Is it possible that Old IE did something right?” Plenty of people think so.
This demo shows how border-box can help make responsive layouts more manageable. The parent div ‘s width is 50%, and it has 3 children with different widths, padding, and margins. Click the border-box button to get all the children in the right place inside the parent. See the Pen Box Sizing Layout Demo by CSS-Tricks (@css-tricks) on CodePen.
Good, Better, and (Probably) Best box-sizing Reset Methods
This works fairly well, but it leaves out pseudo elements, which can lead to some unexpected results. A revised reset that covers pseudo elements quickly emerged:
This method selected pseudo elements as well, improving the normalizing effect of border-box . But, the * selector makes it difficult for developers to use content-box or padding-box elsewhere in the CSS. Which brings us to the current frontrunner for best practice:
Universal Box Sizing with Inheritance
This reset gives you more flexibility than its predecessors — you can use content-box or padding-box (where supported) at will, without worrying about a universal selector overriding your CSS. We went into more depth on this technique and the reasoning behind it in “Inheriting box-sizing Probably Slightly Better Best Practice”. One potential gripe with it is that box-sizing isn’t normally inherited, so it’s specialized behavior, not quite the same as something you’d normally put in a reset.
Every current browser supports box-sizing: border-box; unprefixed, so the need for vendor prefixes is fading. But, if you need to support older versions of Safari ( -webkit and -moz , like this:
box-sizing: border-box; is supported in the current versions of all major browsers. The less-commonly used padding-box is only supported in Firefox at the moment. There’s more comprehensive information about browser support in our box-sizing almanac entry. There are a few issues with older versions of Internet Explorer (8 and older). IE 8 doesn’t recognize border-box on elements with min/max-width or min/max-height (this used to affect Firefox too, but it was fixed in 2012). IE 7 and below do not recognize box-sizing at all, but there’s a polyfill that can help.