You built a chat UI. Sticky composer at the bottom, position: fixed. On a phone the user taps the input, the on-screen keyboard slides up, and your composer sits under it. Or it does not. Or it does on one browser and not the other, and the layout viewport is a different height than it was two seconds ago, and half your app has scrolled itself into a corner. That behaviour, which used to be the browser's business alone, now has a knob. WebKit just wired it up.
The knob, and where it lives
The directive is interactive-widget, and it goes inside the same viewport meta tag you already have in every mobile page. Bramus confirmed the WebKit implementation on his blog and shows the exact shape:
<meta name="viewport"
content="width=device-width, initial-scale=1.0, interactive-widget=resizes-content">
Three values are defined. Each one answers the same question a different way: when a virtual keyboard (or any similar interactive UA widget) opens, which viewport should react?
Two viewports, one keyboard
Fast refresher, because the values only make sense against it. A mobile browser tracks two viewports on the same page. The layout viewport is what CSS resolves against, the box 100vh and your fixed elements pin themselves to. The visual viewport is the currently visible slice of that layout, which can shrink when the user pinch-zooms or when browser chrome eats into it. Historically the keyboard could shrink either, both, or neither, and the choice was the browser's.
interactive-widget moves that choice into the meta tag:
-
resizes-visualis the default. Only the visual viewport gets smaller. Your layout stays the same size; the keyboard just crops what the user can see of it. Fixed elements do not move. -
resizes-contentshrinks both viewports. The layout viewport becomes shorter for as long as the keyboard is up.100vhreports the new, shorter height. Fixed elements reflow against it. -
overlays-contentshrinks neither. The keyboard is drawn on top of the page and the layout is left alone, similar to what the Virtual Keyboard API'soverlaysContent = truegives you.
The default matches what Safari has always done and what Chromium switched to in Chrome 108, back in 2022, when the two engines aligned on "keyboard shrinks only the visual viewport" as the baseline. What is new is that a page can now opt out of the default in either direction.
Picking a value for a real layout
Think in mechanism, not vibes. The value you want is the one that keeps your positioning math honest while the keyboard is on screen.
If your UI is a normal document, an article, a form, a settings page, leave the default. resizes-visual means your CSS heights do not twitch, the user scrolls the field into view, and life carries on. Changing it here would break more than it fixes.
If your UI is a full-height app shell with a bottom-pinned toolbar (chat composer, note editor, camera controls), you probably want resizes-content. The layout viewport becomes shorter, 100vh reports the smaller height, and the toolbar you pinned to bottom: 0 sits above the keyboard instead of behind it. No JavaScript required, no manual measurement of the keyboard height, no listening for visualViewport.resize. You give up some layout stability, because a keyboard toggle now triggers a real reflow. That is the price for the layout you asked for.
If you are drawing your own chrome and want the keyboard to feel like a floating panel on top of the app, overlays-content is the honest answer. Nothing reflows; you take responsibility for whatever the keyboard is now covering, exactly as you would with the Virtual Keyboard API in overlay mode.
Three values, one line of HTML, and the layout algorithm follows.
The support caveat you should not skip
Two things to know before you ship it.
First, "WebKit implemented it" is not the same sentence as "Safari shipped it". Bramus makes the distinction explicit and says it is not yet confirmed whether the WebKit implementation will actually land in Safari. WebKit is the engine; Safari is one of the browsers that ships that engine, and features can sit in WebKit for a while before a Safari release picks them up. To try it today he had to build WebKit locally and run it in the MobileMiniBrowser shell on the iPhone Simulator, which is not a workflow you hand to users.
Second, since this is a viewport meta directive, an engine that has not implemented it will simply ignore the token and fall back to its own default behaviour. That is fine. You can add interactive-widget=resizes-content to your app shell today and it will do nothing on browsers that do not know the value yet, and start doing the right thing on the ones that do. Progressive enhancement, in the most literal sense.
Where this leaves mobile layout craft
The Virtual Keyboard API has been the JavaScript answer to this problem for a while, and it is still the right tool when you want to know the keyboard's pixel height and lay out around it. What interactive-widget gives you is the declarative, HTML-only version: one directive in the tag you already ship, no scripts, no measurements. The two overlap on the overlays-content case and diverge everywhere else.
The interesting part is what a second engine picking this up does to the shape of the problem. A keyboard-aware layout has always meant either trusting the browser or measuring with JS and crossing your fingers. A meta directive that both major engines respect turns the question into a design choice that lives next to your other viewport tokens. Now the work is picking which value your app actually wants, and watching whether Safari itself picks up the WebKit change.
Top comments (0)