I want to do infinite ripple animation, but it will become unnatural..
I don't like this sudden change, I want to make animation continue forever.
How can I do it?
In the code snippet, I could not display it well for some reason, so the current situation is in JSFiddle.
body {font-size: 62.5%; background-color: #000;}
.ripple {
margin: auto;
margin-top: 10rem;
background-color: #fff;
width: 1rem;
height: 1rem;
border-radius: 50%;
animation: ripple 2s linear infinite;
}
#keyframes ripple {
0% {
box-shadow: 0 0 0 .7rem rgba(255,255,255, 0.2),
0 0 0 1.5rem rgba(255,255,255, 0.2),
0 0 0 5rem rgba(255,255,255, 0.2);
}
100% {
box-shadow: 0 0 0 1.5rem rgba(255,255,255, 0.2),
0 0 0 4rem rgba(255,255,255, 0.2),
0 0 0 8rem rgba(255,255,255, 0);
}
}
<div class="ripple" style="animation-delay: 0s"></div>
By the way, I tried also this(▼) with HTML, but the circles overlapped and I could not do it well.. :(
<div class="ripple" style="animation-delay: 0s"></div>
<div class="ripple" style="animation-delay: 1s"></div>
<div class="ripple" style="animation-delay: 2s"></div>
If you'd like your animation to be more smooth you need to match the beginning values with the end values so you don't get that 'jumpy' effect.
Something like this:
#keyframes ripple {
0% {
box-shadow: 0 0 0 0rem rgba($ripple-color, 0.2),
0 0 0 1rem rgba($ripple-color, 0.2),
0 0 0 2rem rgba($ripple-color, 0.2),
0 0 0 5rem rgba($ripple-color, 0.2);
}
100% {
box-shadow: 0 0 0 1rem rgba($ripple-color, 0.2),
0 0 0 2rem rgba($ripple-color, 0.2),
0 0 0 5rem rgba($ripple-color, 0.2),
0 0 0 8rem rgba($ripple-color, 0);
}
}
Here is another easier idea to have a smooth effect. You can keep the shadow animation simple and consider pseudo element to have the same delayed animation. The trick is to correctly choose the delay/duration.
I made the duration to be 3s (3 elements) and there is 1s delay between each one.
body {
background-color: #000;
}
.ripple {
margin: auto;
margin-top: 5rem;
background-color: #fff;
width: 1rem;
height: 1rem;
border-radius: 50%;
display: grid;
animation: ripple 3s linear infinite;
}
.ripple::before,
.ripple::after {
content: "";
grid-area: 1/1;
border-radius: 50%;
animation: inherit;
animation-delay: 1s;
}
.ripple::after {
animation-delay: 2s;
}
#keyframes ripple {
0% {
box-shadow: 0 0 0 .7rem rgba(255, 255, 255, 0.2);
}
100% {
box-shadow: 0 0 0 8rem rgba(255, 255, 255, 0);
}
}
<div class="ripple"></div>
Related
I use named keyframe animations and I want to save myself some writing. I have seen this SO Question regarding scss keyframe function But I feel like its not to helpful (or Im to stupid to understand)
I have tried a couple variations of
$green: limegreen;
#mixin pulse-animation($name, $color) {
#keyframes #{$name} {
0% {
-moz-box-shadow: 0 0 0 0 rgba($color, 0.4);
box-shadow: 0 0 0 0 rgba($color, 0.4);
}
70% {
-moz-box-shadow: 0 0 0 12px rgba($color, 0);
box-shadow: 0 0 0 12px rgba($color, 0);
}
100% {
-moz-box-shadow: 0 0 0 0 rgba($color, 0);
box-shadow: 0 0 0 0 rgba($color, 0);
}
}
}
.my-element {
animation: #include pulse-animation("green", $green) 2s infinite;
}
I would also prefer to not have to pass a name into this mixin.
I found here an interesting situation where first you create an animation with a keyframe mixin and then you use another mixin to include that animation (see 4. Animations and keyframes).
However, if you don't want to include 2 mixins because you want to save yourself some writing, another idea could be to create all keyframe animations you need using a simple map loop:
$colors:(
"green": limegreen,
"black": black,
"white": white /*here you can add all colors you need*/
);
#each $name, $color in $colors {
#keyframes #{$name} {
0% {
-moz-box-shadow: 0 0 0 0 rgba($color, 0.4);
box-shadow: 0 0 0 0 rgba($color, 0.4);
}
70% {
-moz-box-shadow: 0 0 0 12px rgba($color, 0);
box-shadow: 0 0 0 12px rgba($color, 0);
}
100% {
-moz-box-shadow: 0 0 0 0 rgba($color, 0);
box-shadow: 0 0 0 0 rgba($color, 0);
}
}
}
.my-element {
animation: green 2s infinite;
}
I need to change the animation with a transition effect. That is change first transition to another with a flow. When I tried for the same the animation changes with a fast change as in below snippet. Is there any way to animate the change in animation. I have tried the below code.
body{
background: url('https://i.pinimg.com/originals/0b/76/08/0b760848c89b9e4abd03f74f19419498.jpg');
}
.bubble{
top: 50px;
left: 80px;
height: 100px;
width: 100px;
color: #000;
box-sizing: border-box;
border-radius: 50%;
box-shadow: 0 5px 15px 0px rgba(0,0,0,0.4);
transform: translatey(0px);
cursor: pointer;
position: absolute;
border: 10px solid rgba(255,255,255,0.2);
animation: float 4s ease-in-out infinite;
}
.bubble span {
font-size: 12px;
line-height: 85px;
position: absolute;
bottom: 0;
top: 0;
right: 0;
left: 0;
text-align: center;
border-radius: 50%;
background: red;
}
.bubble:before {
position: absolute;
content: "";
top: 0px;
bottom: 0px;
left: 0px;
right: 0px;
border-radius: 50%;
box-shadow: 0 0 rgba(255, 255, 255, 0.1), 0 0 0 8px rgba(255, 255, 255, 0.1),
0 0 0 16px rgba(255, 255, 255, 0.1), 0 0 0 24px rgba(255, 255, 255, 0.1);
z-index: -1;
animation: ripples 1s linear infinite;
animation-play-state: paused;
opacity: 0;
visibility: hidden;
transition: 0.5s;
transform: scale(0.5);
}
.bubble:hover {
transition: all 2s;
animation: tofixed 4s forwards;
box-shadow: none;
border-color: transparent;
}
.bubble:hover:before {
animation-play-state: running;
opacity: 1;
visibility: visible;
transform: scale(1);
}
#keyframes float {
0% { box-shadow: 0 5px 15px 0px rgba(0,0,0,0.6); transform: translatey(0px) scale(0.9); }
50% { box-shadow: 0 25px 15px 0px rgba(0,0,0,0.2); transform: translatey(-20px) scale(1); }
100% { box-shadow: 0 5px 15px 0px rgba(0,0,0,0.6); transform: translatey(0px) scale(0.9); }
}
#keyframes tofixed {
to { transform: translatey(0px) scale(0.9); }
}
#keyframes ripples {
to {
box-shadow: 0 0 0 8px rgba(255, 255, 255, 0.1), 0 0 0 16px rgba(255, 255, 255, 0.1),
0 0 0 24px rgba(255, 255, 255, 0.1), 0 0 0 32px rgba(255, 255, 255, 0);
}
}
<div class="bubble">
<span class="bgviolet">ODOSTORE</span>
</div>
In the above snippet you can see the change in animation is instantly when I hover on it.
I need to animate the circle's box-shadow and scale it down to 1 from 1.6x during the same transition period of box-shadow.
The issue I'm facing is the animation of scale is happening after the animation of box-shadow is done.
body {
background-color: #333;
}
.ripple {
width: 20px;
margin: 50px auto;
height: 20px;
background: #ccc;
border-radius: 50%;
animation: rippleeff 2s ease infinite;
}
#keyframes rippleeff {
0% {
-moz-box-shadow: 0 0 0 0 rgba(204, 169, 44, 0.4);
box-shadow: 0 0 0 0 rgba(204, 169, 44, 0.4);
transform: scale(1.4);
}
70% {
-moz-box-shadow: 0 0 0 20px rgba(204, 169, 44, 0);
box-shadow: 0 0 0 20px rgba(204, 169, 44, 0);
transform: scale(1.6);
}
100% {
-moz-box-shadow: 0 0 0 0 rgba(204, 169, 44, 0);
box-shadow: 0 0 0 0 rgba(204, 169, 44, 0);
transform: scale(1);
}
}
<div class="ripple">
</div>
Fiddle
When your transform: scale(1.6), your box-shadow become transparent and after that when you going to scale(1) your box-shadow is animating but you can't see it because it's transparent...so change box-shadow color
Also changed scale value in the code...
body {
background-color: #333;
}
.ripple {
width: 20px;
margin: 50px auto;
height: 20px;
background: #ccc;
border-radius: 50%;
animation: rippleeff 2s linear infinite;
}
#keyframes rippleeff {
0% {
box-shadow: 0 0 0 0 rgba(204, 169, 44, 0.4);
transform: scale(1);
}
50% {
box-shadow: 0 0 0 20px rgba(204, 169, 44, 0);
transform: scale(1.6);
}
100% {
box-shadow: 0 0 0 0 rgba(204, 169, 44, 0.4);
transform: scale(1);
}
}
<div class="ripple">
</div>
This question already has answers here:
CSS Animations with delay for each child element
(6 answers)
Closed 5 years ago.
i want my buttons chronologically - the second button start animating after first button ends and so on ...
Could somebody help me achieve that effect ?
a {
padding: 6px;
display: block;
width: 50px;
font-size: 17px;
margin: 10px auto;
border: 2px solid;
text-decoration: none;
box-shadow: 0 0 0 rgba(204,169,44, 0.4);
animation: pulse 2s infinite;
}
#keyframes pulse {
0% {
-moz-box-shadow: 0 0 0 0 rgba(204,169,44, 0.4);
box-shadow: 0 0 0 0 rgba(204,169,44, 0.4);
}
70% {
-moz-box-shadow: 0 0 0 10px rgba(255,208,0, 0.2);
box-shadow: 00 0 0 10px rgba(255,208,0, 0.2);
}
100% {
-moz-box-shadow: 0 0 0 0 rgba(204,169,44, 0);
box-shadow: 0 0 0 0 rgba(204,169,44, 0);
}
}
<a class="btn-100" href="#">100</a>
<a class="btn-500" href="#">500</a>
<a class="btn-1250" href="#">1250</a>
As others have suggested, use animation-delay to offset each element's animation.
In order to loop the entire group, multiply the animation duration by the number of elements and change your keyframes accordingly. Below, I've multiplied the animation duration by three and divided the keyframe percentages by three.
If you have a large number of elements or they are added dynamically, you may want to consider using JavaScript, as mentioned here.
a {
padding: 6px;
display: block;
width: 50px;
font-size: 17px;
margin: 10px auto;
border: 2px solid;
text-decoration: none;
box-shadow: 0 0 0 rgba(204, 169, 44, 0.4);
animation: pulse 6s infinite;
}
.btn-100 {
animation-delay: 0s;
}
.btn-500 {
animation-delay: 2s;
}
.btn-1250 {
animation-delay: 4s;
}
#keyframes pulse {
0% {
-moz-box-shadow: 0 0 0 0 rgba(204, 169, 44, 0.4);
box-shadow: 0 0 0 0 rgba(204, 169, 44, 0.4);
}
23.333% {
-moz-box-shadow: 0 0 0 10px rgba(255, 208, 0, 0.2);
box-shadow: 00 0 0 10px rgba(255, 208, 0, 0.2);
}
33.333% {
-moz-box-shadow: 0 0 0 0 rgba(204, 169, 44, 0);
box-shadow: 0 0 0 0 rgba(204, 169, 44, 0);
}
}
<a class="btn-100" href="#">100</a>
<a class="btn-500" href="#">500</a>
<a class="btn-1250" href="#">1250</a>
Just add some animation delay:
.btn-500 {
animation-delay: 0.6s;
}
.btn-1250 {
animation-delay: 1.3s;
}
Demonstration:
a {
padding: 6px;
display: block;
width: 50px;
font-size: 17px;
margin: 10px auto;
border: 2px solid;
text-decoration: none;
box-shadow: 0 0 0 rgba(204, 169, 44, 0.4);
animation: pulse 2s infinite;
}
.btn-500 {
animation-delay: 0.6s;
}
.btn-1250 {
animation-delay: 1.3s;
}
#keyframes pulse {
0% {
-moz-box-shadow: 0 0 0 0 rgba(204, 169, 44, 0.4);
box-shadow: 0 0 0 0 rgba(204, 169, 44, 0.4);
}
70% {
-moz-box-shadow: 0 0 0 10px rgba(255, 208, 0, 0.2);
box-shadow: 00 0 0 10px rgba(255, 208, 0, 0.2);
}
100% {
-moz-box-shadow: 0 0 0 0 rgba(204, 169, 44, 0);
box-shadow: 0 0 0 0 rgba(204, 169, 44, 0);
}
}
<a class="btn-100" href="#">100</a>
<a class="btn-500" href="#">500</a>
<a class="btn-1250" href="#">1250</a>
View on jsFiddle
I want to make a CSS3 animation where a div gets a box shadow on mouse over, and loses it on mouse out. This is what I have so far:
HTML:
<div id="page">
<div id="container" onmouseover="mouseOverContainer()" onmouseout="mouseOutContainer()" class="">
</div>
</div>
JS:
var container = undefined;
function assignContainer() {
if(container===undefined) {
container = document.getElementById("container");
}
}
function mouseOverContainer() {
assignContainer();
container.className="container-in";
}
function mouseOutContainer() {
assignContainer();
container.className="container-out";
}
CSS:
#keyframes box-shadow-anim-in{
from {
box-shadow: 0 0 0 rgba(0,0,0,0.0);
background-color: #ccc;
margin-top: 20px;
margin-top: 20px;
}
to {
box-shadow: 0 0 250px rgba(127,127,127,1.0);
background-color: #efefef;
margin-top: 18px;
margin-top: 18px;
}
}
#-o-keyframes box-shadow-anim-in{
from {
-o-box-shadow: 0 0 0 rgba(0,0,0,0.0);
background-color: #ccc;
margin-top: 20px;
}
to {
-o-box-shadow: 0 0 250px rgba(127,127,127,1.0);
background-color: #efefef;
margin-top: 18px;
}
}
#-webkit-keyframes box-shadow-anim-in{
from {
-webkit-box-shadow: 0 0 0 rgba(0,0,0,0.0);
background-color: #ccc;
margin-top: 20px;
}
to {
-webkit-box-shadow: 0 0 250px rgba(127,127,127,1.0);
background-color: #efefef;
margin-top: 18px;
}
}
#-ms-keyframes box-shadow-anim-in{
from {
-ms-box-shadow: 0 0 0 rgba(0,0,0,0.0);
background-color: #ccc;
margin-top: 20px;
}
to {
-ms-box-shadow: 0 0 250px rgba(127,127,127,1.0);
background-color: #efefef;
margin-top: 18px;
}
}
#-moz-keyframes box-shadow-anim-in {
from {
-moz-box-shadow: 0 0 0 rgba(0,0,0,0.0);
background-color: #ccc;
margin-top: 20px;
}
to {
-moz-box-shadow: 0 0 250px rgba(127,127,127,1.0);
background-color: #efefef;
margin-top: 18px;
}
}
#keyframes box-shadow-anim-out{
from {
box-shadow: 0 0 250px rgba(127,127,127,1.0);
background-color: #efefef;
margin-top: 18px;
}
to {
box-shadow: 0 0 0 rgba(0,0,0,0.0);
background-color: #ccc;
margin-top: 20px;
}
}
#-moz-keyframes box-shadow-anim-out{
from {
-moz-box-shadow: 0 0 250px rgba(127,127,127,1.0);
background-color: #efefef;
margin-top: 18px;
}
to {
-moz-box-shadow: 0 0 0 rgba(0,0,0,0.0);
background-color: #ccc;
margin-top: 20px;
}
}
#-o-keyframes box-shadow-anim-out{
from {
-o-box-shadow: 0 0 250px rgba(127,127,127,1.0);
background-color: #efefef;
margin-top: 18px;
}
to {
-o-box-shadow: 0 0 0 rgba(0,0,0,0.0);
background-color: #ccc;
margin-top: 20px;
}
}
#-webkit-keyframes box-shadow-anim-out {
from {
-webkit-box-shadow: 0 0 250px rgba(127,127,127,1.0);
background-color: #efefef;
margin-top: 18px;
}
to {
-webkit-box-shadow: 0 0 0 rgba(0,0,0,0.0);
background-color: #ccc;
margin-top: 20px;
}
}
#-ms-keyframes box-shadow-anim-out{
from {
-ms-box-shadow: 0 0 250px rgba(127,127,127,1.0);
background-color: #efefef;
margin-top: 18px;
}
to {
-ms-box-shadow: 0 0 0 rgba(0,0,0,0.0);
background-color: #ccc;
margin-top: 20px;
}
}
#page {
width: 900px;
margin: 0 auto;
}
#container {
width: 60%;
height: 250px;
background-color: #ccc;
margin-top: 20px;
border: 1px solid #999;
}
.container-out {
animation: box-shadow-anim-out 0.3s;
-moz-animation: box-shadow-anim-out 0.3s;
-webkit-animation: box-shadow-anim-out 0.3s;
-o-animation: box-shadow-anim-out 0.3s;
-ms-animation: box-shadow-anim-out 0.3s;
animation-fill-mode: forwards;
-moz-animation-fill-mode: forwards;
-o-animation-fill-mode: forwards;
-ms-animation-fill-mode: forwards;
-webkit-animation-fill-mode: forwards;
}
.container-in {
animation: box-shadow-anim-in 0.3s;
-moz-animation: box-shadow-anim-in 0.3s;
-webkit-animation: box-shadow-anim-in 0.3s;
-o-animation: box-shadow-anim-in 0.3s;
-ms-animation: box-shadow-anim-in 0.3s;
animation-fill-mode: forwards;
-moz-animation-fill-mode: forwards;
-o-animation-fill-mode: forwards;
-ms-animation-fill-mode: forwards;
-webkit-animation-fill-mode: forwards;
}
Everything works fine, as you can see in this JSFiddle.
But, as you can see, we have to define browser-specific keyframes in order to make it work on all browsers.
It's a bit boring, especially when you have to change one small detail in one animation, because you have to change all other browser-specific animations too.
I thought I could use just one block, inserting all keyframes separated by comma, like this:
#keyframes box-shadow-anim-in,
#-o-keyframes box-shadow-anim-in,
#-webkit-keyframes box-shadow-anim-in,
#-ms-keyframes box-shadow-anim-in,
#-moz-keyframes box-shadow-anim-in {
from {
box-shadow: 0 0 0 rgba(0,0,0,0.0);
-o-box-shadow: 0 0 0 rgba(0,0,0,0.0);
-webkit-box-shadow: 0 0 0 rgba(0,0,0,0.0);
-ms-box-shadow: 0 0 0 rgba(0,0,0,0.0);
-moz-box-shadow: 0 0 0 rgba(0,0,0,0.0);
background-color: #ccc;
margin-top: 20px;
}
to {
box-shadow: 0 0 250px rgba(127,127,127,1.0);
-o-box-shadow: 0 0 250px rgba(127,127,127,1.0);
-webkit-box-shadow: 0 0 250px rgba(127,127,127,1.0);
-ms-box-shadow: 0 0 250px rgba(127,127,127,1.0);
-moz-box-shadow: 0 0 250px rgba(127,127,127,1.0);
background-color: #efefef;
margin-top: 18px;
}
}
#keyframes box-shadow-anim-out,
#-o-keyframes box-shadow-anim-out,
#-webkit-keyframes box-shadow-anim-out,
#-ms-keyframes box-shadow-anim-out,
#-moz-keyframes box-shadow-anim-out {
from {
box-shadow: 0 0 250px rgba(127,127,127,1.0);
-o-box-shadow: 0 0 250px rgba(127,127,127,1.0);
-webkit-box-shadow: 0 0 250px rgba(127,127,127,1.0);
-ms-box-shadow: 0 0 250px rgba(127,127,127,1.0);
-moz-box-shadow: 0 0 250px rgba(127,127,127,1.0);
background-color: #efefef;
margin-top: 18px;
}
to {
box-shadow: 0 0 0 rgba(0,0,0,0.0);
-o-box-shadow: 0 0 0 rgba(0,0,0,0.0);
-webkit-box-shadow: 0 0 0 rgba(0,0,0,0.0);
-ms-box-shadow: 0 0 0 rgba(0,0,0,0.0);
-moz-box-shadow: 0 0 0 rgba(0,0,0,0.0);
background-color: #ccc;
margin-top: 20px;
}
}
But this doesn't seem to work (JSFiddle here), so maybe I'm doing something wrong or I just can't do it like this.
Is it possible to do something like this? If yes, how?
No, it's not possible with CSS. You can't group different at-rules together, much like how you can't group vendor-prefixed selectors.
You could resort to using a Sass/LESS mixin, but that's assuming you're working with a preprocessor already, and that just outputs separate duplicate CSS rules anyway.
For what it's worth, there are several prefixes that can be removed to reduce some of the bloat in your CSS:
#-ms-keyframes and -ms-animation are not used by any stable version of IE; IE10 supports them unprefixed right out of the box
Firefox also supports unprefixed #keyframes/animation, starting from version 16
-ms-box-shadow and -o-box-shadow have never existed, so they should be removed/unprefixed
-moz-box-shadow is only required by Firefox 3.5 and 3.6, neither of which support CSS animations (not even via #-moz-keyframes — that was added in version 5), so it should be unprefixed
You should also place the prefixless item last instead of first, to ensure (by the cascade) that it takes precedence over the prefixed item in browsers that support it.
This is not possible without a preprocessor such as SASS or LESS.
But, there is another option using JS. Take a look here: http://leaverou.github.io/prefixfree/
I would personally suggest you switch over to a CSS preprocessor, as it will undoubtedly be handy in the future.