A PostCSS plugin to fix an element's dimensions to an aspect ratio.
Explanation
The plugin provides three new properties and one new value type:
- The
aspect-ratioproperty makes the height of this element relative to its width,heightwill be dynamic based on the ratio.aspect-ratiohas two aliases you can use instead:ratioaspect
- An
aspect-ratioproperty that includes a value expressed as'NUM:NUM'(eg.'4:3') will automatically be converted to a percentage (3/4 * 100 = 75%). You must wrap the value in single ' or double " quotes.
The effect is achieved using the quirky behaviour of CSS percentage padding; any element with a percentage value for its padding property will use the width of its container to calculate that percentage. Therefore this plugin requires a specific HTML structure to work. The element you wish to constrain with an aspect ratio and a single inner element that will hold its contents.
<div class="aspect-box"> <div class="aspect-box__content"> <!-- Any content you like, very useful for video and image elements. --> </div> </div>
Install
npm install postcss-aspect-ratio --save
Example 1
A simple example using the custom ratio value '16:9'.
/* Input. */ .aspect-box { position: relative; background: lime; aspect-ratio: '16:9'; } /* Output. */ .aspect-box { position: relative; background: lime; box-sizing: border-box; } .aspect-box > * /* This targets .aspect-box__content */ { position: absolute; top: 0; right: 0; bottom: 0; left: 0; box-sizing: border-box; } .aspect-box:before /* This pseudo element uses the padding trick to set the height. */ { position: relative; display: block; content: ""; padding-top: 56.25%; box-sizing: border-box; }
Example 2
A more complex example using the ratio value calc('4:3' - 20px).
/* Input. */ .aspect-box { position: relative; background: lime; aspect-ratio: calc('4:3' - 20px); } /* Output. */ .aspect-box { position: relative; background: lime; box-sizing: border-box; } .aspect-box > * { position: absolute; top: 0; right: 0; bottom: 0; left: 0; box-sizing: border-box; } .aspect-box:before { position: relative; display: block; content: ""; padding-top: calc(75% - 20px); box-sizing: border-box; }