// css
We measured 18 modern web features on 600 real sites. :has() is at 50%, dialog at 3.8%
Support is documented everywhere. Actual use is not. We fetched the home pages of the Tranco top 600, read the served HTML and CSS, and counted what is really there - with the full method, the raw CSV, and the limits.
Whether a browser supports a feature is documented in a dozen places: MDN, caniuse, Baseline. Whether developers actually use it is documented far less often, and almost never in a form you can re-run yourself.
So we measured it. On 10 August 2026 we fetched the home page of the first 600 domains of the Tranco list W3779, read the HTML they served plus their linked stylesheets, and counted eighteen modern platform features by literal pattern matching.
The raw data, the summary and the collection script are deposited on Zenodo under DOI 10.5281/zenodo.21870382, CC BY 4.0. You can re-run the whole thing against any dated Tranco list.
What we found
Denominators first, because they decide what the percentages mean. 320 of the 600 domains returned HTTP 200; those are the basis for HTML features. 306 of those exposed at least one readable stylesheet; those are the basis for CSS features.
| Feature | Sites | Share |
|---|---|---|
| CSS custom properties | 250 | 81.7% |
aspect-ratio | 157 | 51.3% |
:has() | 153 | 50.0% |
srcset | 150 | 46.9% |
loading="lazy" | 137 | 42.8% |
fetchpriority | 100 | 31.2% |
<picture> | 92 | 28.8% |
type="module" | 74 | 23.1% |
text-wrap: balance | 65 | 21.2% |
color-mix() | 62 | 20.3% |
@container | 56 | 18.3% |
@layer | 32 | 10.5% |
subgrid | 32 | 10.5% |
<details> | 14 | 4.4% |
<dialog> | 12 | 3.8% |
CSS nesting (&) | 5 | 1.6% |
popover | 3 | 0.9% |
importmap | 2 | 0.6% |
The gap worth arguing about
:has() is on half the sites that answered. <dialog> is on 3.8%. Both have been available across modern browsers for a comparable stretch of time, so support alone does not explain a thirteen-fold difference.
One reading - which this dataset does not establish, and which we offer as a hypothesis rather than a finding - is that the cost of adoption differs enormously. Adding :has() means editing a stylesheet: nothing else in the page has to change, and if the rule does not match, nothing breaks. Adopting <dialog> means rewriting a modal component that already works, including its focus handling, its close behaviour and whatever library currently owns it. The second is a refactor; the first is a line of CSS.
The same shape shows up further down. @container at 18.3% and subgrid at 10.5% are additive - you can use them on one component and leave the rest alone. CSS nesting at 1.6% is not: authors who want nesting have had it in Sass for a decade, and the native version competes with a build step that already works.
popover at 0.9% and importmap at 0.6% are simply early. They are the two youngest features in this list, and this is what the bottom of an adoption curve looks like.
What this measurement cannot see
These limits are not caveats added for form. Each one changes how you should read the table.
- Only what is served. We read the bytes that come back from a single GET. Anything a framework injects after hydration is invisible to us, so client-rendered sites under-report on every HTML feature.
- Home pages only. A feature used on a product page and not on the home page counts as absent here.
- Declared use, not rendered use. A marker proves the code is present. A CSS rule may never match anything; a
<dialog>may never open. - Four stylesheets per page. Sites that split CSS across many files can be under-counted.
- Non-responders are excluded, not counted as zero. 280 domains did not return 200: 205 unreachable, 38 refused the request, 16 returned 404, the rest assorted. Much of that is the top of the Tranco list being DNS and CDN infrastructure that serves no web page at all.
- One run, one day. No trend is claimed here, and none can be read from a single snapshot.
Re-run it yourself
The point of publishing the script is that you do not have to take our word for any of this.
curl -sL "https://tranco-list.eu/download/W3779/1000000" -o tranco.csv
python3 web-feature-adoption.py --n 600 --out . Your numbers will differ from ours: sites change, and the sample is a live snapshot. If they differ a lot, we would rather know.