Things CSS Could Still Use Heading Into 2023

Just a couple of ideas! They came to me while I was poking around thinking of something to say for Alex Trost’s Holiday Mega-Stream (my segment starts here).

Styleable Resizers

Ya know how a <textarea> is resizeable by default?

That’s a nice default. If users are typing, they should have some control over how much space they have to do it. This type of resizing isn’t limited to <textarea>. You can make anything resizeable so long as it’s not an inline element and it has overflow: hidden;.

div.resizeable {
  overflow: hidden;
  resize: both;
}Code language: CSS (css)

There is also some degree of control. If the direction changes to rtl, the resizing happens from the bottom left (inline-start block-end) direction instead. You can scope the resizing to one direction with resize: vertical || horizontal — or turn it off with none.

What you can’t do is style it in any way. Well, you could position some element on top of it with pointer-events: none, but that’s a weak workaround that doesn’t, for example, affect the interactive area.

That’s too bad, as styling form controls has come a long way, and that’s essentially what this is. Lemme make that resizer match the other styling decisions on my site!

Most importantly, though, I want to be able to move and resize it. I’d like it if, say, I’m making a resize: horizontal element, that the entire inline direction edge is a drag handle. If this was possible it would reduce as much need for heavy JavaScript libraries that help with this.

It would be nice to make that entire orange bar a drag handle.

And speaking of resize: horizontal, shouldn’t resize: inline (and resize: block respectively) work?

That resize handle is a thing that appears in Shadow DOM, as best as I know. Just like number incrementers of a type="number" input, or the track and handle of a type="range" input. We have been able to reach in there to style things, but it’s always been fraught. See A Sliding Nightmare: Understanding the Range Input by Ana Tudor.

It may be that the standards organizations don’t want to specify Shadow DOM implementations, so the implementing browser has some freedom. But that’s putting browsers ahead of authors ahead of users. This is something that would make things better for users, and authors want to do it, so let’s put them over browsers.

CSS should be able to make a middle dragger bar like this.

Flowable Regions

With columns in CSS, you can make text that flows into multiple columns. But this comes with some pretty extreme limitations.

All the columns have to be of equal width, for one, and you can’t force an element across multiple columns naturally, which is awfully restrictive. Worse, you can’t tell the content where to flow after it “fills” the columns — the area either grows in height or overflows. A situation where a user needs to scroll down to read, then scroll back up to read the next column is unacceptable UX.

Now that we have strong grid layout, allowing content to flow naturally to a defined arrangement of elements placed on the grid would be very nice. I should be able to do this:

Magazine layout, with arrows on it indicating how a grid layout should flow.
Not hard to imagine this kind of thing as a web layout.

Circa 2014, Adobe took this up as a pet project. This was an absolutely perfect project for them, as doing this kind of thing in an app like InDesign is, well, the point of using an app like InDesign, which is used for just a massive swath of all design headed for printing.

Then the “father of CSS” swooped and pooped all over it with a bunch of arguments that I thought were dumb and bad then and I think are dumb and bad now.

It looks like the spec has been picked up as of 2021 again, and I love to see it.

#this {
  flow-into: my-flow;

#there {
  flow-from: my-flow;
}Code language: CSS (css)

Standardized Multi-Line Truncation

Did you know all browsers now support truncating text to a certain number of lines? I wouldn’t blame you if you didn’t because it needs all this code to work:

.line-truncate {
  display: -webkit-box;
  -webkit-box-orient: vertical;
  -webkit-line-clamp: 3;
  overflow: hidden;
}Code language: CSS (css)

That’s wild. That’s a very ancient flexbox syntax and an invented line clamping syntax all vendor-prefixed up, plus an awkward required bonus requirement (the hidden overflow) which has sucky side effects (sorry, no box-shadow for you!).

I’d prefer:

line-clamp: 3;Code language: HTTP (http)

Browsers can clearly do it! Make it easy!

Mixins & Extends

It would be nice to say hey selector, do all the same styling as this other selector. Sass does that like:

