126

Is there any way to do the opposite of :hover using only CSS? As in: if :hover is on Mouse Enter, is there a CSS equivalent to on Mouse Leave?

Example:

I have a HTML menu using list items. When I hover one of the items, there is a CSS color animation from #999 to black. How can I create the opposite effect when the mouse leaves the item area, with an animation from black to #999?

jsFiddle

(Have in mind that I do not wish to answer only this example, but the entire "opposite of :hover" issue.)

TylerH
  • 19,065
  • 49
  • 65
  • 86
Cthulhu
  • 4,449
  • 7
  • 42
  • 54
  • What exactly are you trying to do? Maybe there is a different alternative? – Moin Zaman Jun 12 '12 at 10:52
  • 17
    The opposite of `:hover` is quite simply `:not(:hover)`; however, `:hover` is *not* synonymous with `onmouseenter` nor is `:not(:hover)` the same as `onmouseleave`. CSS doesn't have any concept of DOM events. – BoltClock Jun 12 '12 at 10:53
  • When your mouse leaves the area, `:hover` ceases to be applied and returns to the previous style. So, the 'default' style is the equivalent of your 'mouse leave'. – Widor Jun 12 '12 at 10:53
  • @BoltClock can you explain further? – Cthulhu Jun 12 '12 at 10:54
  • 1
    @Cthulhu: `:hover` simply means "an element that has a mouse pointer over it". It doesn't indicate if the mouse pointer transitioned from another element to this element. It just means that the mouse pointer is currently on the element. – BoltClock Jun 12 '12 at 10:55
  • 1
    @BoltClock would :not(:hover) actually do anything be triggered at all? – Moin Zaman Jun 12 '12 at 10:59
  • 5
    @Moin Zaman: Yep. As long as your mouse isn't over a certain element, then `:not(:hover)` will apply. Here's a demo: http://jsfiddle.net/BoltClock/rghBX – BoltClock Jun 12 '12 at 11:01
  • Nice! I can think of few interesting things to do with that... – Moin Zaman Jun 12 '12 at 11:26

11 Answers11

108

If I understand correctly you could do the same thing by moving your transitions to the link rather than the hover state:

ul li a {
    color:#999;       
    transition: color 0.5s linear; /* vendorless fallback */
    -o-transition: color 0.5s linear; /* opera */
    -ms-transition: color 0.5s linear; /* IE 10 */
    -moz-transition: color 0.5s linear; /* Firefox */
    -webkit-transition: color 0.5s linear; /*safari and chrome */
}

ul li a:hover {
    color:black;
    cursor: pointer;
}

http://jsfiddle.net/spacebeers/sELKu/3/

The definition of hover is:

The :hover selector is used to select elements when you mouse over them.

By that definition the opposite of hover is any point at which the mouse is not over it. Someone far smarter than me has done this article, setting different transitions on both states - http://css-tricks.com/different-transitions-for-hover-on-hover-off/

#thing {
   padding: 10px;
   border-radius: 5px;

  /* HOVER OFF */
   -webkit-transition: padding 2s;
}

#thing:hover {
   padding: 20px;
   border-radius: 15px;

  /* HOVER ON */
   -webkit-transition: border-radius 2s;
}
Temani Afif
  • 180,975
  • 14
  • 166
  • 216
SpaceBeers
  • 12,834
  • 6
  • 43
  • 61
  • 1
    "(Have in mind that I do not wish to answer only this example, but the entire "opposite of :hover" issue.)" – Cthulhu Jun 12 '12 at 10:59
  • 2
    @Cthulhu - I've edited my answer now. That might help a bit more. I thought that was too obvious an answer. – SpaceBeers Jun 12 '12 at 11:07
  • +1 for pointing me in the right direction. I was having an animation discrepancy between browsers. Chrome was rendering everything smoother but I had a .1s different in transitions and Mozilla and IE were both displaying the error. I was able to fix it by matching up my transition numbers. – Termato Apr 07 '15 at 20:39
  • Ugh. The 'definition' of `:hover` you've quoted is from W3Schools, who are in no way an authoritative source. The actual spec can be found at http://www.w3.org/TR/CSS21/selector.html#dynamic-pseudo-classes, although it's not the most accessible explanation. – Mark Amery Jun 21 '15 at 16:38
24

Just use CSS transitions instead of animations.

A {
    color: #999;
    transition: color 1s ease-in-out;
}

A:hover {
    color: #000;
}

Live demo

Marat Tanalin
  • 12,887
  • 1
  • 32
  • 50
  • Like I said on the example, my issue is not with the animation, but with the "on mouse leave" part. – Cthulhu Jun 12 '12 at 10:53
  • 5
    Transition works both on mouse over and mouse leave. It's enough to specify styles for normal state and `:hover` state. – Marat Tanalin Jun 12 '12 at 10:54
  • How do you stop the transition at the instant when the webpage loads? – Cloud Walker Mar 12 '21 at 03:36
  • @CloudWalker Not sure what you mean. Transition cannot be stopped, it rolls back when the selector does not match anymore. – Marat Tanalin Mar 13 '21 at 15:16
  • For example, if you have a transition on text colour from black to white, then the instant the text loads, it changes from white to black(same duration as the transition duration). Not sure if this is an issue on my end. – Cloud Walker Mar 14 '21 at 04:40
  • @CloudWalker Are you talking about my live demo or about your own case? If the former, I cannot reproduce this: transition is not triggered on page load. If the latter, your page probably applies some transition-involving styles (e.g. via adding a class) on page load. – Marat Tanalin Mar 15 '21 at 17:55
