CSS3 transitions on pseudo-elements (:after, :before) not working? - css

I'm showing the title attribute of a link on :hover. The title attribute is appended to the link via :after… 
Now I'm wondering how I can animate the opacity of the :after pseudo-element when hovering-in and hovering-out.
html
<a class="link" href="#" title="something"></a>​
css
.link {
display:block;
width:50px;
height:50px;
background:red;
}
.link:after {
position:relative;
content: attr(title);
top:55px;
color:$blue;
zoom: 1;
filter: alpha(opacity=00);
opacity: 0;
-webkit-transition: opacity .15s ease-in-out;
-moz-transition: opacity .15s ease-in-out;
-ms-transition: opacity .15s ease-in-out;
-o-transition: opacity .15s ease-in-out;
transition: opacity .15s ease-in-out;
}
.link:hover:after {
zoom: 1;
filter: alpha(opacity=100);
opacity: 1;
}
Check out the demo: http://jsfiddle.net/d2KrC/
Any ideas why this is not working?
​

WebKit (Chrome, Safari) does not support transitions on pseudo elements.
https://bugs.webkit.org/show_bug.cgi?id=23209
http://code.google.com/p/chromium/issues/detail?id=54699
It should work in Firefox.
Edit: The issue in WebKit is now resolved. The patch allready landed in Chrome Carnery, so it will be supportet from version 26 on. I don't know about Safari.

Theres a fairly easy workaround to this webkit bug to make transitions work on pseudo classes. Here's a great blog post about it: http://xiel.de/webkit-fix-css-transitions-on-pseudo-elements/
Basically webkit doesnt support the transitions directly but you can apply the transition and style you want to change to its parent element. Then in the pseudo class you put the same style properties that you want to affect, but give them the value: inherit. That will cause them to inherit all of the parent elements values including the transition.
Here's a sample I did to animate the :after element, up and down
a {
position: static; /* explicitly defined so not to forget that it can't be relative or :after transition hack will not work */
top: 1px; /*doesnt move it because it is position static */
-webkit-transition: top 200ms ease 0;
}
a:after {
content: '';
position: absolute;
top: inherit;
}
a:hover {
top: 3px;
}
*Update
The bug has been fixed in Chrome Canary (as of February), but still appears to be broken in Safari. Can check the status and stay updated on it here:
https://code.google.com/p/chromium/issues/detail?id=54699

Related

css apply filter: brightness(0) to an anchor that has nested images inside (but do not apply the filter to the images) [duplicate]

I'm using a very fancy webkit filter to make background-images grayscale, and on hover over the images become color.
Here's the filter
filter: none;
-webkit-filter: grayscale(0);
transition: opacity .3s ease-in-out;
-moz-transition: opacity .3s ease-in-out;
-webkit-transition: opacity .3s ease-in-out;
As you can see, there's even a 'transition' property so that the image has a smooth fading transition into full color. The problem that I'm having is that the div I'm applying it to is also affecting the child text positioned inside the div, turning the text into grayscale as well. This is a problem because the text needs to be white, even when not being hovered over.
I've tried negating the filter with another one on the child text but it doesn't seem to work... Check out the fiddle
Fiddle http://jsfiddle.net/yMHm4/1/
This is not a problem of properties inheritance, as you can think.
The way filters work makes that imposible to fix changing attributes in the CSS: The element affected by the filter is rendered, all the children are rendered, and then the result (as an image) has the filter applied.
So the only alternatives left are:
1) Change the HTML, as Lowkase suggested
2) In your case, seems that all you want to make gray is the background image. In this case, you can leave the HTML as is, display the image in a pseudo element, and apply the filter to this pseudo element.
CSS
.cell{
opacity:0.7;
width:420px;
height:420px;
transition: opacity .3s ease-in-out;
-moz-transition: opacity .3s ease-in-out;
-webkit-transition: opacity .3s ease-in-out;
}
.A1 {
position: relative;
}
.A1:before {
content: "";
position: absolute;
width: 100%;
height: 100%;
top: 0px;
left: 0px;
background-image:url('http://i.imgur.com/NNKxZ5R.jpg');
filter: url(filters.svg#grayscale); /* Firefox 3.5+ */
filter: gray; /* IE6-9 */
-webkit-filter: blur(15px); /* Google Chrome, Safari 6+ & Opera 15+ */
z-index: -1;
}
#text {
color:#ffffff;
text-align:center;
font:18px sans serif;
text-decoration:none;
}
.cell:hover {
opacity:1.0;
}
.A1:hover:before {
filter: none;
-webkit-filter: grayscale(0);
transition: opacity .3s ease-in-out;
-moz-transition: opacity .3s ease-in-out;
-webkit-transition: opacity .3s ease-in-out;
}
fiddle
I have also changed your filter to blur to make it more clear the the text is not affected by the filter. Since you had also some opacity set, the text still looked grayish just because you were seeing the gray under it.
Added example using brightness filter (for webkit)
demo 2
You had a couple of HTML errors with your br's, they should be br/, not /br.
The following solution takes the text container out of the image div and places it as an absolute positioned element:
http://jsfiddle.net/yMHm4/3/
#text {
position:absolute;
top:10px;
left:25%;
color:#ffffff;
text-align:center;
font:18px sans serif;
text-decoration:none;
}
<div id="container">
<div id="row">
<div class="cell A1"></div>
<div id="text">
<b>SPINDRIFT KIOSK</b>
<br/>
Digital Collage
<br/>
<i>Mikey</i>
</div>
</div>
</div>
You could probably use "not" selectors in your CSS but I am not sure how cross browser friendly they are. This solution is a more plain jane way to do it.

