My CSS Wishlist

Photo by Austin Ban on Unsplash

My CSS Wishlist

Feb 19, 2023·

4 min read

Maybe a few weeks late to the party, but better late than never. Today I will talk about the things I wish CSS had.

CSS has been getting so many awesome features lately, and some of the items on this list are already being worked on, while others should totally be achievable in the near future. But just for fun, I will also include a few stretch goals that might only be possible with some magic wand 🪄.

Arbitrary mixins

What I mean by this is basically Sass mixins. I want to be able to include any arbitrary set of declarations or rules inside another rule. This arbitrary CSS could also come from a different file.

@import url('./utils.css') mixins(visually-hidden);

.skip-to-content:not(:focus, :active) {
  @apply visually-hidden;
}

We're kinda getting there with style queries, but the problem is that a container cannot query itself so the "trigger" needs to be set on the parent element.

Visually hidden

Sure would be nice if I didn't have to define an esoteric set of declarations for hiding content visually while keeping it accessible to assistive technologies.

.skip-to-content:not(:focus, :active) {
  display: visually-hidden;
}

Scoping

I talk about this one a lot. Scoping is one of the essential features missing from CSS currently. Naturally, this leads to developers (including me!) coming up with their own hacky ways to manage scoping.

The good news is that @scope is being worked on, even if it's a little confusing. The most interesting bit there is that it allows defining a lower boundary (aka CSS donuts).

🪄 The dream would be to extend native CSS module scripts (and constructable stylesheets) to behave more like non-native CSS modules so that the classes can be referenced in JavaScript or HTML. One of the challenges here is that this needs to also work at build time (outside the browser) for optimal performance.

import sheet from './styles.css' assert { type: 'css' };
const styles = sheet.scopedClasses;

const App = () => /*html*/`
  <div class=${styles.wrapper}>
    <span class=${styles.inner}>hi</span>
  </div>
`;

Auto color contrast

I want to be able to dynamically find colors that sufficiently contrast with the background. There are ongoing discussions about a color-contrast() function, and some version of it is even implemented in Safari TP.

.foo {
  background: var(--bg);
  color: color-contrast(var(--bg) vs white, black);
}

But as I understand, this feature is currently blocked because the WCAG contrast algorithm is not perfect. Very unfortunate, because this is something that can be easily achieved at build time - CSS variables only exist at runtime. Can I just have the "imperfect" version in the meantime and switch to a better algorithm when it's available? 🥺

SVG-in-CSS

We can use svgs from a url in a background-image, but we can't change its fill. To change the fill, we need to do the whole dance of using mask with background-color, …which is a lot. And it's not perfect, as we don't get granular control over the paths inside the svgs.

Wouldn't it be nice if we could just use svgs inside CSS and do whatever we want with them, including inline CSS variables? 🪄

.icon[data-icon=sun] {
  --_fill: orange;
  background: svg('<svg fill="var(--_fill)" viewBox="0 0 512 512"><path d="M256 118a22 ..."/></svg>');
}
.icon[data-icon=moon] {
  --_fill: wheat;
  background: svg('<svg fill="var(--_fill)" viewBox="0 0 20 20"><path d="M17.39 15.14A7.33..."/></svg>');
}

Animateable display

First we got animateable grid, so the natural next step is to be able to animate between height: 0 and height: auto. Why not go one step further and let us animate to/from display: none?

Static variables

Custom properties are extremely powerful, but they are just properties, which means they have many limitations, such as not being able to use outside style rules.

What if we could have a less powerful (and therefore more flexible) version of variables, similar to Sass? We'd be able to use them anywhere, including inside strings and media queries. 🪄

__mobile: calc(500 / 16 * 1rem);

@media (width > __mobile) { ... }

Tooltips

It shouldn't require a delicate contraption of precisely authored HTML+CSS+JS to make a damn tooltip. The challenge here is to make it show in the top-layer (which traditionally requires portaling the markup out near the root) and pin it to a reference element (which requires JavaScript to calculate position) and adjust the position when near the edge of the viewport (which requires even more JS).

Maybe 2023 will be the year of CSS anchor positioning which addresses all of these issues.

Double slash comments

To end on a lighter note, as a frequent Sass user, I often find myself writing // double slash comments even in vanilla CSS files. I'm sure there is a technical, parsing-related reason why this cannot be made to work, but it certainly would be nice. 😅


Other wishlists