5

The opposite is using :not

e.g.

selection:not(:hover) { rules }

Jared Wilber
  • 3,329
  • 20
  • 32
4

No there is no explicit property for mouse leave in CSS.

You could use :hover on all the other elements except the item in question to achieve this effect. But Im not sure how practical that would be.

I think you have to look at a JS / jQuery solution.

Moin Zaman
  • 24,413
  • 5
  • 65
  • 73
3

Put your duration time in the non-hover selection:

li a {
  background-color: #111;
  transition:1s;
}

li a:hover {
  padding:19px;
}
Dharman
  • 21,838
  • 18
  • 57
  • 107
2

You can use CSS3 transition

Some good links:

http://css-tricks.com/different-transitions-for-hover-on-hover-off/

http://www.alistapart.com/articles/understanding-css3-transitions/

SVS
  • 4,185
  • 1
  • 21
  • 28
2

Just add a transition to the element you are messing with. Be aware that there could be some effects when the page loads. Like if you made a border radius change, you will see it when the dom loads.

.element {
  width: 100px;
  transition: all ease-in-out 0.5s;
}
 
 .element:hover {
  width: 200px;
    transition: all ease-in-out 0.5s;
}
1

Although answers here are sufficient, I really think W3Schools example on this issue is very straightforward (it cleared up the confusion (for me) right away).

Use the :hover selector to change the style of a button when you move the mouse over it.

Tip: Use the transition-duration property to determine the speed of the "hover" effect:

Example

.button {
    -webkit-transition-duration: 0.4s; /* Safari & Chrome */
    transition-duration: 0.4s;
}

.button:hover {
    background-color: #4CAF50; /* Green */
    color: white;
}

In summary, for transitions where you want the "enter" and "exit" animations to be the same, you need to employ transitions on the main selector .button rather than the hover selector .button:hover. For transitions where you want the "enter" and "exit" animations to be different, you will need specify different main selector and hover selector transitions.

Govind Rai
  • 10,062
  • 7
  • 54
  • 74
1

Just add a transition and the name of the animation on the class inicial, in your case, ul li a, just add a "transition" property and that is all you need

ul li {
    display: inline;
    margin-left: 20px;
}

ul li a {
    color: #999;
    transition: 1s;
    -webkit-animation: item-hover-off 1s;
    -moz-animation: item-hover-off 1s;
    animation: item-hover-off 1s;
}

ul li a:hover {
    color: black;
    cursor: pointer;
    -webkit-animation: item-hover 1s;
    -moz-animation: item-hover 1s;
    animation: item-hover 1s;
}

@keyframes item-hover {
    from {
      color: #999;
      }
    to {
      color: black;
      }
}
    
@-moz-keyframes item-hover {
    from {
        color: #999;
      }
    to {
        color: black;
      }
}
    
@-webkit-keyframes item-hover {
    from {
        color: #999;
      }
    to {
        color: black;
      }
}

@keyframes item-hover-off {
    from {
      color: black;
      }
    to {
      color: #999;
      }
}
    
@-moz-keyframes item-hover-off {
    from {
        color: black;
      }
    to {
        color: #999;
      }
}
    
@-webkit-keyframes item-hover-off {
    from {
        color: black;
      }
    to {
        color: #999;
      }
}
<ul>
    <li><a>Home</a></li>
    <li><a>About</a></li>
    <li><a>Contacts</a></li>
</ul>
Stock Dave
  • 43
  • 1
  • 1
  • 7
0

You have misunderstood :hover; it says the mouse is over an item, rather than the mouse has just entered the item.

You could add animation to the selector without :hover to achieve the effect you want.

Transitions is a better option: http://jsfiddle.net/Cvx96/

Alex Chamberlain
  • 3,977
  • 2
  • 20
  • 48
0

The opposite of :hover appears to be :link.

(edit: not technically an opposite because there are 4 selectors :link, :visited, :hover and :active. Five if you include :focus.)

For example when defining a rule .button:hover{ text-decoration:none } to remove the underline on a button, the underline shows up when you roll off the button in some browsers. I've fixed this with .button:hover, .button:link{ text-decoration:none }

This of course only works for elements that are actually links (have href attribute)

scripter
  • 9
  • 3
  • Your information is incorrect. `:link` just selects links, as simple as that. Look here the definition of `:link`: https://developer.mozilla.org/en-US/docs/Web/CSS/%3Alink – Cthulhu Jul 07 '15 at 08:21
  • @Strive55 Ahhh, thanks, that makes sense. The link you gave states that "In order to appropriately style links, you need to put the :link rule before the other ones, as defined by the LVHA-order: :link — :visited — :hover — :active." If I understand it correctly, that means that if none of the other selectors apply (:visited, :hover, or :active) then :link is the one that applies. Not technically an opposite, because there are 4, but it still works – scripter Jul 12 '15 at 22:34