aspect-ratio CSS property

Last updated:

Note: This is a personal draft. It is neither endorsed nor approved by the CSS Working Group.

Introduction

The aspect-ratio property allows you to control the shape of an element when one or both of its width and height are unconstrained. You can use it to, for example, require that an HTML <video> element is as wide as its parent element at all times, but maintain a 4:3 ratio.

The aspect-ratio Property

property : aspect-ratio

values : <number> | none

default value : none

applies to : block-level elements

computed value : same as specified value

(This doc uses the terms "measure" and "extent", which are the logical counterparts to the physical "width" and "height". They're defined in CSS Writing Modes Level 3. As well, the term "min or max constraints" refers to min-width, max-width, min-height, and max-height, whichever is appropriate for the dimension in question.)

The aspect-ratio property controls the resolution of underspecified values for the width and height properties of elements in CSS, such that the ratio of the measure and extent is a specific value.

For elements in static flow, width or height are underspecified if the computed values of width/height for the element are auto and the element is not a replaced element. For absolutely positioned elements, width is underspecified if the computed value for width on the element is auto and the computed values of left or right are auto; height is underspecified if the computed value for height on the element is auto and the computed values of left or right are auto. [[What about replaced elements?]]

The <number> in the value of the property must be greater than zero. If it is not, it is a syntax error.

If aspect-ratio is none, it must have no effect.

If aspect-ratio is not none, but neither width nor height are underspecified for the element, aspect-ratio must have no effect. [Brad Kemper points out that it may be better for back-compat to have aspect-ratio override in this case, just ignoring the extent dimension. This would let someone specify a "default" ratio via an explicit width/height, and have aspect-ratio take over to ensure it actually maintains the desired ratio.]

  • If the element's extent is underspecified and the measure is not, then the used value of the element's extent must be the result of dividing the element's measure by the aspect-ratio. If this would cause the element's extent to be in violation of a min or max constraint, the extent must instead be the value required by those constraints.

  • If the element's measure is underspecified and the extent is not, then the used value of the element's measure must be the result of multiplying the element's extent by the aspect-ratio. If this would cause the element's measure to be in violation of a min or max constraint, the measure must instead be the value required by those constraints.

  • If both the measure and extent are underspecified, first resolve the measure of the element normally, then follow these steps:

    1. Attempt to set the used value of the element's extent to the result of dividing the element's measure by the aspect-ratio.
    2. If the previous step would cause the element's extent to be in violation of a min or max constraint, then instead set the element's extent to the value required by those constrains, then attempt to set the used value of the element's measure to the result of multiplying the element's extent by the aspect-ratio.
    3. If the previous step would cause the element's measure to be in violation of a min or max constraint, then instead ignore the aspect-ratio property on this element.

For example, given an element with width:auto; height:auto; aspect-ratio: 2/1; max-height: 200px; in a 500px wide container, the element would first be set to 500px wide, then aspect-ratio would naively set the height to 250px, which is in violation of the max-height constraint. Instead, the element's height becomes 200px and the width is set to 400px. If the element additionally had min-width: 450px, aspect-ratio would be completely ignored, as there's no way to satisfy it.

[[Should we instead make it try and satisfy the aspect ratio somehow?]]

Note: This property take a single number as the ratio value. However, several common ratios are usually expressed as fractions or explicit ratios, such as "16 by 9". These can be easily expressed using the calc() function, like aspect-ratio: calc(16/9);.

Note: Videos, in particular, often do not exactly match a 4:3 or 16:9 ratio, even if they are advertised as such, because they are encoded with non-square pixels. As such, setting a <video> element to one of those ratios may end up with the element's ratio not quite matching the content's ratio. However, the default style for <video> in HTML (using the object-fit property) will letterbox the content, so it's not scaled in an ugly fashion.

Serialization

To serialize the value of the aspect-ratio property, serialize it as a <number> or <keyword>, as appropriate.

(a limited set of Markdown is supported)

#1 - lucitribal:

I'd love to see something like this implemented. Right now I find myself forced to use vw units that are a buggy mess or JavaScript hacks, none of which are ideal for defining the aspect ratio.

Reply?

(a limited set of Markdown is supported)