Hover off transition css

this question might be obvious but i'm new in css.
I'm animating a shape so when you hover it, it stretches. I've completed the hover on with a nice ease transition but when you move off the mouse the transition doesn't work. Is there a way to make it happen also in the hover off moment?
.shape1{
position: absolute;
background:red
top:512px;
width:180px;
height:140px;
}
.shape1:hover {
height: 160px;
top:492px;
transition: 0.2s ease;
}
Your answer
You have added the transition property on the hover state of the element. Therefore the transition is not applied when you leave the cursor from the element.
.shape1{
position: absolute;
background: red;
top: 512px;
width: 180px;
height: 140px;
transition: .2s ease; /* move this here from :hover */
}
Further information
Besides this you can also add specific properties to the transition. For example, if you only want the height to be animated you could it like this:
.shape1 {
transition: height .2s ease;
/* this inly affects height, nothing else */
}
You can even define different transition-times for each property:
.shape1 {
transition: height .2s ease, background-color .5s linear;
/* stacking transitions is easy */
}
Add the transition before the :hover, so the transition always applies
.shape1 {
transition: 0.2s ease;
}
The :hover selector is used to select elements when you mouse over them.
W3Schools
When you add also transition to your shape1 class it should works

css transition background image fade

I'm using css transitions to cause a fade-in and fade-out effect on a background-image property. The property gets changed via jquery when the user scrolls.
It initially did not work on any browser. I found that setting an completley empty/transparent PNG file on the original element made chrome work, but the other browsers still don't.
Here's an example of the code:
nav {
background:url(/img/empty.png);
background-origin:border-box;
background-position:top;
background-repeat:repeat;
background-size:50px 50px;
transition: background 1s ease-in-out;
-moz-transition: background 1s ease-in-out;
-webkit-transition: background 1s ease-in-out;
}
.contrast {
background:#3a3a3a url(/img/xnav.jpg);
background-origin:border-box;
background-position:top;
background-repeat:repeat;
background-size:50px 50px;
}
The contrast class gets applied to the nav element via jquery. It only seems to fade out on most browsers, but not fade in. It works properly in chrome.
Q1: Is there a cleaner way to do this? Adding a transparent PNG as a background element to the nav element seems like a hack.
Q2: This still doesn't work on firefox, IE or Safari. Can anyone suggest a clean fix?
You can "fake" the background-image opacity with pseudo-element on your:
nav{
position:relative;
}
nav::before{
content: "";
background: url(/img/xnav.jpg);
background-origin:border-box;
background-position:top;
background-repeat:repeat;
background-size:50px 50px;
opacity: 0;
top: 0;
left: 0;
bottom: 0;
right: 0;
position: absolute;
transition: opacity 1s ease-in-out;
}
.contrast{ // applied on nav::before
opacity: 1;
}
Thanks to Nicolas Gallagher for this.

MouseOver and MouseOut In CSS

