Some Imaginary CSS

Written by Tyler Sticka on

The other day I was using CSS grid and custom properties to solve some problems that would have seemed almost impossible only a year or two ago. This made me wonder: What CSS could I be writing in a few years that might seem far-fetched today?

Just for fun, I went through some of my recent CSS files and re-wrote portions using fictional CSS features I wish existed. Then I asked a few of my capable Cloud Four crew to help me illustrate some of those ideas.

As far as I know, none of these examples are real as of this writing… they are purely flights of fancy!

Container Queries

This is the most requested missing CSS feature, and I continue to find use cases with each and every project. Here’s a simple one: Only round an element’s corners when it’s narrower than the full viewport width.

.card:media(width < 100vw) {
  border-radius: 0.5em;

A wide viewport with rounded cards beside a narrower viewport with full-width, non-rounded cards

Illustration by Paul Hebert

Content-Aware SVG

Plugins like PostCSS Inline SVG have made me pine for a future where SVG is as much a first-class citizen of our presentation as it is our content.

@svg icon-star {
  content: url("/icons/star.svg");
  stroke: currentColor;
  stroke-width: 0.125em;

.icon-star {
  background-image: icon-star;

Align to Typeface Median

vertical-align: middle aligns an element with the baseline of text minus half its x-height. This makes it a poor fit for glyph-sized elements like icons, which will always look a tad too low. Ideally we’d have a property that would align with the middle of the typeface’s cap height instead.

.icon {
  vertical-align: text-middle;
The text 'Favorite' accompanied by a heart icon repeated twice, the first aligned with the x-height, the second with the cap height

Borrow Scroll Behavior from Document

It’s easy to make child elements scroll independently of the document. But it would be nice to easily allow “fullscreen” elements like modals and menus to take over as the document’s primary scrolling element. {
  overflow: document;

Click/Touch Target Sizing

Making elements large enough for our fingers can be more challenging than it seems. It’d be swell if we could manipulate the interactive area via CSS!

.button {
  pointer-box-offset: 0.5rem;

A touch target extends past the visual boundaries of a button element within a web page

Illustration by Danielle Romo

Pseudo Elements Between Siblings

Horizontal navigation patterns like breadcrumbs often include visual separators between each segment. While there are several ways to style these separators via CSS (using pseudo elements and adjacent sibling selectors, for example), a surprising number of websites still hard-code vertical bars or other text characters right in their HTML.

Maybe what we need is a simpler way to inject content between adjacent elements instead of just before or after?

.breadcrumbs > *::between {
  content: "▸";
  margin: 0 2ch;

Breadcrumb navigation with small arrows between each link

Illustration by Danielle Romo

Easily Style Form Affordances

It feels a little silly that we can’t just override <select> arrows and similar details without obliterating them entirely.

select::expand {
  content: url("icons/arrow-down.svg");

A mosaic of various styled select dropdown arrows

Illustration by Paul Hebert

Optical Margin Alignment

Something I always miss from my graphic design days is the ability to automatically align quotation marks, uppercase “T” characters, etc. slightly past the box margin so they appear more visually balanced.

body {
  text-align: optical left;
Two examples of the same text passage, the right version showcasing optical margin alignment

Update: Amelia Bellamy-Royds helpfully pointed out that this may be partially addressed by the hanging-punctuation property. It’s only supported in Safari as of this writing, but it looks like a promising step!

Eased Gradients

Gradients can look pretty gnarly in browsers without some easing applied! Crossing my fingers that this eventually makes it into the CSS spec.

.example {
  background-image: linear-gradient(to bottom, cubic-bezier(0.455, 0.03, 0.515, 0.955), #456BD9, #F14CA3);

A gradient (from pink to blue) without easing on the left, and with easing on the right

Illustration by Arianna Chau
Tyler Sticka

Tyler Sticka is Cloud Four's VP of Design, allowing him to think about design systems every day. When he isn’t directing his team, sketching on sticky notes or nitpicking CSS, he enjoys reading comics, making video games and listening to weird music. He tweets as @tylersticka.

Never miss an article!

Get Weekly Digests


Pseudo-elements between items can currently be created as follows:

.breadcrumbs > *:not(:first-child)::before { ... }

Tommy Carlier


Thanks, Tommy! I have a slight preference for this selector (less specificity):

.breadcrumbs > * + *::before { }

I don’t see either technique used in the wild as often as I’d like, which is why I thought a simplified selector might help.

Nice! It would be simple to preprocess CSS containing a custom pseudo-element selector like *::--between to become * ~ *::before in the output, but if you wanted to work with something like that client-side browsers would toss out any custom pseudo-element selectors like that it found…but browsers will keep around any pseudo-element selector that begins with ::-webkit-, so it is very easy to support something like ::-webkit-between even in the browser with a very small amount of JS:

We recently made a class .comma, for comma-separated content, and we had to deal with ::empty elements if there were some. Decause if something went wrong, we had something like this: apple, orange, , banana. It would be great for CSS to handle it automatically

i am just thinking
line-height only when multilined
line: top bottom
line-height: 1 21px
when multilined then 2qpx otherwise just 1

i had this issue so many times to get icons and texts and height issues set when

icon + text

just exists

What about a opposite selector for “+” like “-” to select the previous element.
There are many uses for it.. one is a ‘glow’ of one list item, when you set the primary color on the hovered element and a slightly lighter color on the next and previous element.

For me it would be great to have sth like max-height: 5 lines;

I agree with everything you’ve said.

It would be nice to expose some basic scroll states to CSS. A use case would be to apply an overlay/arrow at the container edge to clue users in that something is scrollable.

.container::scrollable-x-start {
  ... Apply styles at start of scroll ...
.container::scrollable-x-end {
  ... Apply styles at end of scroll ...
.container:not(::scrollable-x-start):not(::scrollable-x-end) {
  ... Apply styles in between ...

Maybe a hex shorthand like #fa to represent #fafafa would be neat.

Also, we have relative height height: 100% that requires all parent elements to have it set as well. We have a viewport height height: 100vh. I think you know where I’m leading you since we’ve all ran into the issue of backgrounds abruptly stopping when scrolling. So why not a document height that is the entire length of the document, scrollbar and all with height: 100dh? I guess it’s easier said than done for them not to implement this annoyance by now.

I’d love to see a a value for display like contents but that would be truly transparent to css so that sibling and descendant selectors would apply to the effective visual tree.

Nice wishlist. Would love to see those implemented, specially some sort of container queries and better form styling.

Extending the clickable area of a button can be done with some hacks.

Is it fragile? yes. Is it hacky? definitely. Should you use it? gosh, please don’t. But it’s something.

Maybe there is one more desired pseudo-selector. We have now very handy position: sticky, but it lacks something like ::is-stuck

Let’s discuss your project! Email Us