Is it possible to use keyframes animation to pseudo-element? - css

is it possible to use css keyframes animation to pseudo-element such as 'before' and 'after'?
I am developing webservice for smartphone, and want to blink element. but do not want to blink element itself.
so, ways I came up with are two;
one is to cover element with another element, and blink that element;
and another is to use pseudo-element, but it seems not working.
css:
.fadeElement {
background-color: #000000;
width: 60px;
height: 60px;
}
.fadeElement:after {
display: block;
content: '';
position: relative;
height: 100%;
width: 100%;
z-index: 500;
background-color: rgba(249, 4, 0, 0.5);
animation-name: 'fade';
animation-duration: 2s;
animation-iteration-count: infinite;
-webkit-animation-name: 'fade';
-webkit-animation-duration: 2s;
-webkit-animation-iteration-count: infinite;
}
#keyframes 'fade' {
0% {
opacity: 0;
}
40% {
opacity: 0.5;
}
60% {
opacity: 0.5;
}
100% {
opacity: 0;
}
}
#-webkit-keyframes 'fade' {
0% {
opacity: 0;
}
40% {
opacity: 0.5;
}
60% {
opacity: 0.5;
}
100% {
opacity: 0;
}
}
html:
<div class="fadeElement"></div>

Firefox, Chrome, and IE10+ support this.
See more info at Chris Coyier's site: http://css-tricks.com/transitions-and-animations-on-css-generated-content/

Related

CSS opacity animation don't work

I want to animate opacity from 0 to 1 so it show fade out to white animation, First I've used before pseudo element but it didn't work so I replaced it with div but got the same results here is the code:
body {
background: black;
}
.tv {
height: 100vh;
position: relative;
}
.white {
height: 100%;
position: absolute;
left: 0;
right: 0;
bottom: 0;
top: 0;
background: white;
z-index: 1;
opacity: 0;
/* infinite while debugging */
animation: opacity 5s ease-out infinite;
animation-fill-mode: forwards;
}
#keyframes opacity {
0%: { opacity: 0 }
100%: { opacity: 1; }
}
<div class="tv">
<div class="white"></div>
</div>
My first keyframe was like this:
#keyframes opacity {
to: { opacity: 1; }
}
What's wrong with this animation?
Remove colons after 0% and 100% and you will get the animation. Try like this:
#keyframes opacity {
0% { opacity: 0 }
100% { opacity: 1; }
}

Transition from one image to another

currently I'm using this code:
#div { background-image: url('imageurl.com'), url('imageurl2.com'); position: absolute !important; right: 0; left: 0; height: 210px !important; display: table-cell !important; vertical-align: middle !important;}
#keyframes FadeInOut {
0% {
opacity:1;
}
45% {
opacity:1;
}
55% {
opacity:0;
}
100% {
opacity:0;
}
}
#div img.top {
animation-name: FadeInOut;
animation-timing-function: ease-in-out;
animation-iteration-count: infinite;
animation-duration: 10s;
animation-direction: alternate;
}
I'm actually trying to implement the code from Demo 3 on this website:
http://css3.bradshawenterprises.com/cfimg/
In that demo, there are two images in one div and the code is just fading the first one in and out on a timer. I tried implementing this myself using the above code, but it's fading anything in and out. Does anyone know what I'm missing?
If you need implementation through background-image you can use pseudo-element:
#cf2 {
position:relative;
height:281px;
width:450px;
margin:0 auto;
background-image: url("http://css3.bradshawenterprises.com/images/Windows%20Logo.jpg");
}
#cf2::after{
content: ' ';
display: block;
position: absolute;
left: 0;
top: 0;
width: 100%;
height: 100%;
z-index: 1;
background-image: url("http://css3.bradshawenterprises.com/images/Turtle.jpg");
background-repeat: no-repeat;
background-position: 50% 0;
background-size: cover;
}
#keyframes cf3FadeInOut {
0% {
opacity:1;
}
45% {
opacity:1;
}
55% {
opacity:0;
}
100% {
opacity:0;
}
}
#cf2::after {
animation-name: cf3FadeInOut;
animation-timing-function: ease-in-out;
animation-iteration-count: infinite;
animation-duration: 10s;
animation-direction: alternate;
}
<div id="cf2">
</div>
here's the implementation, they use separate <img> tags to show/hide images:
they are absolutely positioned one above the other, that one which is on top is just showing and hiding by the animation (which changes its opacity) - so the bottom one just becomes visible when top one has opacity = 0
#keyframes cf3FadeInOut {
0% {
opacity: 1;
}
45% {
opacity: 1;
}
55% {
opacity: 0;
}
100% {
opacity: 0;
}
}
#cf3 img.top {
animation-name: cf3FadeInOut;
animation-timing-function: ease-in-out;
animation-iteration-count: infinite;
animation-duration: 10s;
animation-direction: alternate;
}
#cf3 img {
position: absolute;
left: 0;
}
#cf3 {
position: relative;
height: 281px;
width: 450px;
margin: 0 auto;
}
<div id="cf3" class="shadow">
<img class="bottom" src="http://css3.bradshawenterprises.com/images/Turtle.jpg">
<img class="top" src="http://css3.bradshawenterprises.com/images/Windows%20Logo.jpg">
</div>

