Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
67 changes: 67 additions & 0 deletions content/blog/2025-10-24-better-coverage-ranges.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,67 @@
---
title: Can we have better CSS Coverage ranges, please?
excerpt: Browers often don't report atrule ranges correctly in the CSS Coverage ranges.
---

The last couple of months I've been working hard on improving how we can [inspect](/css-coverage/) what parts of CSS are used by the browser and which parts aren't. There's some stuff I'm doing to [make](https://github.com/projectwallace/css-code-coverage) large coverage reports so you can inspect several pages in one go by combining coverage JSON files into a single one, prettifying all the CSS etc. But there's one thing that is being consistently troublesome for me:

**Browers often don't report atrule ranges correctly.**

'Often' doesn't mean 'always', but more than enough that it has bitten me more than I care to admit. It depends on where in they live and whether neighbouring rules are covered. But take this example that I've created using Playwright's [coverage API](https://playwright.dev/docs/api/class-coverage#coverage-start-css-coverage), but I've observed this in Edge/Chrome as well:

```html
<!doctype html>
<html>
<head>
<link rel="stylesheet" href="http://localhost/style.css" />
</head>
<body>
<h1>Hello world</h1>
<p>Text</p>
</body>
</html>
```

```css
/* style.css */
@media all {
h1 {
color: green;
}
}
@supports (display: grid) {
h1 {
font-size: 24px;
}
}
```

Which parts do you think are marked as covered by the browser? The `@media all {}` rule? Or `@supports (display: grid) {}`. Well yes. No. Both. Neither. Let's look at what the browser/Playwright generates for this:

```js
let coverage = [
{ start: 7, end: 11 },
{ start: 14, end: 37 },
{ start: 50, end: 66 },
{ start: 69, end: 95 }
]
```

It doesn't mark the whole stylesheet as covered. Instead there are 4 different ranges. Let's highlight the bits that the browser says are covered, leaving out tabs and newlines for readability:

1. `all ` (Missing `@media ` and opening `{`)
2. `h1 { color: green; }`
3. `(display: grid) ` (Missing `@supports ` and opening `{`)
4. `h1 { font-size: 24px; }`

And both atrule ranges also miss their closing `}`.

## What I want

Can browsers please:

- Include the atrule name in the ranges
- Include the opening _and_ closing brackets (`{}`) in the ranges
- Be smart and then mark my example in a _single_ range covering the whole stylesheet

Thanks.
6 changes: 1 addition & 5 deletions src/lib/components/Markdown.svelte
Original file line number Diff line number Diff line change
Expand Up @@ -181,17 +181,13 @@
margin-right: 0.25ch;
margin-left: 0.25ch;
color: var(--highlight-name);
background-color: var(--bg-200);
}

:global(.markdown pre code) {
color: var(--fg-200);
}

:global(.markdown :is(p, li, figcaption) :not(pre) code::before),
:global(.markdown :is(p, li, figcaption) :not(pre) code::after) {
content: '`';
}

:global(.markdown aside) {
border: 2px solid var(--accent);
padding: var(--space-6) var(--space-5);
Expand Down
8 changes: 2 additions & 6 deletions src/lib/css/style.css
Original file line number Diff line number Diff line change
Expand Up @@ -391,16 +391,12 @@
line-height: calc(var(--leading-base) * 1rem);
}

p code {
:is(p, li) code {
display: inline-block;
margin-right: 1ch;
margin-left: 1ch;
color: light-dark(var(--accent-700), var(--accent-300));
}

p code::before,
p code::after {
content: '`';
padding-inline: .5ch;
}

[aria-selected='true'] {
Expand Down
Loading