CSS Wishlist for 2025

The new year is bringing out plenty of folks blogging about their CSS wishlists. It’s fun! I love thinking about the future of CSS capability, particularly now when CSS seems to be moving so fast. I’m going to make my own list by listing some of my own wishes, then linking up other people’s ideas who I agree with (from any year).

Stuff That Doesn’t Exist Yet

Adam Argyle: Pick Where to Stick

Layout with position: sticky; doesn’t let you be as specific as you might want to be with what parent element it’s going to stick against. Aside from other issues where it’s weirdly easy to break the stickiness, I agree it would be nice to just say where you want it to stick:

For that all too common moment when you want to pick which element position sticky will respect. What if we could use container-name or something and reference it from position sticky by making it a function?

Personally, I’d want the same thing for position: fixed;. I think it’s a bit annoying that you can only use it relative to the viewport and not a specific parent container.

Me: Unlimited Pseudo Elements with More Placement Options

Why do we only get ::before and ::after? I’m sure there are historical discussions you could dig up, but whatever happened, that’s how it was specced out. Feels a little arbitrary to me, like if someone decided functions in JavaScript could only have two arguments. What if it matched the great API that is insertAdjacentHTML and we had ::beforebegin, ::afterbegin, ::beforeend, and ::afterend? That would be nice. Even better, no particular limit to them, like ::afterbegin(n) which would allow us to add as many of these as we like. After all, they help us keep non-content elements out of HTML, which is typically A Good Thing™.

Ryan Trimble: Promoting Elements to the Top Layout without Popover

A massive reason to use the popover attribute to create native popovers is that you don’t have to fiddle with z-index and stacking contexts and such. If it’s open, users will be able to see it, because it’s promoted to what’s called the “top layer”. This is an amazing feature! I can imagine how careful the specs need to be to prevent it from being just another thing that’s easy for authors to screw up, but I can also imagine opening up this superpower to more than the handful of things that happen to use it today.

Me: An extend() Function

The concept of “extend” (in my mind) comes from Sass. It means: make this selector have the same styles as this other selector. Maybe it could remain an at-rule in CSS that looks like a function?

/* somewhere in any loaded CSS */
.special-title-style {
  paint-order: stroke fill;
  -webkit-text-stroke: 6px #b39ddb;
  text-shadow: -1px -1px 0 white;
}

/* somewhere else in CSS */
#matching .what .the .CMS [gave-me] {
  @extend(.special-title-style); /* NOTE: not real yet */
}Code language: CSS (css)

This would be helpful when you have less control over the HTML. Like you both don’t want to wrestle control over what the CMS is outputting (because that’s technical debt) and you don’t want to bend your CSS system to the whims of the CMS either.

Sass has @extend() and it’s sometimes called an anti-pattern, but that’s largely because it can produce ultra-verbose CSS that you might not even be aware of, which would not be a problem in native CSS.

Rachel Andrew: Regions & Reading Flow

With grid and flexbox we were given the power to easily reflow and reorder elements in ways that very much do not match whatever the current languages natural flow is (e.g. left to right and top to bottom). This can be an accessibility issue where the source order, and thus typically the tabbing order, doesn’t match the visual order, which can confuse people and/or lead to awkward screen-jumping.

There is a draft for reading-flow that Rachel explains:

The property aims to solve the issue where the source (and therefore tab) order of a page gets disconnected from layout when using CSS grid layout or flexbox. This is a problem I’ve been talking and writing about for a long time. As soon as I realized this problem existed when using grid, I felt as if we were giving people potential with one hand but then removing it with the other. I’m very happy that we’re now fixing that problem.

Yes please.

The rule reading-flow: grid-rows in this demo would make assistive tech read how it looks (4, 2, 3, 1) rather than what the source is (1, 2, 3, 4).

At the risk of sounding lazy, I’d want to do html { reading-flow: make-it-all-correct; } — that is — just not worry about moving around the order of things, make a browser heuristic in charge of making the tab ordering logical.

Me: image-set() with Container Size Breakpoints

I just ran across this the other day so I figured I’d put it on my list. I had a container where I wanted to swap out the background-image at different container widths. Container queries can do this by writing a container queries that override the background-image, but it occurs to me that we could do it in a more concise image-set() declaration if that were to be allowed.

