Sean LeBlanc
Sean LeBlanc

Reputation: 586

CSS transition disabled by `display:none`

I'm having an issue which seems to be preventing CSS transitions from playing on an element which is simultaneously changing from display:none.

In the following example, the divs have identical CSS, except that hovering over the first one hides the other two. The second div is hidden using visibility:hidden, and the third is hidden using display:none.

When you mouse over the first div, the behaviour is as expected: the first div transitions and the other two are hidden. When you mouse out, the behaviour is different from what I would expect: the first div transitions back to normal, the second div is unhidden then transitions back to normal, but the third div is unhidden and still in the normal state.

I was expecting for the third div to match the behaviour of the second and also be unhidden, then transition back to normal.

div{
  width:100px;
  height:50px;
  background:red;
  
  border-radius:50%;
  
  transition: border-radius 1s;
}

#hover:hover, #hover:hover ~ div{
  border-radius:0%;
}

#hover:hover ~ #hide1{
  visibility:hidden;
}

#hover:hover ~ #hide2{
  display:none;
}
<div id="hover">hover me for transition</div>
<div id="hide1">I transition back</div>
<div id="hide2">but I don't</div>

Since the second div works as expected, it's fairly easy to come up with alternate solutions using visibility:hidden and some positioning CSS, but is it possible to accomplish this in just CSS using display:none? If not, why does display:none affect other transitions in this way?

Note: This seems like something that would be easy to find, but my searches only turned up questions about attempting to transition the display property itself, not its side-effects on other transitions.

Upvotes: 9

Views: 2414

Answers (4)

misterManSam
misterManSam

Reputation: 24692

A simple explanation of display: none:

Turns off the display of an element (it has no effect on layout); all descendant elements also have their display turned off. The document is rendered as though the element did not exist.

(Emphasis mine)

The transition is not triggered because it was never started. The div was removed completely on hover and returned in its initial state with border-radius: 50%.

Workaround

The only possible way to achieve this affect with display: none using just CSS is to use an animation that will be triggered each time the display: none div appears.

div {
  width: 100px;
  height: 50px;
  background: red;
  border-radius: 50%;
  transition: border-radius 1s;
  animation: display 1s;
}
#hover:hover,
#hover:hover ~ div {
  border-radius: 0%;
}
#hover:hover ~ #hide1 {
  visibility: hidden;
}
#hover:hover ~ #hide2 {
  display: none;
}
@keyframes display {
  0% {
    border-radius: 0;
  }
  100% {
    border-radius: 50%;
  }
}
<div id="hover">hover me for transition</div>
<div id="hide1">I transition back</div>
<div id="hide2">but I don't (unless I have an animation)</div>

Upvotes: 8

NickyTheWrench
NickyTheWrench

Reputation: 3230

No, you cannot use display:none;

Reason:

When using display:none; - The element will be hidden, and the page will be displayed as if the element is not there. So when you hover over it - the element is totally removed...and border-radius:0%; never gets applied. When you hover away - the element shows immediately as the css tells it to - with border-radius:50%;

visibility:hidden; hides an element, however the element will still take up the same space as before. The element will be hidden, but still affect the layout.

Upvotes: 0

Rohit Chopra
Rohit Chopra

Reputation: 567

div{
  width:100px;
  height:50px;
  background:red;
  border-radius:50%;
  transition: border-radius 1s;
}

#hover:hover, #hover:hover ~ div{
  border-radius:0%;
}

#hover:hover ~ #hide1{
  visibility:hidden;
}

#hover:hover ~ #hide2{
  visibility: hidden;
}
<div id="hover">hover me for transition</div>
<div id="hide1">I transition back</div>
<div id="hide2">but I don't</div>

This will work. On mouse out third div also have transition.

Upvotes: -3

Morteza QorbanAlizade
Morteza QorbanAlizade

Reputation: 1550

You just can use transition for numerical properties in CSS, So you should use opacity and transition: all 1s to do this:

div{
  width:100px;
  height:50px;
  background:red;
  
  border-radius:50%;
  
  transition: all 1s;
}

#hover:hover, #hover:hover ~ div{
  border-radius:0%;
}

#hover:hover ~ #hide1{
  visibility:hidden;
}

#hover:hover ~ #hide2{
  opacity: 0;
}
<div id="hover">hover me for transition</div>
<div id="hide1">I transition back</div>
<div id="hide2">but I don't</div>

Upvotes: -1

Related Questions