Reputation: 3997
I apply width-transition on a div element and the animation on it works perfectly. But providing height and width to the same div in CSS prevents the animation. What am I missing?
On hover, neither color nor animation changes. How do I provide common styling for all divs:
JS Fiddle sample here, and snippet here:
#div2 {
/*Un-commenting the below part, fails the animation assigned to this div
width:100px;
height:50px;
*/
-webkit-transition:width 3s;
background-color:blue;
}
div {
width:100px;
height:50px;
background:red;
color:white;
font-weight:bold;
-webkit-transition:width 2s;
}
#div1 {
-webkit-transition-timing-function: cubic-bezier(0, 0, 0.25, 1);
}
#div2 {
-webkit-transition-timing-function: cubic-bezier(0.25, 0.1, 0.25, 1);
}
div:hover {
width:300px;
color:black;
}
Upvotes: 1
Views: 168
Reputation: 3248
The issue you have is because of the selector's specifity. It's not really due to having a width
or height
, rather than they are in a rule that is more specific and thus has priority.
In your particular case, a rule with an ID takes precedence over a rule with an element (DIV
tag) and pseudo-selector (:hover
).
Lets consider first the case where the ID width
is commented out. the width
that will be used for div2
, the blue one, could come from these rules:
When the user is not hovering, the only rules to chose from get further reduced to:
And thus the browser picks that one, since the only one available. When the user hovers over the div, then we can choose between the 2 ones. Since the div:hover is more specific the browser chooses 300px for the value.
Let's see what happens when you un-comment width
in #div2
.
Now you have 3 rules to choose from.
When not hovering this gets reduced to
and from the two the one that is more specific and wins out is #div2
(you don't notice the difference because both have a 100px value).
When the user moves the cursor over the div and is now hovering, the browser gets to choose again from all 3 rules. This time the winner is not the ones you thought would win. Instead, #div2
wins over the other two, even the one with the :hover
pseudo-class, because it's more specific. That rule applies only to the element with ID div2
, and not to all div
s hovered on. So the value chosen for the width
is 100px again. Hence there's no visible animation. It's because the element doesn't get a different width value.
How to fix this. If you're going to use an id to set an initial width, you'll also need to have a #div2:hover
rule. You could modify the existing :hover
rule such as this to avoid repetition (although in more complex situations you might not want to duplicate all the properties of the rule, and prefer to have 2 separate :hover
rules):
div:hover , #div2:hover
{
width:300px;
}
The other option is to have a .blueDiv
rule instead of a #div2
one, such that the rule with the class is more specific than the non-hover element one, but not more than the hover rule element one.
.blueDiv
{
width:100px;
}
Upvotes: 3
Reputation: 3997
This is bungling, but I provided the same properties using CLASS instead of ID and the animation and property (font color, width and height) was working.
So I suppose providing properties using ID's can get overridden.. So it is always safe to use classes.
Upvotes: 0
Reputation: 4516
Since the styling in the ID overrides the styling mentioned previously for the tag, the hover also gets overridden.
If you're applying separate dimensions for the ID, you need to define its hover width separately for the ID.
Something like this in your case:
#div2{
width:100px;
height:50px;
-webkit-transition:width 3s;
background-color:blue;
}
#div2:hover{
width:300px;
}
Example in your modified jsfiddle
Upvotes: 0