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:
- Attempt to set the used value of the element's extent to the result of dividing the element's measure by the aspect-ratio.
- 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.
- 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.
- Attempt to set the used value of the element's extent to the result of dividing the element's measure by the aspect-ratio.
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.
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?