Notes

Group elements using only CSS

I wanted to group a list of posts by year for my blog. Due to templating constraints I had to find a way to do it with just CSS.


Luke Lowrey
Luke Lowrey
- 2 min read

Turns out, it is possible to group elements using just CSS - provided you have some control over the mark up. The way to do it is use the Adjacent sibling combinator CSS selector to detect when two adjacent elements are of the same group. MDN explains it way better than I can:

"The adjacent sibling combinator (+) separates two selectors and matches the second element only if it immediately follows the first element, and both are children of the same parent element."

What you need to do is hide the heading (or other repeated element) for every item where the previous item is of the same "group".

In this example HTML markup, each post has a year h1 tag and CSS class.

<article class="post post-date-2021">
    <h1>2021</h1>
    <a href="https://lukelowrey.com/ghostsolo-update-february-2021/">
        GhostSolo update (0.5.0) - February 2021
    </a>
</article>

<article class="post post-date-2021">
    <h1>2021</h1>
    <a href="https://lukelowrey.com/dotnet-email-guide-2021/">
        A complete guide to send email in .NET (2021)
    </a>
</article>

<article class="post post-date-2020">
    <h1>2020</h1>
    <a href="https://lukelowrey.com/github-action-dotnet-pr-validation/">
        GitHub Action - Build and Run .NET Tests on new pull requests
    </a>
</article>

<article class="post post-date-2020">
    <h1>2020</h1>
    <a href="https://lukelowrey.com/github-action-to-add-blog-posts-to-your-profile/">
        GitHub action to automatically add blog posts to your profile
    </a>
</article>

<article class="post post-date-2021">
    <h1>2021</h1>
    <a href="https://lukelowrey.com/ghostsolo-update-february-2021/">
        GhostSolo update (0.5.0) - February 2021
    </a>
</article>

<article class="post post-date-2019">
    <h1>2019</h1>
    <a href="https://lukelowrey.com/find-developers-to-hire-in-australia/">
        Where to find developers to hire in Australia
    </a>
</article>

Without CSS it looks like this:

So much waste!

By adding a CSS selector that targets every ".post-date-yyyy" class where the previous sibling element had the same class, I can hide the extra headings.

.post-date-2019+.post-date-2019 h1,
.post-date-2020+.post-date-2020 h1,
.post-date-2021+.post-date-2021 h1 {
    display: none;
} 

Now it looks like this! The extra headings are hidden to simulated grouped data.

Magic

See the full example https://codepen.io/lukencode/pen/NWbrPVX