.card {
  container: card / inline-size;

  .card-banner {
    background-image: image-set(
      /* Not real... yet */
      "small.jpg" container(width < 500px)
      "large.jpg" container(width >= 500px)
    );
  }
}Code language: PHP (php)

Sarah Gebauer: :local-link

The pseudo-class :local-link is a selector which targets links that point to the same web site. At the moment it’s not supported by any browser.

That would be cool. I wonder if people had easier access to style same-website links differently easily, they would be less quick to target="_blank", which I’m of the opinion you should only do in rare and specific circumstances.

Roman Komarov: Shrinkwrapping

There is one old, yet unsolved, CSS problem: shrinking containers to fit the content when it automatically wraps.

When an element wraps, the width becomes as wide as the container. But that feels/looks silly sometimes when the new now-wrapped content doesn’t occupy all that space.

Me: Be able to style the handle on resizeable elements

See those little line nuggets in the bottom right? I think they are ugly and I want to style them.

Not to mention I might want to move or resize them, potentially bettering the UX.

Geoff Graham: Mixins

A mixin is like a function, only the returned value is always style rules.

The deal is that we can use utility classes almost as little CSS snippets to build out other style rules and maintain a clearer separation between markup and styles.

@mixin --sr-text {
  position: absolute;
  left: -10000px;
  top: auto;
  width: 1px;
  height: 1px;
  overflow: hidden;
}

header a:first-child {
  @apply --sr-text;
}Code language: CSS (css)

I’ll note that style queries are really close to mixins in my mind, which actually have some support already.

Me: Trim Text from the Middle

Let’s say you want output:

/styles/setup/colors.scss

But you only have ~15 characters to do it in. We have text-overflow (‘n’ friends) now to truncate it to something like:

/styles/setup...

But that could be awful as the entire file name is being truncated away. There is a wild CSS trick to truncate it from the other side, but I’d prefer something less hacky. And even better, we should be able to do that truncation from the middle instead of an edge. I think it would be nice to get something like:

/styl...lors.scss

Styling Grid Gaps and Cells

It’s to hard to style the gaps between grid columns and rows. Just want a 1px line between all the columns? There are ways, but nothing just easy and side-effect-free. For that matter, it could be argued it shouldn’t be necessary to put an HTML element into a grid cell in order to style it. That would be nice to do in CSS alone.

The “Want Better Support” List

A random() Function

There is a working draft for this already done. So I suppose this is more of a waiting game.

There are plenty of design choices that benefit from a degree of randomness. Random dots on a grid, random movements, random timings…

Which of these animations runs first? What if you didn’t have to decide, you could just randomize it each run? Would it benefit from randomized delays, durations, or easings?

If we try generate the random number, with, say, a CSS processor, that randomness is only calculated once and won’t feel particularly random across users and page loads.

What’s less clear to me about this runtime version of randomness is how often it will be calculated. Like if you did div { height: random(100px, 200px); }, and that selector matched 50 <div>s, would each of them have a random height or would all 50 of them have the same height, even if that height is randomly calculated. Or if you used random() within a @keyframe animation that infinitely animates, would the value be re-calculated each iteration? I suspect it’s stuff like that which makes it something browsers don’t want to jump on implementing until they have very clear answers.

Eric Meyer: margin-trim

Trim off the leading block margin on the first child in an element, or the trailing block margin of the last child, so they don’t stick out of the element and mess with margin collapsing.  Same thing with block margins on the first and last line boxes in an element.  And then, be able to do similar things with the inline margins of elements and line boxes!  All these things could be ours.

I really want this as it seems to come up for me a lot. That is, this kind of thing…

.card {
  padding: 1rem;
  
  :first-child {
    margin-block-start: 0;
  }
  :last-child {
    margin-block-end: 0;
  }
}Code language: CSS (css)

Those extra selectors are easy to forgot and feel a bit fragile to me. I’d rather write:

.card {
  padding: 1rem;
  margin-trim: block;
}Code language: CSS (css)

The margin-trim property is already in Safari so let’s go. My thinking on this boils down to if you set padding in a direction on an element, margin-trim in that same direction.

