Google I/O, HTML-in-Canvas, and CSS Tricks You'll Actually Use

Published on 21.05.2026

motyl.dev<div></div></>FRONTEND

Google I/O 2026 and the "Agentic Web"

TLDR: Google used I/O 2026 to frame a sweeping narrative around what it's calling the "era of the agentic web," announcing 15 updates to Chrome and web platform tooling, with WebMCP and Modern Web Guidance being the standouts for developers.

The framing from Google is ambitious, maybe a bit breathless. They want agents to be first-class citizens of the web, not just scraping pages or clicking through forms, but interacting with structured APIs exposed directly by sites. WebMCP is the proposed standard that makes this concrete. It lets you expose JavaScript functions and HTML forms as tools that browser-based agents can call directly. The example Google floats is a travel planning workflow where instead of an agent tediously filling out flight search forms, it queries the backend API you've explicitly exposed. That's a real difference in reliability and speed.

An origin trial for WebMCP launched in Chrome 149, and Gemini in Chrome will support it soon. I'm watching this space carefully. There's a real tension between "make your site agent-friendly" and "give up control over how users interact with your product." Every exposed tool is a surface that can be called in ways you didn't anticipate, at scale, by automated systems. The security and rate-limiting implications alone warrant some deliberate thought before you start wiring up your app.

The other announcement worth noting is Modern Web Guidance, a set of expert-curated AI skills for coding agents that covers accessibility, performance, layouts, and more. It integrates with Baseline, so your agent knows which CSS features are safe to use for your chosen target. This is genuinely useful, not because AI can't write CSS, but because AI consistently writes CSS that works in Chrome and breaks elsewhere.

Key takeaways:

  • WebMCP proposes a standard for exposing structured site tools to browser-based agents, with an origin trial already running in Chrome 149
  • Modern Web Guidance provides vetted, Baseline-aware coding patterns for AI agents and is available now in early preview
  • Chrome DevTools for agents gives AI tools access to console logs, network traffic, and the accessibility tree directly

Why do I care: WebMCP is the kind of proposal that could go one of two ways. If it lands well, it genuinely improves agent-driven workflows by giving them structured interfaces instead of brittle DOM scraping. If it lands poorly, it becomes a vector for abuse and a maintenance burden. As someone who's thought a lot about API surface design, the discipline required here is the same as designing any public API, except now the "users" are non-deterministic AI systems. Get your error handling and input validation sorted before you opt in.

15 Updates from Google I/O 2026


HTML-in-Canvas: DOM Meets WebGL

TLDR: The HTML-in-Canvas proposal lets you render real DOM elements, with full CSS styling and accessibility intact, directly into a canvas element, then use that as a WebGL texture. It's experimental and flag-gated, but the potential is clear.

For years, if you wanted accessible, CSS-styled content, you stayed in the DOM. If you needed shader effects, post-processing, or 3D integration, you moved to canvas and lost everything the browser gives you for free: layout, accessibility, native text rendering. The HTML-in-Canvas proposal aims to close that gap. The API is small: a layoutsubtree attribute on the canvas, a drawElementImage() method, and a paint event. You put real HTML inside the canvas, render it with drawElementImage, and then use the canvas as a texture wherever you want it.

Vittorio Retrivi's exploration over at Codrops runs through four categories of use cases. The simplest is post-processing: take your hero section, render it into a canvas, apply a shader on top. The content stays in the DOM, crawlable and accessible, but visually it can have fluid distortion, rain effects, or a pixelation filter. The more interesting cases are the 3D ones. Three.js 184 already shipped HTMLTexture, a texture class built on this proposal, along with an InteractionManager that routes pointer events back from a 3D plane to the original DOM element. That means hover, focus, and input handling all work natively on a piece of HTML that's mapped onto the face of a 3D object.

There's an origin trial running now, and you can test it today by enabling chrome://flags/#canvas-draw-element in any Chromium browser. The workarounds that existed before this, html2canvas and SVG foreignObject, are genuinely limited. html2canvas explicitly documents that it will never support all CSS properties. foreignObject loses most accessibility information. This proposal keeps the browser's full rendering pipeline intact.

Key takeaways:

  • The API introduces layoutsubtree, drawElementImage(), and a paint event to bridge DOM and canvas rendering
  • Three.js 184 already has HTMLTexture and InteractionManager built on this proposal, with full pointer event forwarding
  • An origin trial is active; test it with chrome://flags/#canvas-draw-element

Why do I care: This changes the mental model for 3D web experiences. Right now, building UI for a WebGL scene means reimplementing layout primitives in shader code or reaching for libraries like uikit. With HTML-in-Canvas, you describe UI with HTML and CSS the way you always would, then hand it to the scene as a texture. The accessibility and SEO story is also much better than the alternatives. I'd start experimenting now even though it's behind a flag. The API shape looks stable enough to prototype against.

