14

The CSS transition property lets you animate on both hover-in & hover-out if you put the transition as below:

#inner{
    opacity:0;
    transition:opacity 2000ms;
}
#outer:hover #inner{
    opacity:1;
}

However, if the transition is moved to :hover state, it only happens on hover-in.

#inner{
    opacity:0;
}
#outer:hover #inner{
    opacity:1;
    transition:opacity 2000ms;
}

Is it possible to do the reverse, i.e. animate on hover-out only?

TylerH
  • 20,799
  • 66
  • 75
  • 101
user4150760
  • 2,739
  • 5
  • 18
  • 25

3 Answers3

17

Here's one way to achieve this (put a bogus property none for transition property in :hover):

#inner2{
    opacity:0;
    transition:opacity 2000ms;
}
#outer:hover #inner2{
    opacity:1;
    transition:none;
}

http://jsfiddle.net/j716sbav/4/

Answer updated to incorporate @BoltClock's suggestion. Putting none instead of a bogus property is definitely more elegant.

user4150760
  • 2,739
  • 5
  • 18
  • 25
  • 2
    While this works, the more "correct" way of doing this, so to speak, is to use `none` instead of a bogus property. Note that you can specify this using either the longhand `transition-property: none` or the shorthand `transition: none`. – BoltClock Jan 12 '15 at 14:53
8

If you prefer not to specify the transition property more than once, you can apply the transition to :not(:hover), but the caveat is that you need to swap all of the other declarations as well:

#inner2{
    opacity:1;
}
#outer:not(:hover) #inner2{
    opacity:0;
    transition:opacity 2000ms;
}

Either of these will work, but if you don't want to deal with confusing inversions, stick with overriding via transition: none.

Also note that CSS selectors represent states and not events, which means that it utilizes a :hover state rather than mouseover and mouseout events; however, a transition from :hover to :not(:hover) is essentially the CSS way of expressing a mouseout animation.

Community
  • 1
  • 1
BoltClock
  • 700,868
  • 160
  • 1,392
  • 1,356
1

I know this is a very old post but, as it came up in response to my Google search on the subject, I thought I'd post my solution.

After reading everything posted here, I found the simplest solution. Place a transition on the initial state as follows:

.btn {
  opacity:0;
  transition:0.6s;
}

.btn:hover {
  opacity:1;
  transition:0.8s;
}

So it has a transition time to the hover state and a transition time to the non-hover (ie normal) state. Saves a whole bunch of code.

bettsy
  • 11
  • 1