A shorthand for matching every class that starts with a given string has moved from idea to spec text. Lea proposed it in 2024, Bramus flagged its formal adoption, and it has now been added to the Selectors Level 5 draft.
/* Adding a base class */
.btn {
padding: 0.5rem 1rem;
border-radius: 4px;
}
/* Listing everything... yuck! */
.btn-primary,
.btn-secondary,
.btn-danger {
padding: 0.5rem 1rem;
border-radius: 4px;
}
/* Works, but performs badly */
[class^="btn-"],
[class*=" btn-"] {
padding: 0.5rem 1rem;
}
/* Newly resolved class prefix selector */
.btn-* {
padding: 0.5rem 1rem;
border-radius: 4px;
}
What changes in the selector
The syntax compresses what currently takes substring attribute matching into a single token. The class^="prefix" and class=*" prefix" forms work today, but they are verbose and read poorly next to .prefix-*. They also carry performance costs that Bramus cites as a main argument for the new selector.
The alternative — [data-attribute] selectors — avoids the substring matching but demands an extra pass over the markup and adds its own verbosity, so it isn't a clean substitute.
Two limits are worth knowing. The wildcard matches only the dashed form, leaving other conditions and non-dashed cases alone:
/* Nope */
.prefix* {}
.prefix-*-suffix {}
.prefix_* {} /* the door is left open on this */
And the spec currently implies, without stating outright, that the selector carries the same specificity as a plain class selector, (0,1,0) — which follows from .prefix-* being equivalent to .prefix-variation.
Adoption is the awkward part
Backwards compatibility cuts both ways. Nothing breaks for anyone who keeps using substring selectors, and those selectors keep their other uses. But because this is an addition rather than an upgrade to an existing feature, it isn't progressively enhanced from day one — shipping it today means guarding it:
@supports selector(.prefix-*) {
/* ... */
}
How long that guard stays necessary is unknown. If ergonomics are the whole pitch, then the waiting period spends exactly what the feature was meant to buy.
Brian Kardell's reply to the proposal raised the unease that comes with adding a second way to express an existing capability:
Yeah, I guess if we have a very specific case we can optimize it more than a general one, but I'm not seeing how this is a lot more specific than the version above which almost exists today. Feels like if we could optimize this we could optimize that. I'd be curious how it is optimized.
— Brian Kardell (@bkardell.com) 2026-08-20T15:43:02.158Z
The counterargument is precedent. Color functions were extended for brevity in much the same spirit:
/* old */
color: hsla(100, 50%, 50%, .5);
/* new */
color: hsl(100 50 50% / .5);
Where it reads well
Nesting is one place the shorthand earns its keep:
.prefix {
/* This would work, right? */
&-* { /* ... */ }
}
Web component authors have a stake too — Dave's request was for the selector to work against components:
Do custom-elements next!
— Dave Rupert (@davatron5000.bsky.social) 2026-08-20T15:36:16.326Z