Play first keyframe only once / queue animations

I've written the following bit of CSS:
.bulb--off {
position: relative;
z-index: 11;
}
.bulb--on {
position: absolute;
z-index: 11;
left:rem(1);
right:0;
opacity:0;
}
.bulb--on {
opacity:0.4;
animation-name: bulbFlicker;
animation-duration: 0.5s;
animation-timing-function: linear;
animation-iteration-count: infinite;
animation-play-state: running;
animation-delay: 1s;
}
#keyframes bulbFlicker {
0% { opacity: 1; }
25% { opacity: 0.9; }
50% { opacity: 0.95; }
75% { opacity: 0.9; }
100% { opacity: 1; }
}
What I hope to happen here is that the bulb would fade from off (opacity:0) to on (opacity:1) and then flicker.
What actually happens is that the bulb jumps from off to on (no fade) and then starts flickering, clearly what is happening is that when the animation starts it begins keyframe 1 as it should. I've tried adding a transition on opacity so that when it starts keyframe 1 it fades to it but it seems to ignore that property. Is there a way I can chain animations or even only make it play the first keyframe once?
I think I can do this using javascript but I've managed to get this far using CSS only and ideally I'd like it to remain CSS only.
If you apply two animations and add a delay to the second one equal to the length of the first animation you get the played first effect.
.light {
-webkit-animation: fade 3s;
animation: fade 3s;
opacity: 1;
}
.light .bulb {
-webkit-animation: jitter 1s infinite;
animation: jitter 1s infinite;
-webkit-animation-delay: 4s;
animation-delay: 4s;
}
#-webkit-keyframes fade {
from {
opacity: 0;
}
to {
opacity: 1;
}
}
#keyframes fade {
from {
opacity: 0;
}
to {
opacity: 1;
}
}
#-webkit-keyframes jitter {
0% {
opacity: 1;
}
50% {
opacity: 1;
}
55% {
opacity: 0.4;
}
60% {
opacity: 1;
}
100% {
opacity: 1;
}
}
#keyframes jitter {
0% {
opacity: 0.5;
}
50% {
opacity: 0.2;
}
100% {
opacity: 1;
}
}
/*Meaningless stuff for it to look cool*/
.bulb {
width: 50px;
height: 50px;
border: 2px solid gray;
border-top-left-radius: 100%;
border-top-right-radius: 100%;
border-bottom-left-radius: 50% 85%;
border-bottom-right-radius: 50% 85%;
background-color: yellow;
}
.metal {
margin-left: 10px;
width: 34px;
height: 10px;
background-color: gray;
border-bottom-right-radius: 10%;
border-bottom-left-radius: 10%;
}
.pole {
margin-left: 17.5px;
height: 100px;
width: 20px;
background-color: gray;
}
<div class="light">
<div class="bulb"></div>
<div class="metal"></div>
<div class="pole"></div>
</div>

