ampproject / ampproject/amphtml
I2I: Use aspect ratio CSS to implement responsive layout
- Dominant language
- JavaScript
- Stars
- 14.9k
- Forks
- 4.1k
- PR merge metrics
- No merged PRs in 30d
Description
## Summary
The new [`aspect-ratio`](https://developer.mozilla.org/en-US/docs/Web/CSS/aspect-ratio) CSS layout from [CSS Sizing 4](https://drafts.csswg.org/css-sizing-4/#aspect-ratio) is being actively worked on in [Chrome](https://bugs.chromium.org/p/chromium/issues/detail?id=1045668) and [Firefox](https://bugzilla.mozilla.org/show_bug.cgi?id=aspect-ratio).
This CSS should eventually supersede `layout=responsive`. In the meantime, the proposal is to reimplement `layout=responsive` via `aspect-ratio` CSS where it's available.
See [demos here](https://dvoytenko.github.io/aspect-ratio-css/).
## Implementation brief
On the surface, the implementation is trivial:
```
if (layout == 'responsive') {
if (CSS.supports('aspect-ratio: 1 / 1')) {
element.style.aspectRatio = `${width} / ${height}`;
} else {
// The current code that injects a fake element.
}
}
```
The situation is a lot more complex with AMP optimizer because there's no way to confirm the `aspect-ratio` CSS support on that level. This is still TBD, but one approach we can take:
```
@supports(aspect-ratio) {
.i-amphtml-sizer-responsive {
display: none !important;
}
}
```
In this approach, the optimizer will add both: new and legacy markup and we will control which one is used on the client side using the `@supports()` CSS.
## Motivation
First, the `aspect-ratio` CSS layout is designed to be more universal. The `layout=responsive` is implemented via a fake element with the `padding-top: {height/width * 100}%` hack. This hack only works for bound-width case, such as normal block flow or flex-row layout. It doesn't work correctly for bound-height (e.g. flex-column) layouts and bound-width-and-height (`position:absolute`) layouts. `aspect-ratio` CSS will eventually support all three use cases.
Second, the `aspect-ratio` CSS layout will work better with out CSS constraints such as `min-width` and `max-height`.
Third, it's expected to be faster, since no fake elements are injected. In fact, eventually, `aspect-ratio` CSS will require no JS involvement at all. This would be a big benefit to CLS metric.
Fourth, in the Bento world, the fewer fake elements are injected the better. This is because any fake element will be visible to the user script and can confuse its behavior.
## Launch
The following steps are necessary for launch:
- [x] Implement client-side support for a "raw" page.
- [x] Implement client-side support for an optimized page.
- [x] ~Implement client-side support for "intrinsic" layout.~
- [ ] Implement optimizer support.
/cc @ampproject/wg-approvers
Contributor guide
Assessment
This issue has not been assessed yet.