While we’re talking about trimming, Jason Bradberry’s Why I’m excited about text-box-trim as a designer deserves a shout-out on this list.

The “ui” font families everywhere

The most popular and well-supported of these is system-ui and I see plenty of that on the web already. It amounts to being able to use the San Francisco on modern Macs, Segoe on Windows, Roboto on Android, and the list goes on… generally matching what font the operating running the browser uses. I think that rules. But it doesn’t have to be the only one — and isn’t — in the spec. There are more like:

ui-serif
ui-sans-serif
ui-monospace
ui-rounded

Those don’t have to map to anything, but it’s sure nice if they do. They do in Safari on Mac and I kinda love it.

Safari (Demo)

This is a big wish as it’s not something that browser makers can just do. It requires, like, computer makers to agree and ship appropriate fonts that then map to these. I guess that’s why we call it a wishlist.

Eric Meyer: Expanded attr() Support

Example from Eric:

td {
  width: attr(data-size em, 1px)
}Code language: CSS (css)
<td data-size="5"></td>Code language: HTML, XML (xml)

Yep. Love that. Part of what I like is that it moves some design information over to the HTML in a way that doesn’t need to be entirely prescribed right there. For example, setting data-color="red" gives you a lot more CSS opportunity to fiddle with than style="color: red;" does. Not to mention an easier way to back out of the support for it in the future which inline styles do not offer.

To be clear, attr() “works” now, the values you get out are just strings, not “typed”, so you can’t use them to set things like colors and sizes like you might expect you can.

Ahmad Shadeed: State Queries

Ahmad has made good points over the years about being able to style things when in certain states. Like applying styles when a flexbox container has elements that are wrapping (vs when it’s not).

.section-header {
  container-type: style flex-wrap;
  display: flex;
  flex-wrap: wrap;
}

@container style(wrap) {
  /* do the things you should do when the flex items are wrapped. */
}Code language: CSS (css)

Similarly, and this is a big one I’ve heard a million times, styling a sticky element only when it is stuck. I put this one in the “better support” section as there is actual movement on this.

.page {
  container-name: sticky-header;
  container-type: sticky;
}

.site-header {
  position: sticky;
  top: 0;
}

@container state(stuck: top) {
  .site-header__bottom {
    display: none;
  }
}Code language: CSS (css)

Custom Media Queries

There is a draft with this in it, but it’s never seem to come to be.

This doesn’t work:

:root { --mobile: 35em; }

@media (min-width: var(--mobile)) {
  /* non-mobile styles go here */
}Code language: CSS (css)

The draft syntax was like this:

@custom-media --narrow-window (max-width: 30em);

@media (--narrow-window) {
  /* narrow window styles */
}Code language: CSS (css)

But alas, nothing but this hack.

Style Queries that Support More Than Custom Properties

We actually have some support for style queries already, but all they can do is test custom properties. Example from Una:

@container style(--theme: warm) {
  .card {
    background-color: wheat;
    border-color: brown; 
    ...
  }
}Code language: CSS (css)

Above, if --theme matches the value warm (anywhere), then the nested styles will get applied to the relevant container. But we don’t have access to styling information generally to query against. Like this:

@container style(background: black) {
  a {
    color: white;
  }
}Code language: CSS (css)

Perhaps that’s not an amazing example, but being able to write styles that apply themselves based on arbitrary other styles on a container would be powerful.


What’s on your CSS wishlist?

Wanna learn CSS from a course?

One response to “CSS Wishlist for 2025”

  1. pd says:

    So, if this list is anything to do by, in 2026 we still won’t have a style able select.

    Surely dozens, maybe hundreds, of new features have been delivered over decades and all of you lot in the web development intelligentsia love to push for more of them with wish lists like this.

    Meanwhile, fundamental failures like the pathetic state of select styling is absent from your lists but constantly tops requested features in developer surveys.

    What? It’s being fixed? No! No it’s not! It’s not fixed or being fixed until it’s fixed!

    There’s an extreme dearth of pressure on browser developers to get this feature done. Thus is never been done.

    Pull your fingers out, intelligentsia!

Leave a Reply

Your email address will not be published. Required fields are marked *

Did you know?

Frontend Masters Donates to open source projects. $363,806 contributed to date.