CSS3 keyframes ease-in box then ease-out

I am having a look at CSS3 keyframes and want to have a box that eases in then eases out for the specified iteration-count, this is what I have so far it eases in then disappears then eases in again.
I want the box to ease in then ease out. See my fiddle. What do I need to do to achieve this?
<div id="content">
<span class="aniamte"></span>
</div>
#keyframes reset {
0% { opacity: 0; }
100% { opacity: 0; }
}
#keyframes fade-in {
0% { opacity: 0; }
60% { opacity: 0; }
100% { opacity: 1; }
}
.aniamte {
background: red;
display: inline-block;
height: 100px;
width: 100px;
animation-name: reset, fade-in;
animation-duration: 3s;
animation-timing-function: ease-in-out;
animation-iteration-count: 5;
animation-delay: 0, 1s;
}
I believe you're looking for animation-direction:alternate, but your question is not very clear. This will make your element use the keyframes from 0% to 100% for the specified duration then go from 100% to 0% after the first iteration is complete
#keyframes fade-in {
0% { opacity: 0; }
100% { opacity: 1; }
}
.animate {
background: red;
display: inline-block;
height: 100px;
width: 100px;
animation-name: fade-in;
animation-duration: 3s;
animation-timing-function: ease-in-out;
animation-direction:alternate;
animation-iteration-count: 5;
}
Demo

Is there any way to animate an ellipsis with CSS animations?

