Chrome 154 Takes Over Iframe Sizing and Carousel Semantics — Here's Where to Adopt It
Chrome 154, stable on September 22, 2026, adds frame-sizing so an iframe can match the height of the document inside it without a postMessage shim, plus links and tabs modes that give CSS scroll markers real WAI-ARIA roles. Both are Chromium-only today, and Google warns responsive iframe sizing can shift content and hurt Core Web Vitals.
Chrome 154 Takes Over Iframe Sizing and Carousel Semantics — Here's Where to Adopt It
Yes: as of Chrome 154, stable on September 22, 2026, an <iframe> can size itself to the height of the document inside it with one CSS property, and a CSS carousel can declare tablist, tab, and tabpanel semantics without you writing a line of ARIA. Neither feature is Baseline — frame-sizing and the new scroll-marker-group modes are Chromium-only for now — and Google's own documentation warns that responsive iframe sizing can shift content and damage Core Web Vitals. The correct move is feature-detected adoption: keep your postMessage shim as the fallback, turn the new pattern on where you control both documents, and leave anything that renders in the first viewport alone until you have measured it.
What actually shipped in Chrome 154
Two features in this release retire code that front-end teams have maintained for a decade.
Responsively-sized iframes. The embedding page sets the property:
.embed {
width: 100%;
frame-sizing: content-height;
}
The embedded document opts in from its own <head>:
<meta name="responsive-embedded-sizing" content="allow-origins=*">
That's the whole mechanism. The iframe box is derived from the embedded document's intrinsic size, so a comment thread, a form, or a long article inside the frame no longer needs a nested scrollbar. The accepted values are auto, content-width, content-height, content-inline-size, and content-block-size; for vertical growth in horizontal writing modes you want content-height or content-block-size, and you can still combine it with constraints such as max-height: 80vh.
CSS scroll marker modes. scroll-marker-group already generated the ::scroll-marker-group and ::scroll-marker pseudo-elements that turn a scroll-snap list into a carousel with dots. Chrome 154 adds a second keyword that decides what those dots mean:
/* links mode (default): activating a marker moves focus to the target */ scroll-marker-group: after links; /* tabs mode: group is a tablist, markers are tabs, targets are tabpanels */ scroll-marker-group: before tabs;
In tabs mode the generated group takes the tablist role, each marker takes the tab role, and the originating elements take tabpanel — the WAI-ARIA tabs pattern, produced by the browser from CSS you were going to write anyway.
The shim you can retire, and the one you keep
The iframe story is a straight replacement for a pattern that never should have needed postMessage in the first place.
Manual postMessage resize | Chrome 154 frame-sizing | |
|---|---|---|
| Who writes the code | Both documents | Parent CSS + one meta tag in the child |
| Dynamic content | Child measures and re-sends on every change | Child calls window.requestResize() after DOM changes |
| Cross-origin | Works, if both sides implement it | Works, gated by allow-origins |
| Failure mode | Resize loops, missed messages, stale height | Not supported → property ignored, fixed height stays |
| Browser support | All browsers | Chromium 154+ only today |
| Security surface | Message handlers you have to validate | Origin list next to CSP frame-ancestors |
The last row matters more than it looks. frame-ancestors answers "who may embed this document"; allow-origins answers "who may size me." They are complementary controls, and shipping allow-origins=* on a page that reveals sensitive layout information is the same mistake as an over-broad frame-ancestors. For a third-party widget, restrict the list to the origins that need it.
Two implementation details bite in practice. The meta tag cannot be injected after the embedded document has loaded — it has to be in the parsed HTML, which means adoption is owned by whoever publishes the embedded document, not by the page embedding it. And the browser does not continuously observe layout inside the frame: after content changes (more comments, an expanded panel), the embedded document must call window.requestResize() before layout. Google recommends exactly that ordering to avoid resize loops where a new height changes the viewport, which changes the content, which changes the height again.
The CLS trap
This is where the feature earns its warning label. Google's documentation states it plainly: responsive iframes may cause content shifts as the embedded document loads after the host document, and that can hurt Core Web Vitals when the iframe is in the first viewport.
The mechanics are unavoidable. The parent paints at some provisional height, the child document arrives and reports a taller intrinsic size, the parent re-lays out — and everything below the iframe moves. A shift triggered by input is excluded from CLS in the first 500 ms, but an embed that resolves a second after paint is counted in full, and it keeps counting every time the frame grows.
That is the same failure mode we covered in the overflow-anchor breakdown: the metric and the reading experience are not the same measure, and a layout that feels stable can still be scored badly.
Where to adopt, and where to wait
| Embed type | Recommendation | Why |
|---|---|---|
| Below-the-fold comments, forms, long-form widgets | Adopt now, feature-detected | Shift happens outside the first viewport; low LCP exposure |
| Same-origin content you control (docs, TOC, changelog) | Adopt with reserved space | You also control the meta tag and requestResize() |
| Above-the-fold embeds, hero media, chat bubbles | Hold | First-viewport shifts land directly in CLS |
| Third-party widget whose vendor hasn't shipped the meta | Keep the shim | Your page cannot opt in on their behalf |
| Video or fixed-ratio media | Do not use | Height should come from aspect-ratio, not content flow |
Ship it behind a feature query so the fallback survives:
.widget {
width: 100%;
height: 500px;
}
@supports (frame-sizing: content-height) {
.widget {
height: auto;
max-height: 80vh;
frame-sizing: content-height;
}
}
Carousels: the ARIA the browser now writes
The second feature is a continuation of an argument this blog has been making since we called for native HTML over ARIA: semantics belong to the platform, and hand-written ARIA is a maintenance liability. Chrome 154 extends that logic to carousels, which are the most commonly botched widget on the web.
The choice between the two modes is a semantic decision, not a styling one:
linksmode (default) behaves like a group of links — activating a marker moves focus to the target. Use it for pagination-style navigation through sections of content.tabsmode assigns the full tabs pattern:tabliston the group,tabon each marker,tabpanelon the content, with the focus order and keyboard behavior that assistive technology expects. Use it only when the content really is a set of panels.
Two cautions. Tabs mode removes non-selected panels from the active accessibility experience, so it is wrong for a carousel of independent links — misapplied, it hides content from screen reader users rather than helping them. And neither mode is Baseline: MDN lists scroll-marker-group as limited availability and experimental, with Firefox and Safari implementations still in progress. Your existing accessible carousel markup stays as the fallback; CSS markers are an upgrade path, not a replacement yet.
What this means for your compatibility process
Every major engine now ships every two weeks, and Chrome 155 is already scheduled for October 6. That cadence is exactly why version-number matrices stopped being useful: a feature that is Chromium-only today can be Baseline in three releases, or silent for two years.
So the process is the deliverable, not the feature:
- Feature-detect, never version-detect.
@supports (frame-sizing: content-height)and a"requestResize" in windowcheck are the only tests that matter. - Keep the old path until Baseline, not until it feels old. Both new features degrade by being ignored — a fixed-height iframe and a plain scroll container still work.
- Measure the embed, not the page average. Track layout shifts attributable to iframes separately; a page that passes on average can still have one badly behaved widget.
- Ask vendors the right question. For third-party embeds, "do you ship
<meta name=\"responsive-embedded-sizing\">?" replaces "do you have a resize script?"
Adopt the pattern where you own both sides of the frame, reserve space before you turn it on, and leave the ARIA you already wrote in place until the rest of the engines catch up.
Frequently Asked Questions
What is frame-sizing in CSS?
frame-sizing is a CSS property Chrome 154 applies to an <iframe> in the embedding page. Set to content-height (or content-inline-size / content-block-size), the iframe's box is derived from the intrinsic size of the embedded document, so the iframe grows with its content instead of showing an internal scrollbar. The embedded document must opt in with a <meta name="responsive-embedded-sizing"> element.
Does frame-sizing affect Core Web Vitals?
It can. Google's own documentation warns that responsive iframes may shift content when the embedded document loads after the host document, which can hurt Core Web Vitals when the iframe sits in the first viewport. Reserve space with a min-height or aspect-ratio, ship it below the fold first, and measure layout shifts before extending it.
Is frame-sizing supported in Firefox and Safari?
No. As of Chrome 154 the property is Chromium-only — caniuse shows it unsupported in Firefox 156 and Safari 27. Use @supports (frame-sizing: content-height) to keep your existing postMessage resize code as the fallback while support spreads.



