{
    "archive_path": "archive/1792577119.294737",
    "base_url": "www.joshwcomeau.com/css/interop-2027",
    "basename": "",
    "bookmarked_date": "2026-10-21 10:05",
    "canonical": {
        "archive_org_path": "https://web.archive.org/web/www.joshwcomeau.com/css/interop-2027",
        "dom_path": "output.html",
        "favicon_path": "favicon.ico",
        "git_path": "git/",
        "google_favicon_path": "https://www.google.com/s2/favicons?domain=www.joshwcomeau.com",
        "headers_path": "headers.json",
        "htmltotext_path": "htmltotext.txt",
        "index_path": "index.html",
        "media_path": "media/",
        "mercury_path": "mercury/content.html",
        "pdf_path": "output.pdf",
        "readability_path": "readability/content.html",
        "screenshot_path": "screenshot.png",
        "singlefile_path": "singlefile.html",
        "warc_path": "warc/",
        "wget_path": "www.joshwcomeau.com/css/interop-2027/index.html"
    },
    "domain": "www.joshwcomeau.com",
    "extension": "",
    "hash": "12GKDRSVWZWSVE6X46DK",
    "history": {
        "archive_org": [],
        "dom": [],
        "favicon": [
            {
                "cmd": [
                    "curl",
                    "--silent",
                    "--location",
                    "--compressed",
                    "--max-time",
                    "120",
                    "--output",
                    "favicon.ico",
                    "--user-agent",
                    "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/118.0.0.0 Safari/537.36 ArchiveBox/0.7.4 (+https://github.com/ArchiveBox/ArchiveBox/) curl/curl 8.14.1 (x86_64-pc-linux-gnu)",
                    "https://www.google.com/s2/favicons?domain=www.joshwcomeau.com"
                ],
                "cmd_version": "curl 8.14.1 (x86_64-pc-linux-gnu)",
                "end_ts": "2026-10-21T10:05:20.802430+00:00",
                "index_texts": null,
                "output": "favicon.ico",
                "pwd": "/data/archive/1792577119.294737",
                "schema": "ArchiveResult",
                "start_ts": "2026-10-21T10:05:20.141609+00:00",
                "status": "succeeded"
            }
        ],
        "git": [],
        "headers": [
            {
                "cmd": [
                    "curl",
                    "--silent",
                    "--location",
                    "--compressed",
                    "--head",
                    "--max-time",
                    "120",
                    "--user-agent",
                    "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/118.0.0.0 Safari/537.36 ArchiveBox/0.7.4 (+https://github.com/ArchiveBox/ArchiveBox/) curl/curl 8.14.1 (x86_64-pc-linux-gnu)",
                    "https://www.joshwcomeau.com/css/interop-2027/"
                ],
                "cmd_version": "curl 8.14.1 (x86_64-pc-linux-gnu)",
                "end_ts": "2026-10-21T10:05:21.182168+00:00",
                "index_texts": null,
                "output": "headers.json",
                "pwd": "/data/archive/1792577119.294737",
                "schema": "ArchiveResult",
                "start_ts": "2026-10-21T10:05:20.811979+00:00",
                "status": "succeeded"
            }
        ],
        "htmltotext": [],
        "media": [],
        "mercury": [
            {
                "cmd": [
                    "/app/node_modules/@postlight/parser/cli.js",
                    "https://www.joshwcomeau.com/css/interop-2027/"
                ],
                "cmd_version": "1.0.0",
                "end_ts": "2026-10-21T10:05:35.360549+00:00",
                "index_texts": null,
                "output": "mercury",
                "pwd": "/data/archive/1792577119.294737",
                "schema": "ArchiveResult",
                "start_ts": "2026-10-21T10:05:28.713991+00:00",
                "status": "succeeded"
            }
        ],
        "pdf": [],
        "readability": [
            {
                "cmd": [
                    "/app/node_modules/readability-extractor/readability-extractor",
                    "/tmp/tmp44maw6so",
                    "https://www.joshwcomeau.com/css/interop-2027/"
                ],
                "cmd_version": "0.0.11",
                "end_ts": "2026-10-21T10:05:28.700196+00:00",
                "index_texts": [
                    "For the past few years, all of the major browser vendors (Google, Apple, Microsoft, and Mozilla, along with Igalia and Bocoup) have been working together on  Interop(opens in new tab), a project to improve universal browser support on web technologies. It\u2019s been a remarkably successful effort; when a focus area gets added to Interop, it often winds up reaching near-100% support across all major browsers within a year. \u2728\nCSS Subgrid is a good example. Subgrid is a super-powerful extension to CSS Grid which enables entirely new layouts. It was implemented in Firefox back in 2019, but there wasn\u2019t much movement with other browsers for years. It got added to Interop 2023, and by the end of that year, it was widely available across all modern browsers:\nThe Y axis shows the percentage of tests related to subgrid passing in each browser. The black \u201cInterop\u201d line shows tests passing in all browsers.\nAs we reach the end of 2026, Interop 2027 is currently being planned, and the team at Mozilla has created a ranking system(opens in new tab) for us to upvote our most-requested features. They plan on using the ranking data to decide what to include for next year\u2019s Interop!\nIn this blog post, I want to dig into the top 10 features I voted for, to offer a bit of a preview of what CSS might look like within the next year. There will also be some little tips and tricks you can start using today!\nLink to this heading1. CSS functions\nCurrent Browser SupportSupported in Chrome 155 and Edge 154Not supported in Firefox 157Not supported in Safari 27\nOne of the most exciting ideas is the proposal to add functions to CSS(opens in new tab):\n/* Define a function: */\n@function --gradient-to-transparent(--color, --direction: bottom) {\n  result: linear-gradient(\n    to var(--direction),\n    var(--color),\n    transparent;\n  );\n}\n\n/* Invoke it: */\n.elem {\n  background: --gradient-to-transparent(red);\n}\n\n/* \u2026which produces: */\n.elem {\n  background: linear-gradient(\n    to bottom,\n    red,\n    transparent;\n  );\n}\nIf you\u2019re familiar with JavaScript, this should feel pretty familiar. We define new functions with @function and specify the returned value with result.\nThere\u2019s so much cool stuff we can do with this. Personally, the use case I\u2019m most interested in is the ability to convert between polar and cartesian coordinates, a concept we use over and over in my Whimsical Animations course(opens in new tab):\n@function --translate-polar(--angle, --distance) {\n  result: translate(\n    calc(cos(var(--angle)) * var(--distance)),\n    calc(sin(var(--angle)) * var(--distance))\n  );\n}\n\n/* Move this element 100px at a 45\u00b0 angle: */\n.particle {\n  transform: --translate-polar(45deg, 100px);\n}\nThis feels pretty \u201cscience-fiction\u201d to me, but it\u2019s already implemented in Chromium browsers, and if it gets added to Interop 2027, I think there\u2019s very good odds that it could become widely available sooner rather than later!\nLink to this heading2. Bevels and squircles with corner-shape\nCurrent Browser SupportSupported in Chrome 155 and Edge 154Not supported in Firefox 157Not supported in Safari 27\nIn CSS, we can use the border-radius property to round off the edges of our DOM nodes to create rounded rectangles. This property effectively adds a quarter-circle to each corner, connecting the 4 straight sides.\nThe corner-shape property is an exploration of alternative ways to connect the 4 sides of our DOM nodes. It provides a handful of new options:\n\nWhen I first heard about this property, I was most excited about squircle. If you\u2019re not familiar, squircles are an alternative algorithm for generating rounded corners using superellipses. Apple has been making use of them for years because they produce smoother, gentler edges.\nThat said, after messing around with corner-shape for a while, I find myself using corner-shape: bevel a ton. It\u2019s great for creating video game / sci-fi UIs. Here\u2019s a little preview of a side-project I\u2019ve been working on, with tons of corner-shape: bevel:\n\nWe\u2019ve technically been able to do stuff like this with clip-path or masks, but unlike those features, corner-shape actually changes the shape of the border-box. This means that our borders, outlines, and box-shadows will correctly follow the altered corner shapes!\nAnd even though this property isn\u2019t available in Firefox/Safari (as I write this in October 2026), I think it\u2019s reasonable to start using it today. It\u2019s a perfect progressive enhancement!\nLink to this heading3. Infinite possibilities with border-shape\nCurrent Browser SupportSupported in Chrome 155 and Edge 154Not supported in Firefox 157Not supported in Safari 27\nIn addition to corner-shape, there\u2019s a separate proposal for  border-shape(opens in new tab), which is essentially a lower-level version that allows us to draw the border ourselves.\nI covered this property in depth in a recent newsletter issue, so I won\u2019t repeat myself too much here. To summarize, border-shape lets us create whatever border shape we want using straight lines, arcs, and B\u00e9zier curves.\nI used this property recently to draw this card with a big circular scoop at the top:\n\nLike corner-shape, this property changes the element\u2019s actual border box, so borders/outlines/shadows will trace it correctly. I drew the shape I wanted and then added a white border and black outline to achieve the effect shown above!\nWe can even animate between differnt border shapes, like I do in this clip:\n\nYou can learn a bit more about this property in my newsletter issue on the subject.\nLink to this heading4. Anchored Container Queries\nCurrent Browser SupportSupported in Chrome 155 and Edge 154Not supported in Firefox 157Not supported in Safari 27\nI recently published a blog post on Anchor Positioning, one of the most exciting modern CSS features (which was actually prioritized in Interop 2026, and is now widely available!).\nThe Anchor Positioning API allows us to anchor one element to another. For example, we might anchor a floating tooltip element to its trigger, so that no matter where that trigger is on the page, the tooltip will always be connected to it.\nIf you\u2019ve ever tried to solve this sort of problem yourself, you know it\u2019s surprisingly tricky. For example, we might want our tooltip to float above the anchor, but what if the anchor is near the top of the viewport?\nThis is a tooltip displaying additional information about this button.The tooltip fits comfortably.This is a tooltip displaying additional information about this button.The tooltip\u2019s getting cut off!\nThe original Anchor Positioning API gave us most of the tools needed to solve this problem easily in CSS. It allows us to specify fallback positions; if the target element doesn\u2019t fit above the anchor, it can flip automatically to the bottom.\nThe only thing missing was the ability to tell whether or not the target had flipped. We had no way to know, in CSS, whether the target element is currently sitting above or below the anchor, whether it\u2019s using the default or fallback position. For tooltips, this is a problem because we typically want to add a little protrusion that points towards the anchor.\nThe \u201cLevel 2\u201d version of the Anchor Positioning API includes a new type of container query that allows us to check whether the target element is using a fallback position or not. You can learn more about it in my Anchor Positioning blog post, or check out the Interop 2027 proposal(opens in new tab).\nLink to this heading5. CSS inherit() function\nSo honestly, I had never heard of this proposal(opens in new tab), and as far as I can tell, it isn\u2019t implemented in any browsers. It\u2019s not even listed on caniuse, so I can\u2019t display one of those little widgets!\nAnd yet, the moment I saw it, it became something I needed to have. \ud83d\ude02\nAs you might know, the inherit keyword in CSS allows us to pass a value down from the parent, even if that property isn\u2019t typically inherited:\n\nThis is a useful little trick to reuse values, but I frequently wind up discovering that it doesn\u2019t quite work. For example, suppose we have nested border radiuses (or is it radii?):\n\nIn order for nested border radii to look correct, we need to reduce the amount of rounding on the inner radius. So I don\u2019t exactly want to use the inherited value; I want to transform it.\nThat's where the proposed inherit() function comes in. It will pluck the inherited value and allow us to modify it using calc():\np {\n  border-radius: calc(inherit() - 4px);\n}\nGiven how preliminary this feature is, I\u2019d be a bit surprised if it makes the cut for Interop 2027. But I hope we do get this feature in the future! It seems super useful. \ud83d\ude04\n\nCurrent Browser SupportSupported in Chrome 155 and Edge 154Not supported in Firefox 157Not supported in Safari 27\nIn my blog post on scroll-driven animations, we explore how we can scrub through a keyframe animation by scrolling. For example, we can use it to fade an element in as it traverses the viewport:\n\nScroll-driven animations were part of Interop 2026(opens in new tab), and it\u2019s been successfully implemented across all browsers. In addition to Scroll-driven animations, however, there\u2019s a separate proposal for scroll-triggered animations.\nWith scroll-triggered animations, the goal is to trigger a keyframe animation when the user scrolls to a specific point, like a proximity sensor going off. At that point, the animation runs normally over a specified duration.\nWe can currently implement scroll-triggered animations using the IntersectionObserver API in JavaScript, but it\u2019s kind of a pain. It\u2019ll be super nice when we can use CSS for both scroll-driven and scroll-triggered animations, since they each have their own use cases.\nYou can learn more about scroll-triggered animations in this wonderful article by Bramus(opens in new tab).\nLink to this heading7. CSS reading-flow and reading-order\nCurrent Browser SupportSupported in Chrome 155 and Edge 154Not supported in Firefox 157Not supported in Safari 27\nI\u2019m currently working on a  which involves a dynamic grid-based layout. Items are arranged very differently on desktop vs. mobile:\nDesktop LayoutMobile Layout\nThis is one of the great things about responsive CSS, but it leads to an unfortunate side effect: tab order is always based on the DOM order, not the visual order. So, if someone uses assistive technologies to navigate between elements, that navigation order will always be the same, even as the layout changes dramatically depending on screen size.\nOn desktop, the first visual item is that list of Redacted on the left, but on mobile, the first item is that big red button. Whichever element comes first in the DOM will be the first item to receive focus, which will invariably be wrong for a percentage of our users.\nThankfully, the new reading-flow property grants us a solution to this problem, and there\u2019s a proposal for Interop 2027(opens in new tab).\nThe basic idea is that we can specify that the tab order should follow one of several visual orders:\n.grid {\n  display: grid;\n  reading-flow: grid-rows;\n}\nThere are values for both CSS Grid and Flexbox, and if you need even more control, the reading-order property allows us to create a custom order, sorta like tabIndex in HTML.\nThis property has been championed by one of my personal heroes, Rachel Andrew. You can read more about it in her blog post on reading-flow.\nLink to this heading8. Keyword size animations with interpolate-size and calc-size()\nCurrent Browser SupportSupported in Chrome 155 and Edge 154Not supported in Firefox 157Not supported in Safari 27\nA long-standing pain point on the web has been the inability to animate between keyword values like auto. The interpolate-size property solves this problem, and there\u2019s an Interop 2027 proposal(opens in new tab) for it, alongside the related calc-size() function.\nThe most common use case for this feature is to animate between height: 0 and height: auto, for creating collapsible accordion-type UIs:\n\nThe interpolate-size property is not yet supported in your browser. Here\u2019s what it looks like in supported browsers:\nThis is admittedly kind of a complex example, requiring other niche-but-well-supported CSS like transition-behavior. But the key thing is that interpolate-size: allow-keywords makes this sort of transition possible.\nThis proposal has been kicking around for a while now, and it\u2019s been implemented in Chrome since 2024, so hopefully it makes it into Interop 2027!\nAnd even though it isn\u2019t yet available in all browsers, we can start using it today as a progressive enhancement. Just be sure to gate the transition behind a @supports query, since otherwise a brief delay will be added to unsupported browsers.\nLink to this heading9. CSS gap decorations\nCurrent Browser SupportSupported in Chrome 155 and Edge 154Not supported in Firefox 157Not supported in Safari 27\nOne of the things that makes CSS Grid layout unique is that the grid children are positioned using rows/columns defined entirely in CSS. In every other layout mode, elements are positioned using other elements! In Table layout, for example, every grid cell has an associated <td> or <th> element.\nThere are a lot of upsides to CSS Grid, but one of the downsides is that it\u2019s not as easy to add borders between grid cells. If a grid cell is empty, there\u2019s no element to slap a border: 1px solid on!\nThe gap decorations proposal(opens in new tab) introduces a new set of CSS properties that will allow us to use a border-like syntax on the grid itself. Check this out:\n\nThe rule property is not yet supported in your browser. Here\u2019s what it looks like in supported browsers:\nLike border, the rule property is a shorthand property that allows us to specify the width, color, and style (dashed/dotted/solid) of the line. We can also use row-rule and column-rule if we only want to draw lines between each row or column.\n\n\nCurrent Browser SupportSupported in Chrome 155 and Edge 154Not supported in Firefox 157Not supported in Safari 27\nWhen working with position: sticky, have you ever wished there was a way to know whether the element was currently \u201cstuck\u201d or not? For example, maybe you\u2019ve wanted to change the background color of a sticky header when it becomes stuck to the top of the viewport.\nThis  proposal(opens in new tab) is for the implementation of a new type of container query, one that matches when a position: sticky element switches from its typical in-flow position to being anchored to the viewport. Check it out:\n\nHere\u2019s what this looks like, if this feature isn\u2019t yet supported in your browser.\n\nInterestingly, this new API isn\u2019t just for sticky positioning; we can use it to query all sorts of scroll-related state. For example, we can tell whether a scroll container is scrolled to the top/bottom, which can be useful for showing those scroll-indicating gradients:\n\nIf there's the ability to scroll up, scrollable: top matches, and so we reveal the pseudo-element floating over the top of the content. When scrolled all the way up, scrollable: top no longer applies, and so the gradient is hidden.\nHere\u2019s what this looks like in supported browsers:\nLink to this headingConclusion\nAs we head into Interop\u2019s 7th year, it's undeniable that the project has been a smashing success for the web. I\u2019m so glad they keep building on this success!\nI know it\u2019s kind of a weird time right now for web developers, and many of us are wondering whether we even need to care about this kind of stuff anymore. If we\u2019re delegating all of our work to LLMs, do we still need to keep up with the latest-and-greatest CSS features?\nPersonally, I think it\u2019s more important than ever. We can\u2019t expect LLMs to use modern CSS features when so much of their training data is years old. Most of the features I\u2019ve shared in this post can be used today as a progressive enhancement, and if history is any guide, many of them will soon be widely available.\nIf we want to build the best possible user experiences, we\u2019ll need to guide our agents to take advantage of modern web features, which requires us to know about them! This is something I dug into in a newsletter issue earlier this year: deep technical expertise remains incredibly worthwhile in the agentic era.\nFinally, I\u2019d strongly encourage you to rank your own top choices(opens in new tab)! There\u2019s a ton of great proposals in this list, including some exciting JavaScript APIs like Temporal which didn\u2019t make sense to include in this blog post.\nLast updated onOctober 20th, 2026# of hits"
                ],
                "output": "readability",
                "pwd": "/data/archive/1792577119.294737",
                "schema": "ArchiveResult",
                "start_ts": "2026-10-21T10:05:24.133145+00:00",
                "status": "succeeded"
            }
        ],
        "screenshot": [],
        "singlefile": [],
        "title": [
            {
                "cmd": [
                    "curl",
                    "--silent",
                    "--location",
                    "--compressed",
                    "--max-time",
                    "120",
                    "--user-agent",
                    "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/118.0.0.0 Safari/537.36 ArchiveBox/0.7.4 (+https://github.com/ArchiveBox/ArchiveBox/) curl/curl 8.14.1 (x86_64-pc-linux-gnu)",
                    "https://www.joshwcomeau.com/css/interop-2027/"
                ],
                "cmd_version": "curl 8.14.1 (x86_64-pc-linux-gnu)",
                "end_ts": "2026-10-21T10:05:24.123623+00:00",
                "index_texts": null,
                "output": "The Future of CSS \u2728 \u2022 Josh W. Comeau",
                "pwd": "/data/archive/1792577119.294737",
                "schema": "ArchiveResult",
                "start_ts": "2026-10-21T10:05:23.978226+00:00",
                "status": "succeeded"
            }
        ],
        "wget": [
            {
                "cmd": [
                    "wget",
                    "--no-verbose",
                    "--adjust-extension",
                    "--convert-links",
                    "--force-directories",
                    "--span-hosts",
                    "--no-parent",
                    "-e",
                    "robots=off",
                    "--reject=js,mjs,woff,woff2,ttf,otf,eot,mp4,m4v,mov,webm,ogv,mkv,avi,flv",
                    "--timeout=120",
                    "--restrict-file-names=windows",
                    "--page-requisites",
                    "--user-agent=Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/118.0.0.0 Safari/537.36 ArchiveBox/0.7.4 (+https://github.com/ArchiveBox/ArchiveBox/) wget/GNU Wget 1.21.3",
                    "--compression=auto",
                    "--timestamping",
                    "https://www.joshwcomeau.com/css/interop-2027/"
                ],
                "cmd_version": "GNU Wget 1.21.3",
                "end_ts": "2026-10-21T10:05:23.969473+00:00",
                "index_texts": null,
                "output": "www.joshwcomeau.com/css/interop-2027/index.html",
                "pwd": "/data/archive/1792577119.294737",
                "schema": "ArchiveResult",
                "start_ts": "2026-10-21T10:05:21.190772+00:00",
                "status": "succeeded"
            }
        ]
    },
    "icons": null,
    "is_archived": true,
    "is_static": false,
    "latest": {
        "archive_org": null,
        "dom": null,
        "favicon": "favicon.ico",
        "git": null,
        "media": null,
        "pdf": null,
        "screenshot": null,
        "singlefile": null,
        "title": "The Future of CSS \u2728 \u2022 Josh W. Comeau",
        "warc": null,
        "wget": "www.joshwcomeau.com/css/interop-2027/index.html"
    },
    "link_dir": "/data/archive/1792577119.294737",
    "newest_archive_date": "2026-10-21T10:05:28.713991+00:00",
    "num_failures": 0,
    "num_outputs": 6,
    "oldest_archive_date": "2026-10-21T10:05:20.141609+00:00",
    "path": "/css/interop-2027/",
    "schema": "Link",
    "scheme": "https",
    "snapshot_id": "abe924af-eaaf-4162-a9da-571d790ef0cf",
    "sources": [
        "/data/sources/1792577119-import.txt"
    ],
    "tags": null,
    "tags_str": "",
    "timestamp": "1792577119.294737",
    "title": "The Future of CSS \u2728 \u2022 Josh W. Comeau",
    "updated": "2026-10-21T10:05:20.140119+00:00",
    "updated_date": "2026-10-21 10:05",
    "url": "https://www.joshwcomeau.com/css/interop-2027/"
}