Imagine you have a list of items. Say, fruit: Banana, Apple, Orange, Pear, Nectarine. We could put those commas (,) in the HTML, but let’s look at how we could do that in CSS instead, giving us an extra level of control. We’ll make sure that last item doesn’t have a comma while we’re at it.
I needed this for a real project recently, and part of the requirements were that any of the items in the list could be hidden/revealed via JavaScript. The commas needed to work correctly no matter which items were currently shown.
One solution I found rather elegant solution is using general sibling combinator. We’ll get to that in a minute. Let’s start with some example HTML. Say you start out with a list of fruits:
<ul class="fruits">
<li class="fruit on">Banana</li>
<li class="fruit on">Apple</li>
<li class="fruit on">Orange</li>
<li class="fruit on">Pear</li>
<li class="fruit on">Nectarine</li>
</ul>
And some basic CSS to make them appear in a list:
.fruits {
display: flex;
padding-inline-start: 0;
list-style: none;
}
.fruit {
display: none; /* hidden by default */
}
.fruit.on { /* JavaScript-added class to reveal list items */
display: inline-block;
}
Now say things happen inside this interface, like a user toggles controls that filter out all fruits that grow in cold climates. Now a different set of fruits is shown, so the fruit.on
class is manipulated with the classList
API.
So far, our HTML and CSS would create a list like this:
BananaOrangeNectarine
Now we can reach for that general sibling combinator to apply a comma-and-space between any two on
elements:
.fruit.on ~ .fruit.on::before {
content: ', ';
}
Nice!
You might be thinking: why not just apply commas to all the list items and remove it from the last with something like :last-child
or :last-of-type
. The trouble with that is the last child might be “off” at any given time. So what we really want is the last item that is “on,” which isn’t easily possible in CSS, since there is nothing like “last of class” available. Hence, the general sibling combinator trick!
In the UI, I used max-width
instead of display
and toggled that between 0
and a reasonable maximum value so that I could use transitions to push items on and off more naturally, making it easier for the user to see which items are being added or removed from the list. You can add the same effect to the pseudo-element as well to make it super smooth.
Here’s a demo with a couple of examples that are both slight variations. The fruits example uses a hidden
class instead of on
, and the veggies example has the animations. SCSS is also used here for the nesting:
I hope this helps others looking for something similar!
Source: CSS-tricks.com