Exploring the HTML-in-Canvas Proposal


Better Fluid Sizing with CSS round()

TLDR: Ahmad Shadeed walks through how the CSS round() function, now well-supported across all browsers, can snap fluid sizing values from clamp() and container query units to predictable steps, giving you cleaner type scales and layout rhythms.

The problem with fluid sizing using clamp() and cqw units is that the computed values are arbitrary. Font sizes land at 19.7px, 27.4px, 143.2px. These values change smoothly, which is the whole point, but they never align to any design grid. If you want typography that snaps to a 4px baseline, you're out of luck without some manual intervention.

round() accepts a mode (up, down, nearest, or to-zero), the value to round, and an interval. Wrapping a clamp() expression like round(down, clamp(1rem, 1rem + 2cqw, 2rem), 4px) means the font size will only ever land on 16, 20, 24, 28px, and so on. That's composable with your spacing tokens and far easier to reason about. Ahmad also shows a more unusual technique: using round() with calc-size(auto, ...) to snap element heights to a layout grid baseline, something that was genuinely impossible before calc-size() existed.

Browser support is solid as of Baseline 2024. Chrome, Edge, Firefox, and Safari all support it. The function is part of a trio alongside mod() and rem(). The round-to-line demo in Ahmad's article is the kind of thing that used to require JavaScript to pull off, where you had to read computed heights and nudge elements programmatically. Now it's a single CSS expression.

Key takeaways:

  • round(mode, value, interval) snaps fluid values to predictable steps compatible with design tokens
  • Pair it with clamp() for fluid ranges that step cleanly rather than change continuously
  • Combining round() with calc-size(auto, ...) lets you snap auto-height elements to a baseline grid

Why do I care: I've been waiting for predictable fluid type scales without a JavaScript-driven tokenization step. round() is that, and it's already broadly supported. The practical application isn't just aesthetics. Snapping values to a grid reduces the number of unique sizes the browser has to calculate at paint time, which can reduce the number of layout recalculations at container query breakpoints. It's one of those functions that looks small but changes how you think about design-to-code translation.

Better Fluid Sizing with round()


Cross-Document View Transitions: The Gotchas Nobody Mentions

TLDR: A practical, experience-first guide through three common failure modes in cross-document view transitions: the deprecated meta tag that silently does nothing, a 4-second timeout that kills transitions without any visible error, and image distortion caused by the default object-fit: fill on transition pseudo-elements.

I've seen this pattern before. A web platform feature ships with initial documentation, the spec changes, old tutorials stay indexed, and developers waste hours debugging against a version that no longer exists. Cross-document view transitions are currently living that reality. The <meta name="view-transition" content="same-origin"> tag that half the tutorials still show was deprecated around Chrome 126 with no console warning. The current approach is a CSS at-rule:

@view-transition {
  navigation: auto;
}

That's the opt-in now. It lives in CSS, not HTML, which is actually an improvement since you can wrap it in a @media (prefers-reduced-motion: no-preference) block or scope it to specific viewport widths. Both pages need the rule for the transition to fire.

The 4-second timeout issue is the one that will burn you in production. Locally, your dev server responds in milliseconds and the transition works every time. In production, if your server is cold-starting a lambda or your CDN misses, the combined TTFB and render time can exceed the limit. The transition silently aborts. There's no console error unless you've wired up a pagereveal listener and are watching for TimeoutError on event.viewTransition.finished. The <link rel="expect" href="#hero" blocking="render"> approach described in the article is worth knowing about: it tells the browser to hold the snapshot until a specific element is in the DOM, giving you a controlled delay instead of a race.

The image taffy problem is the simplest fix once you know about it. The browser takes flat bitmap snapshots and by default stretches them between sizes with object-fit: fill. Two lines of CSS on ::view-transition-old(name) and ::view-transition-new(name) switching to object-fit: cover fixes it.

Key takeaways:

  • The <meta> tag opt-in is deprecated; use @view-transition { navigation: auto; } in CSS instead
  • A 4-second timeout silently kills transitions on slow pages; use a pagereveal listener to detect it
  • ::view-transition-old() and ::view-transition-new() default to object-fit: fill and need cover to avoid image distortion

Why do I care: Cross-document view transitions are the right answer for MPA page animations. No framework, no client-side router, just HTML pages and CSS. The gotchas described here are real and they're not obvious from the official documentation. This article covers the debugging workflow I want in my back pocket: the pagereveal listener pattern, the Animations panel in DevTools for slowing transitions down to 10% speed, and the pseudo-element tree to target. Worth bookmarking before you start a project that needs this.

