Maintaining CSS Style States using “Infinite” Transition Delays

Earlier today I discovered an interesting way to keep (store) a CSS style on an element using CSS transitions. This is probably best explained with an example, so here goes:

Live Demo

This text will only have the color while the button is pressed down.

This text will keep the given color even after the button is released.

As far as CSS only solutions go, there are two other tricks that can be used to achieve this similar behavior: using either the :checked or the :target pseudo selectors. In this post, I’ll show you my CSS transition technique used above, followed by a slightly cooler example that I’ve been working on.


<button class="red">Red</button>
<button class="green">Green</button>
<button class="blue">Blue</button>

  This text will only have the color while the button is pressed down.
<p class="perm">
  This text will keep the given color even after the button is released.


The prefixes below have been omitted for brevity.

/* The large delay prevents the color from changing */
p.perm {
  transition: color 0s 9999999s;

/* When a button is pressed, overwrite the transition property
   to remove the delay, so that we can instantly change the color */
.red:active ~ p.perm,
.green:active ~ p.perm,
.blue:active ~ p.perm {
  transition: color 0s;
.red:active ~ p {
  color: red;
.green:active ~ p {
  color: green;
.blue:active ~ p {
  color: blue;

The JavaScript

// Absolutely none

How It Works

It’s actually pretty simple. With our first CSS declaration, we’ve made it so that any changes to the color property will be delayed by approximately 116 days (

). This virtually infinite delay makes sure that the color stays the same once we’ve set it.

The trick now is to somehow temporary get around this delay, so we can apply the different colors with the buttons. This is done by overriding the transition property during the button press, setting the delay to 0. Now when we release the button, the old transition property will kick back in, setting the delay to 116 days. This will make sure that the text will keep the new color instead of going back to the default.

As far as I know, this only works with animatable properties, but a cool fact is that you can end a transition halfway through and have the property still keep the exact value that it had at that point in the transition. So for example, let’s say we have a linear transition from opacity 1 to 0 over two seconds, but only let it run for one second. The opacity value should now be stuck at 0.5 because the delay prevents it from going back. If we now were to run the opacity transition again, it would continue from 0.5 instead of starting over from the beginning.

Now, before you run off and start using this technique all over the web, keep in mind that this is a very dirty hack for achieving something with CSS that ideally should be done with JavaScript.

Taking it a step further

As I mentioned, I’ve been working on something cool to show this off, so make sure to check out this demo.

Last Updated on

Next Post: GraphProtocol: TS2322 null assignment in Subgraph →