I created a CSS3 animation that works as intended, but on Internet Explorer the rotation is very jittery.
I'm creating a spinner loading indicator so I use CSS animations to do a transform: rotate(...);. On Chrome and other browsers, the rotation is smooth, but on Internet Explorer it appears slightly wobbly.
I tried setting the transform-origin: center, tried using straight pixel values instead of em units and various other things, but nothing seemed to work.
Any ideas on how to improve this animation?
If I make the "track" (border-color) that the quadrant spins upon completely transparent, it makes the effect less noticeable, but I figured I'd ask in case anyone has any ideas.
.loading {
display: inline-block;
font-size: 20px;
height: 1em;
width: 1em;
margin: 0 auto;
position: relative;
-webkit-animation: loading 1s infinite linear;
-moz-animation: loading 1s infinite linear;
animation: loading 1s infinite linear;
border-left: 0.25em solid rgba(0, 0, 0, .3);
border-right: 0.25em solid rgba(0, 0, 0, .3);
border-bottom: 0.25em solid rgba(0, 0, 0, .3);
border-top: 0.25em solid rgba(0, 0, 0, .8);
border-radius: 100%;
vertical-align: middle;
margin: 0 0.5em;
}
.loading * { display: none; }
#keyframes loading { from { transform:rotate(0deg); } to { transform:rotate(360deg); } }
#-moz-keyframes loading { from { -moz-transform:rotate(0deg); } to { -moz-transform:rotate(360deg); } }
#-webkit-keyframes loading { from { -webkit-transform:rotate(0deg); } to { -webkit-transform:rotate(360deg); } }
<div class="loading"></div>
So, I ended up using a 256x256 transparent PNG to replicate the effect without using CSS borders, due to IE not being able to render perfect circles with border-radius.
.loading {
display: inline-block;
font-size: 20px;
height: 1em;
width: 1em;
margin: 0 auto;
position: relative;
-webkit-animation: loading 1s infinite linear;
-moz-animation: loading 1s infinite linear;
animation: loading 1s infinite linear;
/*
**border-left: 0.25em solid rgba(0, 0, 0, .3);
**border-right: 0.25em solid rgba(0, 0, 0, .3);
**border-bottom: 0.25em solid rgba(0, 0, 0, .3);
**border-top: 0.25em solid rgba(0, 0, 0, .8);
*/
background-image: url(../images/loading.png);
background-size: 100% 100%;
border-radius: 100%;
vertical-align: middle;
margin: 0 0.5em;
}
Related
I made a button animation with CSS. If the cursor is hover at the button, the button will shrink, and when its not, its gonna grow. However, when you hover at the button, it keeps playing the animation after 2 seconds. Can you help me fix that?
button{
text-decoration: none;
border: none;
padding: 8px 30px;
background-color: green;
color: #fff;
outline: none;
box-shadow: 7px 6px 28px 1px rgba(0, 0, 0, 0.24);
border-radius: 5px;
cursor: pointer;
animation: goForward;
animation-play-state: running;
animation-iteration-count: 1;
animation-duration: 2s;
}
button:hover{
animation: goBack;
animation-play-state: running;
animation-duration: 2s;
animation-iteration-count: 1;
}
#keyframes goBack{
from{transform: scale(1)}
to{transform: scale(0.72)}
}
#keyframes goForward{
from{transform: scale(0.72)}
to{transform: scale(1)}
}
Better and simple approach is to use transition than animation.
button {
text-decoration: none;
border: none;
padding: 8px 30px;
background-color: green;
color: #fff;
outline: none;
box-shadow: 7px 6px 28px 1px rgba(0, 0, 0, 0.24);
border-radius: 5px;
cursor: pointer;
transform: scale(1);
transition: transform ease 2s;
}
button:hover {
transform: scale(0.72);
}
<button>Click Me</button>
I'm working on a CSS slider animation.
Everything is pretty much done apart from one last thing:
The wanted behaviour is that if I hover over the slider thumb, the slider grows in height and the value moves in the centre of the slider. This works as expected, however when the slider thumb goes underneath the newly positioned value, it goes back to the previous size (basically reverting the animation).
I think that I need some sort of "pass-through", so that basically even if I'm not technically hovering on the slider, the value doesn't interfere at all with my animation.
I know, it is not clear at all, that's why I'm including a codepen to help you better understand what I mean. Change the slider and stop it at 29. Then try sliding again and you will see the wrong effect and what I mean.
https://codepen.io/NickHG/pen/NYOoXR?editors=0110
I'm also posting the code here for future reference: (note: is done using LESScss):
#temp0-14: #185fb6;
#temp15-19: #00bcd4;
#temp20-23: #ffc107;
#temp24-31: #ef6b52;
#gaps: 8, 4, 4, 15;
#temps: #temp24-31, #temp20-23,#temp15-19, #temp0-14;
#darkText: #000;
#lightText: #fff;
#percentage: 20%;
#desaturate-percentage: 40%;
.gaps-loop(#i, #prevgap) when (#i > 0) {
#gap: extract(#gaps, #i);
#temp: extract(#temps, #i);
.span-gen-loop(#j) when (#j < #gap) {
#k: #j + #prevgap;
.temp-#{k} {
display: block;
background: #temp;
color: contrast(#temp, #darkText, #lightText, #percentage);
&:hover {
//background: darken(#temp, 8%);
}
}
.temp-color-#{k} {
color: contrast(#temp, #darkText, #lightText, #percentage);
}
.span-gen-loop(#j + 1);
}
.span-gen-loop(0);
.gaps-loop(#i - 1, #prevgap + #gap);
}
.gaps-loop(length(#gaps), 0);
.animate-color-change {
transition: background 0.8s ease;
}
/* Slider custom style */
#entryHeight: 60px;
#sliderTrackHeight: 25px;
#sliderThumbHeight: #sliderTrackHeight;
#sliderThumbWidth: 25px;
.entry-external-container {
font-family: "Roboto", sans-serif;
height: #entryHeight;
min-height: #entryHeight;
width: 100%;
max-width: 400px;
display: block;
border: 1px solid black;
display: flex;
align-items: flex-end;
padding: 0;
margin: 0;
position: relative;
.dataName {
display: block;
width: 100%;
position: absolute;
top: 0;
transform: translateY(50%);
padding-left: 10px;
z-index: 2;
animation-timing-function: ease-out;
animation: dataNameIn 0.4s forwards;
}
.dataValue {
display: block;
width: 25px;
position: absolute;
top: 0;
text-align: right;
right: 10px;
transform: translateY(50%);
padding-right: 10px;
z-index: 2;
animation-timing-function: ease-in-out;
animation: dataValueZoomOut 0.1s forwards;
}
.slidecontainer {
width: 100%;
box-sizing: content-box;
.custom-slider {
-webkit-appearance: none;
appearance: none;
width: 100%;
height: #sliderTrackHeight;
outline: none;
opacity: 0.7;
margin: 0;
animation: sliderAnimationBackgroundOut 0.3s;
&::-webkit-slider-thumb {
-webkit-appearance: none;
appearance: none;
width: #sliderThumbWidth;
height: #sliderThumbHeight;
background: white;
cursor: pointer;
transition: height 0.25s, box-shadow 0.4s;
border: 1px solid rgba(0, 0, 0, 0.6);
box-sizing: border-box;
border-radius: 3px;
}
&:hover,
&:active {
&~.dataName {
animation: dataNameOut 0.4s forwards;
}
&~.dataValue {
animation: dataValueZoomIn 0.4s forwards;
&:hover{pointer-events:none;}
}
animation: sliderAnimationBackgroundIn 0.3s forwards;
&::-webkit-slider-thumb {
border-radius: 0px 3px 3px 0;
height: #entryHeight;
box-sizing: border-box;
border-right: 1px solid rgba(0, 0, 0, 0.5);
border-top: 1px solid rgba(0, 0, 0, 0.5);
border-bottom: 1px solid rgba(0, 0, 0, 0.5);
border-left: none;
-webkit-box-shadow: -7px 0px 7px -2px rgba(0, 0, 0, 0.2);
-moz-box-shadow: -7px 0px 7px -2px rgba(0, 0, 0, 0.2);
box-shadow: -7px 0px 7px -2px rgba(0, 0, 0, 0.2);
background: -webkit-gradient(
linear,
-20 0,
100% 0,
from(transparent),
to(white),
color-stop(80%, white)
);
}
}
}
}
}
#keyframes sliderAnimationBackgroundIn {
0% {
opacity: 0.7;
height: #sliderTrackHeight;
}
100% {
opacity: 1;
height: #entryHeight;
}
}
#keyframes sliderAnimationBackgroundOut {
0% {
opacity: 1;
height: #entryHeight;
}
100% {
opacity: 0.7;
height: #sliderTrackHeight;
}
}
#keyframes dataNameOut {
0% {opacity: 1;top: 0}
20% {opacity: 0;top: -15px}
100% {top: -40px;opacity: 0}
}
#keyframes dataNameIn {
0% {top: -40px;opacity: 0}
20% {opacity: 0;top: -15px}
100% {opacity: 1;top: 0}
}
#keyframes dataValueZoomIn {
0% { transform: scale(1); top: 5px; right: 7.5px;}
25% { transform: scale(1.2); top: 10px; right: 10px;}
50% { transform: scale(1.3); top: 15px;right: 11px;}
75% { transform: scale(1.4); top: 20px;right: 13px;}
100% { transform: scale(1.5);top: 20px;right: 13.7px;}
}
#keyframes dataValueZoomOut {
100% { transform: scale(1); top: 5px; right: 7.5px;}
75% { transform: scale(1.2); top: 10px; right: 10px;}
50% { transform: scale(1.3); top: 15px;right: 11px;}
25% { transform: scale(1.4); top: 20px;right: 13px;}
0% { transform: scale(1.5);top: 20px;right: 13.7px;}
}
use pointer-events to prevent an element from being hovered :
The pointer-events CSS property specifies under what circumstances (if
any) a particular graphic element can become the target of mouse
events.
.dataValue {
pointer-events: none;
}
PEN
You could achieve the same effect setting the hover state to the parent.
PEN
.slidecontainer {
width: 100%;
box-sizing: content-box;
&:hover {
.custom-slider {
...
}
}
}
Note: Is not a good practice to nest more than 3 levels deep,
I'm building a very simple bounce card animation, however at some point the animation got reseted and the result is not fluent.
Please check:
div{
width: 110px;
height: 50px;
background: #EEE;
border: 1px solid #BBB;
border-radius: 3px;
padding: 3px 5px;
font-family: sans-serif;
left: 200px;
position: absolute;
}
#keyframes cardBouncing {
20%, 60%, to {
transform: rotate3d(0, 0, 1, 80deg);
transform-origin: top left;
animation-timing-function: ease-in-out;
}
0%, 40%, 80% {
transform: rotate3d(0, 0, 1, 60deg);
transform-origin: top left;
animation-timing-function: ease-in-out;
}
}
div{
box-shadow: 3px 3px 10px grey;
animation: 1.5s cardBouncing infinite; //flipInX;
}
<div>HOla!</div>
How I can make it bouncing without that "jump"
This is for a drag animation, how can I center in the mouse cursor position? It seems like it go to much at the left. It's possible?
The solution is with: animation-direction: alternate-reverse;
div{
width: 110px;
height: 50px;
background: #EEE;
border: 1px solid #BBB;
border-radius: 3px;
padding: 3px 5px;
font-family: sans-serif;
position: absolute;
left: 180px;
}
#keyframes cardBouncing {
from {
transform: rotate3d(0, 0, 1, 60deg);
transform-origin: top left;
animation-timing-function: ease-in-out;
}
to {
transform: rotate3d(0, 0, 1, 80deg);
transform-origin: top left;
animation-timing-function: ease-in-out;
}
}
div{
box-shadow: 3px 3px 10px grey;
animation: 0.4s cardBouncing infinite;
animation-direction: alternate-reverse;
}
<div> Hola! </div>
I created a button. This button is defined by these CSS properties:
#button {
width: 50px;
height: 50px;
border: 3px solid #F1F2F0;
text-align:center;
background-color: #02BFC1;
display: table;
position: absolute;
margin: auto;
top: 0;
bottom: 0;
left: 0;
right:0;
-webkit-transition: all 0.5s ease;
cursor: pointer;
box-shadow: 0px 0px 30px rgba(0,0,0,0.4);
animation: blinker 2s ease infinite;
}
This button blinks using the animation blinker that smoothly changes the background-color from a darker to a lighter blue, defined like this:
#keyframes blinker {
50% { background-color: #03FCFF; }
}
It also has a hover animation:
#button:hover {
background-color: #F37C2B;
transform: scale(1.1);
box-shadow: 0px 0px 70px rgba(0,0,0,0.4);
animation-name: none;
}
My problem is this: the hover animation used to be completely smooth before I added the blinker animation. Now, it just instantly changes background-colorto the orange, while the transform: scale(1.1) still changes smoothly.
How can I make it so that hovering the button pauses the blinker animation and smoothly changes background-color, and that the animation resumes by mouse-leaving the button? If possible, I would like to use only CSS for this and no js.
If you prefer, you can modify this JSFiddle to respond.
EDIT: This doesn't work only on chrome, how can I make it so it does?
You have too many things going on in your CSS. As a general rule try to keep things as simple as possible if you want your code to be fast and efficient.
Here is your working code with some explanations:
button {
width: 50px;
height: 50px;
display: block;
border: 3px solid #F1F2F0;
background-color: #02BFC1;
margin: 30px auto;
cursor: pointer;
box-shadow: 0px 0px 30px rgba(0, 0, 0, 0.4);
animation: 2s ease infinite blinker;
transition: background-color .5s ease, transform .5s ease, box-shadow .5s ease; /* it is best to select the properties you want to transition instead of using 'all' */
}
#keyframes blinker {
50% {
background-color: #03FCFF;
}
}
button:hover {
background-color: #F37C2B;
box-shadow: 0px 0px 70px rgba(0, 0, 0, 0.4);
animation: none;
transform: scale(1.1);
}
<button></button>
Don't forget to use the prefixes needed for your project.
I'm using CSS animations (from animate.css) in a project I'm working on.
What I found out is that when fading in a container with an absolutely positioned and z-indexed child in it, the z-index of the child isn't working as it should.
I recreated the issue in this fiddle:
http://jsfiddle.net/Lxsf9ako/
The issue seems to be caused by
animation-fill-mode: both;
This style is placed on the container by animate.css, thus I have no control over this. I could overwrite it by using animation-fill-mode: none, but I rather don't do this for every animation.
Any ideas on this one?
Update:
I just found out this is webkit related, IE11 renders this correctly.
Update 2:
I can't edit the .container class on hover.
Update 3:
The 'hover' in the Fiddle is just a demo. In fact, the .over object is the popup from the angular-ui-bootstrap datepicker directive, and the .container elements are generic elements used throughout the application. Giving them an extra id/class to identify them as datepicker containers is not a clean solution for me.
Just add
#hoverme{
z-index: 1;
}
DEMO
Why you have to do this
Without any z-index value, elements stack in the order that they
appear in the DOM (the lowest one down at the same hierarchy level
appears on top). Elements with non-static positioning will always
appear on top of elements with default static positioning.
Also note that nesting plays a big role. If an element B sits on top
of element A, a child element of element A can never be higher than
element B.
From css-tricks.com
#hoverme {
z-index: 1;
}
.container {
background: rgb(255, 255, 255);
/* Old browsers */
background: -webkit-gradient(linear, 0 0, 0 100%, from(#fff), to(#efefef));
background: -webkit-linear-gradient(#fff 0%, #efefef 100%);
background: -moz-linear-gradient(#fff 0%, #efefef 100%);
background: -o-linear-gradient(#fff 0%, #efefef 100%);
background: linear-gradient(#fff 0%, #efefef 100%);
filter: progid: DXImageTransform.Microsoft.gradient(startColorstr='#ffffff', endColorstr='#efefef', GradientType=0);
/* IE6-9 */
font-family: 'Helvetica Neue', Helvetica, Arial, sans-serif;
display: block;
width: 100%;
border: 1px solid #c7c7c7;
margin-bottom: 10px;
position: relative;
padding: 20px;
box-sizing: border-box;
-webkit-animation-name: fadeIn;
/* Safari, Chrome and Opera > 12.1 */
-moz-animation-name: fadeIn;
/* Firefox < 16 */
-ms-animation-name: fadeIn;
/* Internet Explorer */
-o-animation-name: fadeIn;
/* Opera < 12.1 */
animation-name: fadeIn;
-webkit-animation-duration: 1s;
-moz-animation-duration: 1s;
-ms-animation-duration: 1s;
-o-animation-duration: 1s;
animation-duration: 1s;
-webkit-animation-fill-mode: both;
-moz-animation-fill-mode: both;
-ms-animation-fill-mode: both;
-o-animation-fill-mode: both;
animation-fill-mode: both;
}
#hoverme .over {
display: none;
padding: 20px;
position: absolute;
top: 20px;
left: 20px;
width: 200px;
background: #efefef;
z-index: 10;
box-sizing: border-box;
-webkit-box-shadow: 2px 2px 4px 0px rgba(0, 0, 0, 0.75);
-moz-box-shadow: 2px 2px 4px 0px rgba(0, 0, 0, 0.75);
box-shadow: 2px 2px 4px 0px rgba(0, 0, 0, 0.75);
}
#hoverme:hover .over {
display: block;
}
#keyframes fadeIn {
0% {
opacity: 0;
}
100% {
opacity: 1;
}
}
/* Firefox < 16 */
#-moz-keyframes fadeIn {
0% {
opacity: 0;
}
100% {
opacity: 1;
}
}
/* Safari, Chrome and Opera > 12.1 */
#-webkit-keyframes fadeIn {
0% {
opacity: 0;
}
100% {
opacity: 1;
}
}
/* Internet Explorer */
#-ms-keyframes fadeIn {
0% {
opacity: 0;
}
100% {
opacity: 1;
}
}
/* Opera < 12.1 */
#-o-keyframes fadeIn {
0% {
opacity: 0;
}
100% {
opacity: 1;
}
}
<div id="hoverme" class="container">
<div class="over">I should be over the next container</div>
</div>
<div class="container">I should be under the .over</div>
Update
You could also use a transition on the .over with opacity and visibility.
#hoverme .over {
opacity: 0;
visibility:hidden;
transition:visibility 0.4s, opacity 0.4s;
...
}
#hoverme:hover .over {
visibility:visible;
opacity:1;
}
DEMO
.container {
background: rgb(255, 255, 255);
/* Old browsers */
background: -webkit-gradient(linear, 0 0, 0 100%, from(#fff), to(#efefef));
background: -webkit-linear-gradient(#fff 0%, #efefef 100%);
background: -moz-linear-gradient(#fff 0%, #efefef 100%);
background: -o-linear-gradient(#fff 0%, #efefef 100%);
background: linear-gradient(#fff 0%, #efefef 100%);
filter: progid: DXImageTransform.Microsoft.gradient(startColorstr='#ffffff', endColorstr='#efefef', GradientType=0);
/* IE6-9 */
font-family: 'Helvetica Neue', Helvetica, Arial, sans-serif;
display: block;
width: 100%;
border: 1px solid #c7c7c7;
margin-bottom: 10px;
position: relative;
padding: 20px;
box-sizing: border-box;
}
#hoverme .over {
opacity: 0;
visibility: hidden;
transition: visibility 0.4s, opacity 0.4s;
padding: 20px;
position: absolute;
top: 20px;
left: 20px;
width: 200px;
background: #efefef;
z-index: 10;
box-sizing: border-box;
-webkit-box-shadow: 2px 2px 4px 0px rgba(0, 0, 0, 0.75);
-moz-box-shadow: 2px 2px 4px 0px rgba(0, 0, 0, 0.75);
box-shadow: 2px 2px 4px 0px rgba(0, 0, 0, 0.75);
}
#hoverme:hover .over {
visibility: visible;
opacity: 1;
}
<div id="hoverme" class="container">
<div class="over">I should be over the next container</div>
</div>
<div class="container">I should be under the .over</div>
You could change the z-index of the container on hover. Try this:
.container:hover {
z-index:100;
}
Check this http://jsfiddle.net/Lxsf9ako/2/