Cross-Document View Transitions: The Gotchas Nobody Mentions


Browsers Treat Big Sites Differently (And That's Fascinating)

TLDR: Firefox and Safari ship domain-specific code that changes how certain websites render, fixing broken behavior at the browser level rather than waiting for sites to update. Chrome doesn't need to, because the web is largely built around Chrome's behavior in the first place.

This is the kind of post that reframes something you thought you understood. Open Firefox, type about:compat, and you'll see a list of live site-specific patches with toggles. Turn them off and watch sites break. Safari has a file called Quirks.cpp in its WebKit source that's thousands of lines of conditions like "if the user is on this domain, handle touch events differently." Facebook, Twitter, Netflix, Instagram, TikTok, Zillow, Amazon, SeatGuru. All with custom rendering paths.

The author's analysis of why Chrome doesn't have an equivalent quirks system is the most interesting part. It's not that Chrome is better engineered. It's that the web is built for Chrome. When developers test only in Chrome, they ship to Chrome's behavior. When those sites break in Safari or Firefox, WebKit and Mozilla engineers either add a domain-specific patch or let their users have a broken experience. The economics favor the patch. Filing a bug with a third-party company and waiting months is a losing proposition when you can ship a five-line workaround today.

Safari even ships a fake Chrome user agent string, ready to deploy for sites that serve a degraded experience to non-Chrome browsers. It's not just cosmetic either. There are quirks that change scrollbar rendering, touch event handling, viewport calculations, and image MIME type handling. The list keeps growing because the underlying dynamic is structural, not incidental.

Key takeaways:

  • Firefox's about:compat exposes all active site-specific interventions with live toggles; worth exploring
  • Safari's Quirks.cpp contains thousands of lines of domain-specific rendering fixes for major websites
  • Your site might already be in these files and you'd have no way to know unless you test regularly in non-Chrome browsers

Why do I care: The practical takeaway is blunt: test in Firefox and Safari regularly, not just before launch. If your site is in a quirks file somewhere, that patch isn't guaranteed to stay. WebKit engineers do remove quirks when sites fix their code. The post mentions a FlightAware quirk that was added and later removed after outreach succeeded. If a future browser update drops a workaround your site depends on unknowingly, users in that browser hit a regression you didn't cause but still own.

Browsers Treat Big Sites Differently


RTL Support Isn't Optional If You Have 600 Million Potential Users

TLDR: Evil Martians walk through two distinct RTL scenarios, one where only user inputs need to handle right-to-left text, one where the whole UI needs to flip, and show that the minimal fix in most cases is adding dir="auto" to text inputs and dir="rtl" to the <html> element.

The piece opens with a real bug from bolt.new: Arabic users typing prompts in an LTR input, getting garbled output because the browser doesn't know the text is right-to-left. The instinctive fix, using navigator.language to detect direction, doesn't work. navigator.language tells you the browser's locale setting, not the language of the content being typed right now. A user with a system set to ar-SA might type English. A user with an English system might type Arabic. The correct fix is dir="auto" on the input element. The browser inspects the first strongly-directional character and sets direction accordingly, updating in real time as the user types.

For full RTL interface support, the two-attribute fix scales up into a real architecture question. You put dir="rtl" on the <html> element for RTL locales and you audit your CSS for physical direction properties. margin-left becomes margin-inline-start. padding-right becomes padding-inline-end. text-align: left becomes text-align: start. These CSS Logical Properties have excellent browser support now and they express intent rather than physical position, which means the browser maps them correctly to whichever direction is active.

The two traps to watch for: icons that shouldn't flip (logos, stars, clocks) vs. directional icons that should (back arrows, chevrons), and flexbox containers where you actually want the visual order fixed regardless of reading direction, which needs direction: ltr explicitly. The Stylelint property-layout-mappings rule is a good guardrail to stop physical properties creeping back in on the next PR.

Key takeaways:

  • dir="auto" on free-form text inputs handles RTL text correctly without JavaScript or language detection
  • Full RTL UI support requires dir="rtl" on <html> and a CSS audit to replace physical direction properties with logical equivalents
  • CSS Logical Properties (margin-inline-start, padding-inline-end, etc.) are well-supported and should be default for new code

Why do I care: I keep seeing internationalization treated as a post-launch concern, something to handle "when we add language support." But the dir="auto" case isn't about internationalization in the full sense. It's about letting users type in their own language in an otherwise English product. That's table stakes for anything with a text input. The two-attribute fix the article describes takes less than an hour to ship and opens your product to hundreds of millions of people who are currently watching their text render backwards.

600+ Million People Write Right-to-Left: 2 Fixes Your App Needs