On The Drift

35 notes &

Use CSS to Specify the Aspect Ratio of a Fluid Element

[Update: Although I discovered this trick independently, I’ve since learned that Thierry Koblentz beat me to it. You can find his 2009 article on A List Apart. Credit where credit is due.]

This technique can be used to specify the aspect ratio of a fluid element using only CSS, no JavaScript or placeholder image required. By “fluid element”, I mean an element that can be dynamically resized. This requires that the width of the element be specified, and that the height of the element be expressed as a function of the width (or vice versa, though here the width must be specified).

The example below assumes an inline-level element in the normal flow, though the technique can be extended to block-level elements and absolutely positioned elements. 

First, the HTML:

<div id="container">
    <div id="dummy"></div>
    <div id="element">
        some text
    </div>
</div>

The element whose aspect ratio we want to specify has the ID “element”. The element is wrapped by a container that will be used to specify the width. Additionally, the element has a dummy element as a previous sibling that will be used the express the height as a function of the width. Effectively, the dummy element enforces the aspect ratio.

Now, the CSS:

#container {
    display: inline-block;
    position: relative;
    width: 50%;
}
#dummy {
    padding-top: 75%; /* 4:3 aspect ratio */
}
#element {
    position: absolute;
    top: 0;
    bottom: 0;
    left: 0;
    right: 0;
    background-color: silver /* show me! */
}

A working example can be seen here.

Why does this work?

  • display:inline-block makes the container an inline element that declares a new block formatting context.
  • position:relative gives the container a position box. The position box acts as the containing block of the inner elements. (Note: Using position:absolute would give the element a shrink-to-fit box that would act as the containing block of the inner elements.)
  • width:50% gives the box of the container a width that will be used for the aspect ratio. The width can be specified as a length or as a percentage.
  • padding-top:75% gives the box of the dummy element a height that is 75% of the aforementioned width, thus defining the aspect ratio. The key here is that a percentage value for padding-top or padding-bottom (or for margin-top or margin-bottom, for that matter) refers to the width of the containing block. Because the container is an inline-level block container, the height of the container is automatically computed as the height of the dummy element, which is based on the width of the container. Voilà, instant aspect ratio using only CSS.
  • position:absolute removes the element from the normal flow inside the container, allowing the dummy element to dictate the sizing of the container.
  • top/bottom/left/right:0 stretches the element to the edges of the container, which are determined by the aspect ratio as per the above. The element will thus receive all user events. Set margin/border/padding to taste.

[Edit: In the explanation of padding-top above, I swapped padding and margin from the original version of this post, in response to the excellent catch by Matthew and the follow-up suggestion from ciantic.]

I have tested this on the latest versions of Google Chrome, Firefox, Safari, and Opera as of this writing, with no apparent hangups.

Filed under CSS aspect ratio width height fluid fluid layout

  1. psdtohtmlshop reblogged this from ansciath
  2. ansciath posted this