Is there a way to group browser-specific css3 animations? - html

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.

Related

CSS infinite ripple animation

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>

On hover change animation with transition

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.

Chain/sequence animation in CSS [duplicate]

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

CSS transition doesn't work

section#lBox{
background-color: rgb(168, 0, 0);
border: 1px solid rgba(0,0,0,.15);
border-radius: 0px;
box-shadow: 0 1px 0 rgba(255,255,255,0.2) inset, 0 0 4px rgba(0,0,0,0.2);
margin: 100px auto; /*aligns center*/
padding: 24px;
width: 500px;
opacity: 0.5;
-webkit-transition: all 5s linear;
transition: background-color 5s;
-moz-transition: all 5s linear;
}
section#lbox:hover {
/*background-color: rgba(168, 0, 0, 0.8);
box-shadow: 0px 0px 500px; */
opacity: 0.8;
}
I have been trying to fix it for half an hour and can't seem to find why the transition isn't working. It is supposed to make the translucent box more opaque when the mouse cursor is over it.
Look at this:
section#lBox {
That has a capital letter B in lBox.
Then look at this:
section#lbox:hover {
This has a lowercase b in lbox.
Assuming your box has an id="lBox", the hover opacity: 0.8 part will not work, as CSS is case-sensitive, and lbox and lBox are two different things.
So what you should do is just change this:
section#lbox:hover {
To this:
section#lBox:hover {
And it should work.

Animated submit/progress buttons with pure css3

How can someone achieve the effect shown here using pure css3.
Using this (pure CSS/without javascript):
Animated progress circle in CSS
Using the :target selector
I create an example, Probably still not what you are looking for, but it was the closest I came.
Example (Demo in jsfiddle):
<style>
#-webkit-keyframes rotate {
from {
-webkit-transform: rotate(0deg);
}
to {
-webkit-transform: rotate(360deg);
}
}
#-moz-keyframes rotate {
from {
-moz-transform: rotate(0deg);
}
to {
-moz-transform: rotate(360deg);
}
}
#-o-keyframes rotate {
from {
-o-transform: rotate(0deg);
}
to {
-o-transform: rotate(360deg);
}
}
#keyframes rotate {
from {
transform: rotate(0deg);
}
to {
transform: rotate(360deg);
}
}
#startupload:target {
/*"disable" button*/
background: transparent;
border: none;
}
#startupload:target div.before {
/*Hide If has hash in url address browser*/
display: none;
}
#startupload div.progress-circle-container {
position: relative;
height: 230px;
width: 230px;
margin: 0 auto;
display: none; /*hide If no Hash in address*/
}
#startupload:target div.progress-circle-container {
display: block; /*Show If Hash in address*/
}
#startupload div.progress-circle-container div.progress-circle-outer {
background-color: #faef85;
background-repeat: repeat-x;
background-image: -moz-linear-gradient(0deg, #d66f0f, #faef85);
background-image: -webkit-linear-gradient(0deg, #d66f0f, #faef85);
background-image: -o-linear-gradient(0deg, #d66f0f, #faef85);
background-image: linear-gradient(0deg, #d66f0f, #faef85);
width: 230px;
height: 230px;
position: absolute;
-webkit-animation-play-state: paused;
-moz-animation-play-state: paused;
-o-animation-play-state: paused;
animation-play-state: paused;
-webkit-animation: rotate 2.2s infinite linear;
-moz-animation: rotate 2.2s infinite linear;
-o-animation: rotate 2.2s infinite linear;
animation: rotate 2.2s infinite linear;
-webkit-box-shadow: inset 0 2px 10px #d58513,inset 0 0 20px #b93d00,0 0 15px rgba(216, 140, 23, 0.25);
-moz-box-shadow: inset 0 2px 10px #d58513,inset 0 0 20px #b93d00,0 0 15px rgba(216, 140, 23, 0.25);
box-shadow: inset 0 2px 10px #d58513,inset 0 0 20px #b93d00,0 0 15px rgba(216, 140, 23, 0.25);
-webkit-border-radius: 200px;
-moz-border-radius: 200px;
border-radius: 200px;
}
#startupload:target div.progress-circle-container div.progress-circle-outer.animate {
-webkit-animation-play-state: running;
-moz-animation-play-state: running;
-o-animation-play-state: running;
animation-play-state: running;
}
#startupload div.progress-circle-container div.progress-circle-inner {
height: 170px;
width: 170px;
margin: 0 auto;
position: absolute;
left: 30px;
top: 30px;
-webkit-border-radius: 200px;
-moz-border-radius: 200px;
border-radius: 200px;
background-color: #fff;/*change color background*/
-webkit-box-shadow: inset 0 2px 1px #ffffff,inset 0 -1px 1px rgba(0, 0, 0, 0.08),inset 0 -3px 1px rgba(0, 0, 0, 0.09),0 2px 2px rgba(0, 0, 0, 0.3);
-moz-box-shadow: inset 0 2px 1px #ffffff,inset 0 -1px 1px rgba(0, 0, 0, 0.08),inset 0 -3px 1px rgba(0, 0, 0, 0.09),0 2px 2px rgba(0, 0, 0, 0.3);
box-shadow: inset 0 2px 1px #ffffff,inset 0 -1px 1px rgba(0, 0, 0, 0.08),inset 0 -3px 1px rgba(0, 0, 0, 0.09),0 2px 2px rgba(0, 0, 0, 0.3);
text-align: center;
}
</style>
<form action="#startupload">
<button id="startupload" type="submit">
<div class="before">
Start upload
</div>
<div class="progress-circle-container">
<div class="progress-circle-outer animate">
</div>
<div class="progress-circle-inner"></div>
</div>
</button>
</form>
Perhaps the ultimate goal to achieve the best is something like:
css3 animations frame by frame