.some-selector {
  padding: 1rem;
  border: 1px solid black;
  border-radius: 5vmin;

.some-other-selector {
  @extend .some-selector;

/* Outputs like...
.some-selector, .some-other-selector {
}Code language: JavaScript (javascript)

The trouble with that is those selectors might be in very different places in the Sass, and what you are extending doesn’t necessarily have to match the same specificity, so there are some real source order and specificity challenges with it. The browser could do extends much more naturally, essentially embracing the hey selector, do all the same styling as this other selector spirit without all the awkward compromises.

Alternatively, mixins could be like this:

@mixin stuff-to-reuse {
  padding: 1rem;
  border: 1px solid black;
  border-radius: 5vmin;

.whatever {
  @include stuff-to-resuse;
}Code language: PHP (php)

With Custom Properties, we wouldn’t even really need to ability to pass in parameters to a mixin because you could use the selector scope for --whatever-you-want.

Weird twist… Style Queries will kinda be able to do this. Take that multi-line clamping idea… it could be done like this:

@container style(--clamp: 3) {
  .card {
    display: -webkit-box;
    -webkit-box-orient: vertical;
    -webkit-line-clamp: 3;
    overflow: hidden;

.random-element-with-a-card {
  --clamp: 3;
}Code language: CSS (css)

That feels a lot like a mixin to me. But I’d prefer a more direct syntax. I also think we essentially need either mixins or extends, probably not both.

Single-Line Truncation from Either Side

Apparently, truncation is on my mind. You can also truncate a single line. Also requires multiple properties:

.single-line-trucation {
  overflow: hidden;
  white-space: nowrap;
  text-overflow: ellipsis;
}Code language: CSS (css)

This time it doesn’t really bother me. Maybe dropping the overflow: hidden requirement would be nice, but having to stop the wrapping for single-line overflow is fair.

Here’s the problem, though: this will only trigger the ellipsis on the inline-end side of the element. You can’t tell it to truncate from the other side.

This matters, as what if the “important part” of the text is actually at the end? Like, say, a file path.

You can “trick” an individual element to truncate on the other side by reversing the direction, but, ehhh, that doesn’t seem like a good plan for text that isn’t actually in that direction (I gotta imagine there are bad accessibility implications to that).

Animate to Auto

You cannot truly smoothly animate from height: 0 to height: auto. This is a huge bummer as something like an accordion design pattern has arbitrary height content in the panels and should be able to contract to zero then expand out to “whatever the natural height is” in a consistently-timed and smooth way.

.this-should-just-work {
  height: 0;
  transition: height 1s;
.this-should-just-work[data-open] {
  height: auto;
}Code language: CSS (css)

There are poor ways around this, like animating max-height instead (no smooth ending, have to guess at sizing) or using JavaScript to animate instead. CSS should be able to do it. It can’t be that hard, right?!

Weirdly enough, there is a pure CSS trick today involving animating grid-template-rows. Here it is. Start with a wrapper to set the grid on:

<div class="content">
  <div class="inside">
    Totally arbitrary content! 
</div>Code language: HTML, XML (xml)

Then set it up like this:

.content {
  display: grid;
  grid-template-rows: 0fr;
  transition: 1s;
  overflow: hidden;
.content .inside {
  min-height: 0;
.content.expanded {
  grid-template-rows: 1fr;
}Code language: CSS (css)

So all you gotta do is toggle the class expanded on the parent wrapper there and it’ll work.

I was just messing around with this the other day when I noticed the “dynamic island” on iOS can morph to whatever needed size too, so I made a demo of that:





I work on CodePen! I'd highly suggest you have a PRO account on CodePen, as it buys you private Pens, media uploads, realtime collaboration, and more.

Get CodePen PRO

19 responses to “Things CSS Could Still Use Heading Into 2023”

  1. Sai Charan says:

    Cool! Didn’t know about auto height using grid. Thanks for sharing!

  2. Aaron says:

    Good ideas indeed. What I would love to see regularly would be two things nowadays:

    grid-track-selectors (e.g. :nth-track() )
    it would come handy to be able to style grid tracks or their children
    relative line-height unit
    For alignments it would be handy if there was a line-height-relative unit…e.g. this icon should be half the size of the current line.

    But overall it’s a really good time to be a web developer
    So much good stuff!

  3. This issue feels very relevant to the ellipsizing point

  4. Molly Stewart-Gallus says:

    There’s a weird mild overlap with ARIA wrt the separator role and the hr element

    Only tangentially relevant.

    Supposing HTML added a built-in element for separators beyond hr it would easy enough to give it the most appropriate role.

  5. I would love to see a CSS Regions revival but top of my wishlist is anchor positioning:

    Tooltips continue to be a mountain of frustration and JavaScript and I’ll be happy to see the day that stylistic problem is solved!

    Also really excited to play with CSS Toggles once they work out all the bugs!

  6. Martijn Frazer says:

    Here’s what I’d love to see in CSS or even HTML: native autogrowing textareas. Almost all elements automatically adjust their height based on their contents, but textareas don’t. I feel it’s a shame you have to enable this with hacky JS stuff. It would be a lot nicer if it’s a native thing supported by browsers directly.

  7. Konstantin R says:

    _All the columns have to be of equal width, for one, and you can’t force an element across multiple columns naturally, which is awfully restrictive. _

    Agree with you on that one.
    Although, you can ,kind of, use column-span: all; which might help in some cases.

  8. Martin says:

    Hey, big thanks for this article, especially the auto-height via grid-row.
    I modified your codepen to show some weird thing (showed by adding borders), which doesn’t prevent someone from using this but still feels buggy. Maybe you can have a look?

    As you can see, the inner border seems to have some easing so it’s absolutely not aligned with the outer one. My guess is that this is because of the “fraction” unit but i’m not sure…

  9. Steve says:

    What about full control over checkbox styling?

    Bugs me that I can’t set (what feels simple to me)… a background and border property to style a native element.

    Instead we have to apply a series of hacks and lose some built-in accessibility features.
    (Ditto for radio buttons)

  10. A random one that I’d love to see cleanly solved by CSS (without hacky and wonky workarounds) is the ability to set a background that is explicitly behind any other text/foreground content of a parent. Difficult to describe in words, but here’s a small codepen showing the problem, and an image mockup of what I’d love to be able to do.

    (and yes, people have replied to me ages ago with various possible hacks to achieve something similar … blend modes, etc … but this should be doable without any of that brittle stuff that then fails in different scenarios)

  11. Noam says:

    All super-good points, I hope they’ll be addressed in the upcoming years.

    I would also add CSS scoping, though I think this one is already in discussion.

  12. Sunspot says:

    The auto-height via grid-row rules!

  13. Ken Kunz says:

    Love the Animate to Auto grid-based solution!

    I recently had this scenario come up and had to use a semi-hacky JS solution. I tried replacing it with the grid solution. Seemed to work great … until I tested it in Mobile Chrome on Android. While it didn’t break anything, it also failed to animate. Our scenario is specifically for mobile navigation, so I decided it was best to keep the JS-based solution.

    Anyone else run into this?

  14. Chris Coyier says:

    This Article was mentioned on

  15. Wayne says:

    Do you think we can get something like nesting thru the new is() pseudo-class?

    BTW – I love nesting, its the #1 reason to love SASS. When I saw a video about is() it seemed like “nesting lite.”

  16. Andre says:

    I tested the autoheight grid thing for an accordion, but in Chrome the performance isnt really super smooth sometimes, seems to be CPU heady or something. And the is quite a bug in chrome wenn using padding inside?
    I made a codepen to reproduce, do i overlook something?

  17. Rhys Lloyd says:

    I remember getting excited by CSS regions and then wondered what happened to it. I remember reading that A List Apart article and thinking the arguments were pretty weak—I didn’t expect it to kill regions as it seemed to have.

    Some things just take too darn long! Looking at you container queries.

Leave a Reply

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

Back to Top ⬆️