Reputation: 586
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
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%
.
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
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
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
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