For using mouse into one element we use the :hover CSS attribute. How about for mouse out of the element?
I added a transition effect on the element to change the color. The hover effect works fine, but what CSS attribute should I use for mouse out to apply the effect? I'm looking for a CSS solution, not a JavaScript or JQuery solution.
Here is the best solution, i think.
CSS onomouseout:
div:not( :hover ){ ... }
CSS onmouseover:
div:hover{ ... }
It's better, because if you need to set some styles ONLY onmouseout and trying to do this in this way
div { ... }
you will set your styles and for onmouseover too.
CSS itself does not support a mousein or mouseout selector.
The :hover selector will apply to the element while the mouse is over it, adding the style when the mouse enters and removing the style when the mouse leaves.
The nearest approach is to define the styles which you would place in mouseout within your default (non-hover) styles. When you mouse-over the element the styles within hover will take effect, emulating a mousein, and when you move your mouse off the element the default styles will take effect again, emulating mouseout.
Here is an example, taken from here:
div {
background: #2e9ec7;
color: #fff;
margin: 0 auto;
padding: 100px 0;
-webkit-transition: -webkit-border-radius 0.5s ease-in;
-moz-transition: -moz-border-radius 0.5s ease-in;
-o-transition: border-radius 0.5s ease-in;
-ms-transition: border-radius 0.5s ease-in;
transition: border-radius 0.5s ease-in;
text-align: center;
width: 200px;
}
div:hover {
background: #2fa832;
-webkit-border-radius: 100px;
-moz-border-radius: 100px;
border-radius: 100px;
-webkit-transition: all 1s ease;
-moz-transition: all 1s ease;
-o-transition: all 1s ease;
-ms-transition: all 1s ease;
transition: all 1s ease;
-webkit-transform: rotate(720deg);
-moz-transform: rotate(720deg);
-o-transform: rotate(720deg);
-ms-transform: rotate(720deg);
transform: rotate(720deg);
}
The transitions defined for the div:hover style will take effect when the mouse enters (and hover is applied). The transitions for the div style will take effect when the mouse leaves (and hover is removed). This results in the mousein and mouseout transitions being different.
I think that I've found the solution.
.class :hover {
/*add your animation of mouse enter*/
}
.class {
/*
no need for not(hover) or something else.
Just write your animation here and it will work when mouse out
*/
}
Just try it... :)
You only need the :hover , when you mouse out of the element, it'll return to it's default non-:hover state, like this:
.class { color: black; }
.class:hover { color: red; }
when you hover, the color will be red and when you "mouseout", the color will return to black because it no longer matches the :hover selector. This is the default behavior for all browsers, nothing special you need to do here.

Animate the CSS transition property within :after/:before pseudo-classes

Is it possible to animate CSS pseudo-classes?
Say I have:
#foo:after {
content: '';
width: 200px;
height: 200px;
background: red;
display: block;
-webkit-transition: all 1s ease-in-out;
-moz-transition: all 1s ease-in-out;
-o-transition: all 1s ease-in-out;
}
#foo:hover:after {
width: 250px;
height: 250px;
}
Is this even possible? I've been testing and so far I can't seem to find a solution. I'm trying to trim down the amount of JavaScript support I need by using Modernizr.
I already have a JavaScript method, so please no JavaScript alternatives.
Demo: http://jsfiddle.net/MxTvw/
Your fiddle does work for me in Firefox. And as far as I know, and if this article is up to date this is the only browser that can animate pseudo-elements.
EDIT: As of 2016, the link to article is broken and the relevant WebKit bug was fixed 4 years ago. Read on to see other answers, this one is obsolete.
Google Chrome added the webkit bug fix to Version 27.0.1453.110 m
This WebKit bug was fixed: http://trac.webkit.org/changeset/138632
IT IS POSSIBLE to animate pseudo :before and :after, here are a couple of examples for animating the psuedo-elements :before and :after.
Here is a modification of your example above with some edits, that make it animate in and out more smoothly without the simulated mouseleave / mouseout delay on hover:
http://jsfiddle.net/MxTvw/234/
Try adding the main selector #foo with the grouped :hover pseudo-class in your second :hover pseudo-class rule. Also add the transition property, and not just the vendor specific prefixed properties for transition:
#foo:after{
display: block;
content: '';
width: 200px;
height: 200px;
background: red;
-webkit-transition: all .4s ease-in-out;
-moz-transition: all .4s ease-in-out;
-o-transition: all .4s ease-in-out;
transition: all .4s ease-in-out;
}
#foo,
#foo:hover:after,
#foo:hover:before{
width: 250px;
height: 250px;
}
Note that going forward any Pseudo Elements like :before and :after should use the double colon syntax ::before and ::after. This example simulates a fade in and out using a overlay background-color and a background-image on hover:
http://jsfiddle.net/MxTvw/233/
This example simulates a animate of rotation on hover:
http://jsfiddle.net/Jm54S/28/
Of course moving forward with css3 standards we could use ::before and ::after.
This works in latest Firefox, Chrome, Safari, Opera 18+, IE10, IE11 (IE9 and below do not support css3 transitions or animate.)
It does not seem to work now, however according to the W3 specs you can apply transitions to pseudo-elements. Maybe some time in future…
I just found out that you can animate :after and :before (:
Code example-
.model-item {
position: relative;
&:after {
content: '';
position: absolute;
width: 100%;
height: 100%;
top: 0;
right: 0;
background: transparent;
transition: all .3s;
}
}
.opc {
&:after {
content: '';
position: absolute;
width: 100%;
height: 100%;
top: 0;
right: 0;
background: rgba(0, 51, 92, .75);
}
}
I have the div .model-item and i needed to animate his :after.
So i've added another class which changes background and i added the transition code to the main :after (before animation)

Resources