Reputation:
I followed some tutorials here http://tympanus.net/codrops/2013/08/06/creative-link-effects/
and made a nice animation on hover for navigation list items.
Here's the HTML:
<div id="nav">
<ul id="navbar">
<li><a href="#" data-hover="Home">Home</a></li>
<li><a href="#" data-hover="About">About</a></li>
<li><a href="#" data-hover="Contact">Contact</a></li>
<li><a href="#" data-hover="Sign Up">Sign Up</a></li>
</ul>
</div>
And here's the CSS:
#navbar {
list-style: none;
}
#navbar li {
display: inline-block;
padding: 15px;
}
#navbar li a {
position: relative;
display: inline-block;
margin: 15px 25px;
text-decoration: none;
letter-spacing: 1px;
font-weight: bold;
text-shadow: 0 0 1px rgba(255, 255, 255, 0.3);
font-size: 24px;
padding: 10px 0;
border-top: 1.5px solid #0972b4;
color: #0972b4;
}
#navbar li a:after {
position: absolute;
top: 0;
left: 0;
overflow: hidden;
padding: 10px 0;
max-width: 0;
border-bottom: 1.5px solid #000;
color: #000;
content: attr(data-hover);
-webkit-transition: max-width 0.5s;
-moz-transition: max-width 0.5s;
transition: max-width 0.5s;
}
#navbar li a:hover:after,
#navbar li a:focus:after {
max-width: 100%;
}
It works perfectly for 'Home', 'About' and 'Contact' but not for 'Sign Up'; clearly because of the space!
I understand how the code works but I can't know why such a bug exists!
The pseudo class after
puts the same text on top of the original text and then colors it and extends the bottom-border on hover according to a transition rule.
Here's a JSFiddle: https://jsfiddle.net/rnw00/3dhcz84b/1/
Upvotes: 6
Views: 1179
Reputation: 671
#navbar li a:after {
...
white-space: nowrap;
...
}
Try this. Your content line was breaking.
See here for more info. https://stackoverflow.com/questions/....
http://codepen.io/faizanrupani/pen/qbRGyb
Upvotes: 1
Reputation: 241178
The reason it's occurring is because you're transitioning the pseudo elements width from 0
to 100%
. When the width is less than 100%
, the text wraps to a new line, resulting in the issue that you're seeing.
You can prevent this by adding white-space: pre
to the descendant anchor element.
#navbar li a {
position: relative;
display: inline-block;
/* ... */
white-space: pre;
}
#navbar {
list-style: none;
}
#navbar li {
display: inline-block;
padding: 15px;
}
#navbar li a {
position: relative;
display: inline-block;
margin: 15px 25px;
text-decoration: none;
letter-spacing: 1px;
font-weight: bold;
text-shadow: 0 0 1px rgba(255, 255, 255, 0.3);
font-size: 24px;
padding: 10px 0;
border-top: 1.5px solid #0972b4;
color: #0972b4;
white-space: pre;
}
#navbar li a:after {
position: absolute;
top: 0;
left: 0;
overflow: hidden;
padding: 10px 0;
width: 0;
border-bottom: 1.5px solid #000;
color: #000;
content: attr(data-hover);
-webkit-transition: width 0.5s linear;
-moz-transition: width 0.5s linear;
transition: width 0.5s linear;
}
#navbar li a:hover:after,
#navbar li a:focus:after {
width: 100%;
}
<div id="nav">
<ul id="navbar">
<li><a href="#" data-hover="Home">Home</a>
</li>
<li><a href="#" data-hover="About">About</a>
</li>
<li><a href="#" data-hover="Contact">Contact</a>
</li>
<li><a href="#" data-hover="Sign Up">Sign Up</a>
</li>
</ul>
</div>
By changing the white-space
property's value to pre
or nowrap
, you essentially prevent the pseudo element's text from wrapping (if you're wondering why I added that to the anchor element rather than the pseudo element, it's because the value is inherited since the pseudo element is essentially a child element. It's probably safer adding that directly to the anchor element because you don't want one element wrapping, and the other element staying on one line. This ensures that the behavior is consistent between elements).
Upvotes: 5
Reputation: 23389
Simple fix is to exchange the spaces with "non breaking" spaces..
<li><a href="#" data-hover="Sign Up">Sign Up</a></li>
https://jsfiddle.net/3dhcz84b/2/
Upvotes: 3