Codementor Events

CSS Animation Toggle

Published Apr 26, 2020
CSS Animation Toggle

This article was originally posted on my website.


Before You Read

This is a work in progress, you might encounter typos or worse.οΉ£ Read at your own risk. πŸ˜„

TLDR

Use the :not() pseudo class for the alternate state. Toggle the *--closed class to switch between states.

.bottom-nav__list--closed {
    animation: close-nav 1s forwards;
}

.bottom-nav__list:not(.bottom-nav__list--closed) {
    animation: open-nav 1s forwards;
}

The Story Behind

On the mobile view of my website, I have a bottom navigation helper. It facilitates jumping through the sections of the homepage. I wanted it to be animated both on opening and closing it.

In the past, I tried changing the CSS class when toggling a UI element, and it's never been a great success. This time I had the idea of using the :not() selector for the same. It worked like a charm!

What Does NOT work

We might think that something like this would work, ie. adding the close animation to the base class.

.bottom-nav__list {
    animation: open-nav 1s forwards;
}

But it will simply do nothing. πŸ€·β€β™‚

What's A BAAD Idea

A bad idea is to try switching between classes, ie. an --opened and a --closed class.

Reason #1 οΉ£ What's The Difference? πŸ€·β€β™‚

Disclaimer: πŸ’― opinionated.
It's confusing. Let me explain.
When you debug the code in the browser, you will see the class list flash. Only the close or open will have changed.

<!-- opened state -->
<button ... class="bottom-nav__toggle bottom-nav__toggle--opened" ... >
</button>

<!-- closed state -->
<button ... class="bottom-nav__toggle bottom-nav__toggle--closed" ... >
</button>

Only four letters have changed. Even the count is the same! πŸ€¦β€β™‚

Note that this method could be favoured for a few reasons.

  1. It is (or seems) more maintainable as more explicit with the two classes.
  2. Easier to understand for beginners, no need to know the :not() selector.
  3. It is easier to extend: you can add another state by following the same pattern.

All that being said, here's the simple reason why I prefer the :not() method.

Reason #2 οΉ£ "Nothing" Is Better

I know, it's the same as Reason # 1, we're just presenting the other side. πŸ™„

See the code below for the :not() method: the whole second class is missing!

<!-- opened state -->
<button ... class="bottom-nav__toggle" ... >
</button>

<!-- closed state -->
<button ... class="bottom-nav__toggle bottom-nav__toggle--closed" ... >
</button>

IMHO it is much better: the difference is VISUAL! πŸ‘€
At a glance, I can tell whether the modifier class is applied or not.
No need for me to squeeze my eyes and focus hard to be sure which class is applied. οΉ£ Yes, I am lazy. A good dev is lazy anyways. It's an occupational hazard. πŸ€·β€β™‚ (πŸ™‰)

Live Examples

I've put together codepen demos of each approach.
Using the not() pseudo class: https://codepen.io/cedpoilly/pen/JjYNbKB
Swapping modified classes: https://codepen.io/cedpoilly/pen/XWmRNNZ

Closing

You've been brave enough to read this whole blah blah (unless you've cheated οΉ£ that's baaad, really bad; worse that the --opened & --closed method, how dare you πŸ’’), and you have two ways to switch between the two CSS animations. πŸ‘

Now go code something.

...

Okay, go now.

...

Bye!

...

Hey! Happy coding! ✌

Discover and read more posts from Cedric Poilly
get started