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.
If you even toggle the display property from none to block , your transition on other elements will not occur. To work around this, always allow the element to be display: block , but hide the element by adjusting any of these means: Set the height to 0 . Set the opacity to 0 .
display: none doesn't have a literal opposite like visibility:hidden does. The visibility property decides whether an element is visible or not. It therefore has two states ( visible and hidden ), which are opposite to each other.
display: none; does not remove or in anyway affect an element's DOM representation.
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>
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With