Search code examples
csscss-selectorscss-transitionspseudo-class

Why does it matter which selector (“elem:hover” vs. “elem”) a CSS transition gets applied to?


I’m not even sure how exactly to phrase this question, so let me try to put it into some code:

Suppose I have a div element that I want to animate, so I give it two styles:

#myElement {
  width: 100px;
  height: 100px;
  background: red;
}
#myElement:hover {
  width: 150px;
  height: 150px;
  background: green;
  transition: 1s;
}
<div id="myElement"></div>

Why does it matter which style I apply the transition property to?

If I apply it to the default style, everything works correctly, the transition works both ways, when it changes state from default to hovering, and vice-versa. But when I apply it to the :hover instead, it only works from default to hover, but not the other way, it just jumps back instantly.

Why does this happen, what are the semantics of the transition property? (And is semantics even the right term here?)

If it was: “Whenever changing from this state to another, apply the transition.” Why is the transition also happening from hover to default when applied to default only?

And it can’t be ”Whenever changing to this state from another, apply the transition.” because then it wouldn’t work from default to hover.

So what is it?

Is there some kind of inheritance going on?

I found plenty of resources on how to apply a transition, syntax etc., but I couldn’t find anything where this behaviour is explained.


Edit: I guess I was too focused on the transition property and didn't look into "inheritance" for pseudo classes. So if I put the transition into the default state, :hover inherits it. Also I somehow thought it would only be in the :hover state once the transition is completed, which is wrong. Here is a different scenario, without "inheritance" if anyone is still confused: https://jsfiddle.net/xu6Lsexr/1/

Thanks for clarifiying this for me!


Solution

  • But when I apply it to the :hover instead, it only works from default to hover, but not the other way, it just jumps back instantly. Why does this happen, what are the semantics of the transition property?

    This has nothing to do with any “semantics of the transition property”.

    Whatever styles you define for #myElement:hover get only applied when the element is in the hover state, whereas whatever you define for #myElement gets applied in both states, the “normal” state of the element, and the hover state.

    So if you put transition into the first rule with selector #myElement, the element has that property in both states — whereas if you put it in the second one, it has it only in the hover state.

    A simple example to show you that this has nothing to do with the transition property itself:

    #foo {
      font-size: 20px;
    }
    #foo:hover {
      background-color: red;
      border: 1px solid;
    }
    
    #bar {
      background-color: red;
      font-size: 20px;
    }
    #bar:hover {
      border: 1px solid;
    }
    

    Now, #foo will have red background color only when hovered, whereas #bar has red background color in both states … and it’s the same thing with transition, or any other property.