I'm trying to have an ellipsis animate, and was wondering if it was possible with CSS animations...
So it might be like
Loading...
Loading..
Loading.
Loading...
Loading..
And basically just continue like that. Any ideas?
Edit: like this: http://playground.magicrising.de/demo/ellipsis.html
How about a slightly modified version of #xec's answer: http://codepen.io/thetallweeks/pen/yybGra
CSS Animation that uses steps. See MDN docs
.loading:after {
overflow: hidden;
display: inline-block;
vertical-align: bottom;
-webkit-animation: ellipsis steps(4, end) 900ms infinite;
animation: ellipsis steps(4, end) 900ms infinite;
content: "\2026";
/* ascii code for the ellipsis character */
width: 0px;
}
#keyframes ellipsis {
to {
width: 40px;
}
}
#-webkit-keyframes ellipsis {
to {
width: 40px;
}
}
<h1 class="loading">Loading</h1>
#xec's answer has more of a slide-in effect on the dots, while this allows the dots to appear instantly.
You could try to use the animation-delay property and time each ellipsis character. In this case I've put each ellipsis character in a <span class> so I can animate them separately.
I made a demo, which isn't perfect, but it shows at least what I mean :)
The code from my example:
HTML
Loading<span class="one">.</span><span class="two">.</span><span class="three">.</span>​
CSS
.one {
opacity: 0;
-webkit-animation: dot 1.3s infinite;
-webkit-animation-delay: 0.0s;
animation: dot 1.3s infinite;
animation-delay: 0.0s;
}
.two {
opacity: 0;
-webkit-animation: dot 1.3s infinite;
-webkit-animation-delay: 0.2s;
animation: dot 1.3s infinite;
animation-delay: 0.2s;
}
.three {
opacity: 0;
-webkit-animation: dot 1.3s infinite;
-webkit-animation-delay: 0.3s;
animation: dot 1.3s infinite;
animation-delay: 0.3s;
}
#-webkit-keyframes dot {
0% {
opacity: 0;
}
50% {
opacity: 0;
}
100% {
opacity: 1;
}
}
#keyframes dot {
0% {
opacity: 0;
}
50% {
opacity: 0;
}
100% {
opacity: 1;
}
}
Even a more simple solution, works pretty well!
<style>
.loading::after {
display: inline-block;
animation: dotty steps(1,end) 1s infinite;
content: '';
}
#keyframes dotty {
0% { content: ''; }
25% { content: '.'; }
50% { content: '..'; }
75% { content: '...'; }
100% { content: ''; }
}
</style>
<div class="loading">Loading</div>
Just edited the content with animation instead of hiding some dots...
Demo here: https://jsfiddle.net/f6vhway2/1/
Edit:
Thanks to #BradCollins for pointing out that content is not an animatable property.
Currently, (2021) this works in Chrome/WebKit/Blink/Electron and Firefox and new version of Edge.
Short answer is "not really". However, you can play around with animating width and overflow hidden, and maybe get an effect that is "close enough". (code below tailored for firefox only, add vendor prefixes as needed).
html
<div class="loading">Loading</div>
css
.loading:after {
overflow: hidden;
display: inline-block;
vertical-align: bottom;
-moz-animation: ellipsis 2s infinite;
content: "\2026"; /* ascii code for the ellipsis character */
}
#-moz-keyframes ellipsis {
from {
width: 2px;
}
to {
width: 15px;
}
}
demo: http://jsfiddle.net/MDzsR/1/
edit
It appears chrome has issues with animating the pseudo-element. An easy fix is to wrap the ellipsis in its own element. Check out http://jsfiddle.net/MDzsR/4/
A late addition but I found a way to do this which supports centered text.
<element>:after {
content: '\00a0\00a0\00a0';
animation: progress-ellipsis 5s infinite;
}
#keyframes progress-ellipsis {
0% {
content: '\00a0\00a0\00a0';
}
30% {
content: '.\00a0\00a0';
}
60% {
content: '..\00a0';
}
90% {
content: '...';
}
}
You can animate clip (or better clip-path if you don't need IE support)
div {
display: inline-block;
font-size: 1.4rem;
}
div:after {
position: absolute;
margin-left: .1rem;
content: ' ...';
animation: loading steps(4) 2s infinite;
clip: rect(auto, 0px, auto, auto);
}
#keyframes loading {
to {
clip: rect(auto, 20px, auto, auto);
}
}
<div>Loading</div>
Well Actually there is a pure CSS way of doing this.
I got the example from CSS Tricks, but made it also to be supported in Internet Explorer (I have tested it in 10+).
Check the Demo: http://jsfiddle.net/Roobyx/AT6v6/2/
HTML:
<h4 id="searching-ellipsis"> Searching
<span>.</span>
<span>.</span>
<span>.</span>
</h4>
CSS:
#-webkit-keyframes opacity {
0% {
filter: progid:DXImageTransform.Microsoft.Alpha(Opacity=100);
opacity: 1;
}
100% {
filter: progid:DXImageTransform.Microsoft.Alpha(Opacity=0);
opacity: 0;
}
}
#-moz-keyframes opacity {
0% {
filter: progid:DXImageTransform.Microsoft.Alpha(Opacity=100);
opacity: 1;
}
100% {
filter: progid:DXImageTransform.Microsoft.Alpha(Opacity=0);
opacity: 0;
}
}
#-webkit-keyframes opacity {
0% {
filter: progid:DXImageTransform.Microsoft.Alpha(Opacity=100);
opacity: 1;
}
100% {
filter: progid:DXImageTransform.Microsoft.Alpha(Opacity=0);
opacity: 0;
}
}
#-moz-keyframes opacity {
0% {
filter: progid:DXImageTransform.Microsoft.Alpha(Opacity=100);
opacity: 1;
}
100% {
filter: progid:DXImageTransform.Microsoft.Alpha(Opacity=0);
opacity: 0;
}
}
#-o-keyframes opacity {
0% {
filter: progid:DXImageTransform.Microsoft.Alpha(Opacity=100);
opacity: 1;
}
100% {
filter: progid:DXImageTransform.Microsoft.Alpha(Opacity=0);
opacity: 0;
}
}
#keyframes opacity {
0% {
filter: progid:DXImageTransform.Microsoft.Alpha(Opacity=100);
opacity: 1;
}
100% {
filter: progid:DXImageTransform.Microsoft.Alpha(Opacity=0);
opacity: 0;
}
}
#searching-ellipsis span {
-webkit-animation-name: opacity;
-webkit-animation-duration: 1s;
-webkit-animation-iteration-count: infinite;
-moz-animation-name: opacity;
-moz-animation-duration: 1s;
-moz-animation-iteration-count: infinite;
-ms-animation-name: opacity;
-ms-animation-duration: 1s;
-ms-animation-iteration-count: infinite;
}
#searching-ellipsis span:nth-child(2) {
-webkit-animation-delay: 100ms;
-moz-animation-delay: 100ms;
-ms-animation-delay: 100ms;
-o-animation-delay: 100ms;
animation-delay: 100ms;
}
#searching-ellipsis span:nth-child(3) {
-webkit-animation-delay: 300ms;
-moz-animation-delay: 300ms;
-ms-animation-delay: 300ms;
-o-animation-delay: 300ms;
animation-delay: 300ms;
}
I found clip-path to be the cleanest, with the following benefits:
Does not use width, thus:
works independent of how wide the ellipsis is in whatever font is used.
Does not shift the layout (good for performance, and allows more text behind it without that moving around or reflow).
.loading-ellipsis:after {
overflow: hidden;
display: inline-block;
vertical-align: bottom;
animation: ellipsis-animation steps(1,end) 2s infinite;
content: "\2026"; /* ascii code for the ellipsis character */
/* Enable this to see what is going on: */
/* background-color: red; */
}
#keyframes ellipsis-animation {
0% { clip-path: inset(0 100% 0 0); }
25% { clip-path: inset(0 66.6% 0 0); }
50% { clip-path: inset(0 33.3% 0 0); }
75% { clip-path: inset(0 0 0 0); }
}
<span class="loading-ellipsis">Loading</span> More text behind it that does not move
Credits go to #AaylaSecura's comment, and I improved that to use steps(1,end). This works because I end the animation at 75%, so that the last step shows the full expansion of the ellipsis (the third dot).
(There is an implicit 100% { clip-path: inset(0 0 0 0); } behind it that need not be written.)
Here is my solution with pure css https://jsfiddle.net/pduc6jx5/1/
explained: https://medium.com/#lastseeds/create-text-ellipsis-animation-with-pure-css-7f61acee69cc
scss
.dot1 {
animation: visibility 3s linear infinite;
}
#keyframes visibility {
0% {
opacity: 1;
}
65% {
opacity: 1;
}
66% {
opacity: 0;
}
100% {
opacity: 0;
}
}
.dot2 {
animation: visibility2 3s linear infinite;
}
#keyframes visibility2 {
0% {
opacity: 0;
}
21% {
opacity: 0;
}
22% {
opacity: 1;
}
65% {
opacity: 1;
}
66% {
opacity: 0;
}
100% {
opacity: 0;
}
}
.dot3 {
animation: visibility3 3s linear infinite;
}
#keyframes visibility3 {
0% {
opacity: 0;
}
43% {
opacity: 0;
}
44% {
opacity: 1;
}
65% {
opacity: 1;
}
66% {
opacity: 0;
}
100% {
opacity: 0;
}
}
html
Loading <span class="dot dot1">.</span><span class="dot dot2">.</span><span class="dot dot3">.</span>
I did exactly what #CodeBrauer very cleanly did above, but because my text was text-align: center (this works for right, too) and I didn't want the text to move over every time a period was added, I added "punctuation spaces":
<style>
.loading::after {
display: inline-block;
animation: dotty steps(1,end) 1s infinite;
content: '';
}
#keyframes dotty {
0% { content: '\2008\2008\2008'; }
25% { content: '.\2008\2008'; }
50% { content: '..\2008'; }
75% { content: '...'; }
100% { content: '\2008\2008\2008'; }
}
</style>
<div class="loading">Loading</div>

Resources