Hi I am new to css and I have came across this text underline animation, I couldn't understand how it works. If I just take something out of this code it just stops working. Thanks in advance!
body {
background-color: black;
}
body a {
font-weight: 200;
font-size: 18px;
text-transform: uppercase;
text-decoration: none;
position: relative;
color: #fff;
}
body a:visited {
color: white;
}
body a:hover {
color: white;
}
body a:after {
content: "";
position: absolute;
bottom: 0;
left: 0;
width: 0%;
border-bottom: 2px solid #fff;
transition: 0.4s;
}
body a:hover:after {
width: 100%;
}
<body>
aaaaaaaaaaaaaaaaaaaaaaaaaaaaa
</body>
An :after psuedo CSS means that another "virtual" element is appended after the selected element
the psuedo element appended on a:after is a simple element with bottom border but is without width (0%)
the transition property on that element means, that all properties of that element when changed will be animated
so...
when you hover the element (stated in body a:hover:after) - the width of that "virtual" element is set to 100% - and the animation takes place
What's really important here are the pseudo-elements ":after" and ":before" (although this last one not present here).
This part here is what makes it come to life:
body a:after {
content: "";
position: absolute;
bottom: 0;
left: 0;
width: 0%;
border-bottom: 2px solid #fff;
transition: 0.4s;
}
You see, basically you're looking at the declaration of properties of an element's pseudo element. (You might want to dig in a bit into CSS-CSS3).
It states that after triggering the hover event on an anchor that is a child of body it will make its pseudo element have a bottom border of 2 pixels of width, with a white solid color and a transition of 0.4 seconds.
We can tell by the other declarations that the width of the pseudo-element is 0% in its initial state and after hovering it goes to 100% with a transition (making it go from left to right as seen in the example).
There's much things to consider in this CSS code but you should really learn the basics!
This line creates the animation:
transition: 0.4s;
You will notice that the body a:hover:after rule has a width of 100%. Well, that transition property tells the render engine that there is an animation to be performed on any property that has a value change between the normal and hover state.
When you hover, the render engine reads that you want to set the width property to 100%. Before hover it was set at 0%. Transition says, "ok, on hover, animate the width property from 0 to 100% over a period of 4 tenths of a second.
This will be true of any properties that differ between the hover and non-hover state. In other words, you could animate more than one property at a time so long as the two states define the same property with different values.
Related
I currently need to do this in CSS:
This is a vertical menu so the yellow "div" count is not fixed, could be 5 like it could be 7.
For now, I have a div with this CSS applied:
#main-menu {
width: 250px;
height: 100%;
padding-top: 50px;
}
That contains the yellow div (nothing special). Then I added a "before" pseudo-element like this:
#main-menu::before {
height:624px;
width:250px;
background-image: url("../img/SSC_fondgris_96_Background.png");
content: " ";
position:absolute;
top:0;
}
The image used is just the curve with a transparent background on the left and the grey on the right. This results in the the image above. The issue is that I'd like to have an hover effect on the yellow div's but I can't get that because the "before" element is on top of them (which is wanted in order to allow the curve to hide the overflow of yellow items) and therefore, the "hover" effect is not applied for the yellow divs.
I guess that it's because the hover is done on the "before" pseudo element and that's exacly my issue. So the question is: is it possible to have an image hidding the overflow of child elements but allowing these children to have a hover effect? Bascailly, a z-index for hover effect:-D
The goal here would also be to avoid using JavaScript to do such things...
Use pointer-events:none on the pseudo-element
From MDN
The CSS property pointer-events allows authors to control under what circumstances (if any) a particular graphic element can become the target of mouse events. When this property is unspecified, the same characteristics of the visiblePainted value apply to SVG content.
ul {
list-style: none;
width: 50%;
position: relative;
}
ul::before {
content: '';
position: absolute;
width: 25%;
height: 100%;
top: 0;
right: 0;
background: rgba(255, 0, 0, 0.5);
pointer-events: none;
}
li {
padding: 25px 0;
background: #000;
margin-bottom: 1em;
}
li:hover {
background: orange;
}
<ul>
<li></li>
<li></li>
<li></li>
<li></li>
<li></li>
</ul>
You should be able to "click through" the pseudo element by negating the pointer events on the element:
#main-menu::before {
height:624px;
width:250px;
background-image: url("../img/SSC_fondgris_96_Background.png");
content: " ";
position:absolute;
top:0;
/* Add the below */
pointer-events: none;
}
... let me know how that works for you.
I need to add that browser support is a little dodge though - only IE11 ... caniuse - pointer-events
You can achieve the effect you want by introducing a third, transparent element which you position over the top of the transparent/grey image.
If your third, transparent element is exactly congruent with the yellow div (two layers below), then you can apply :hover effects to the uppermost, transparent element and it will look like the bottom-most element is responding to the hover.
Currently I have a set of links with a div over them. I would like the div to disappear on mouseover allowing the links behind to be clickable.
:hover {display: none}
on the covering div causes a flickering effect at it's creating a loop so I can't do that.
:hover {background-color: rgba(0,0,0,0);}
also does not work as the div is still covering the links. I thought that adding a
:hover {pointer-events:none;}
could work but that also creates a flickering loop.
I basically want a div to not be there when I mouse over it, yet making it not there causes the :hover command to not read it as there, making it come back (...and the flickering begins)
This should work:
:hover {
pointer-events: none;
visibility: hidden;
}
The reason is that display: none physically removes the element, meaning you are no longer hovering it. Thus, it adds it back, and now, you're hovering it. That's why you get the flickering effect. visibility: hidden on the other hand, keeps the element exactly where it is, so you'll still technically be hovering it.
I lied, that is not going to work at all.
Here is a real solution:
HTML
<div class="container">
Hello
<div class="overlay"></div>
</div>
CSS
.container {
width: 50px;
height: 50px;
position: relative;
}
.overlay {
position: absolute;
top: 0;
left: 0;
bottom: 0;
right: 0;
background: black;
}
.container:hover .overlay {
display: none;
}
fiddle: https://jsfiddle.net/zqsn2fym/
I want to use the hover pseudoclass in css to increase the size of individual links in a table, however every time they are hovered over, the size increase affects the size of the rows/columns and all the other links in the table move in accordance.
Any way i can prevent this using only css and html?
You can use CSS3 tranform to scale the links without causing re-positioning of surrounding elements, for example:
table a:hover{ -webkit-transform: scale(1.2); }
-webkit- can be changed for other vendors (e.g., -moz- and -ms-), but is not available in some browsers, including IE8.
Using line-height will not prevent horizontal movement, therefore expanding the column.
You can do this way:
Set the initial height to the line-height.
td {line-height: 20px; font-size: 14px;}
td:hover {font-size: 20px;}
Fiddle: http://jsfiddle.net/mMZjf/
Force the line-height height to be the same and change the font-size on hover.
Example here
You could use relative and absolute positioning:
a:link {
display: block;
font-size: 1em;
outline: thin solid;
}
a:hover {
position: absolute;
top: 0;
left: 0;
font-size: 3em;
}
See this jsFiddle for an example.
I've got a button (<button> tag, but rendered like a link) inserted at the end of a line of text. I need to make a clear separation between the button and the text, so I'm using a :before pseudo element with a content: "—"; property to achieve that. So far so good.
Here is an example: http://jsfiddle.net/Anto/UPjQL/
The problem is that the content of the pseudo element behaves just like the button itself: when hovering it, the default cursor becomes a pointer cursor and the element is underlined. That makes sense, but I'd like to prevent that behavior and let it appear just like a regular text char.
Any idea ?
I know that wrapping the button inside, say, a span element and then giving the :before properties to that wrapper would be a more elegant solution, but in this case I can't afford it.
Take a look at the fiddle http://jsfiddle.net/joplomacedo/UPjQL/3/
.button-rendered-as-a-link {
position: relative; <-------------
border: none;
padding: 0;
margin: 0;
background: none;
-moz-border-radius: none;
-webkit-border-radius: none;
border-radius: none;
-moz-box-shadow: none;
-webkit-box-shadow: none;
box-shadow: none;
color: #8A89BA;
font-weight: bold;
left: 2em; <-------------
}
.button-rendered-as-a-link:hover {
text-decoration: underline;
cursor: pointer;
}
.button-rendered-as-a-link:before {
content:" — ";
position: absolute; <-------------
right: 100%; <-------------
padding: 0 5px;
color: grey;
cursor: default !important;
pointer-events: none; <-------------
}
The arrows represent the stuff I've added.
I've basically removed the pseudo element from the flow by using position: absolute. That made the button's width equal to what it would be without the psuedo element, and therefore, it's underline equal to no more than that width. The left and right properties put them back in place.
Then, as to not trigger a hover on the button I set the pseudo element's pointer-events to none. You can read more about it here https://developer.mozilla.org/en/CSS/pointer-events/.
I would just use JavaScript in your case, the insertBefore method should do the trick quite nicely!
var buttons = document.getElementsByClassName("button-rendered-as-a-link");
for (key in buttons)
try{
buttons[key].parentNode.insertBefore(document.createTextNode(" - "),buttons[key]);
}catch(e){}// this may throw an error?
Can I create button, use a background image that changes on hover and on active, and have the active state show an image that extends outside of the bounds of the anchor? Here's my sprite:
https://dl.dropbox.com/u/7737304/menu-sprite1.png
The top half of the sprite is 'hover', the bottom is 'active'. I don't anything below the solid bar to be a clickable link, and I don't want to set a width as the menu text will set on top and extend beyond the left and right edges of the image.
I've attempted to assign the background image to the parent li tag, which works for 'hover' but I can't make it work for 'active'.
Any ideas?
CSS
.navigation li:hover{
background: transparent url(../images/menu-sprite.png) center -86px no-repeat;
}
.navigation a{
color: #e8e8e8;
font-weight: bold;
text-transform: uppercase;
padding:0.5em 0.8em;
}
.navigation a:hover{
color: #fff;
}
.navigation a.active {
color: #fff;
}
Do you mean something like this ?
The anchor 'expands' when active, but doesn't change the flow, since it uses a negative margin to make it actually the same size as before.
So: add the amount of padding you want to expand the anchor, then add the same amount as a negative margin. (You do need the anchor to be a block or inline-block element, since otherwise it can't use margin)
No need for JavaScript with this method.
This is what I came up with: DEMO
It just puts the background image on the <li>. Not sure if this is exactly what you are looking for or not though.
This is a tough one to explain! What I did was to make the a tag clickable, extended the li with ::after to which I could apply the styles necessary to make it change, but not be click able.
Like I said, tough to explain but here is a demo: http://jsfiddle.net/cchana/SgH5C/
And here's some CSS that may help you:
.navigation li::after {
background: transparent url('https://dl.dropbox.com/u/7737304/menu-sprite1.png') center -49px no-repeat;
bottom: 0px;
content: '';
display: block;
height: 31px;
position: absolute;
width: 100%;
}
.navigation li:hover::after {
background: transparent url('https://dl.dropbox.com/u/7737304/menu-sprite1.png') center -130px no-repeat;
}