i want to move the "letsgo" div to animate from left-margin 100% to margin auto. i.e it stop at a point where left margin and right margin are equal. but i can't figure it out.
Please Help me.
My Code is given bellow:
<!DOCTYPE html>
<html lang="en">
<head>
<title>Do IT...</title>
<meta charset="UTF-8">
<style>
#letsgo{
height: 600px;
width: 500px;
border: 2px solid #64BBF0;
border-radius: 2px;
margin: auto;
position: relative;
animation-fill-mode: forwards;
box-shadow: 5px 5px 2px #64BBF0;
animation-name: miku;
animation-duration: 1s;
}
#keyframes miku{
0%{
margin-left: 100%;
}
100%{
margin: auto;
}
}
#doit{
height: 100px;
width: 100px;
border-radius: 50%;
background: yellow;
position: absolute;
top: 250px;
left: 200px;
}
.child{
height: 25px;
width:25px;
border-radius: 50%;
background: red;
position: absolute;
top: 287.5px;
left:237.5px;
}
*{
transition: all 2s ease-out;
}
#letsgo:hover .child{
box-shadow: -237.5px -287.5px red,
-237.5px 287.5px red,
237.5px -287.5px red,
237.5px 287.5px red,
237.5px 0 red,
-237.5px 0 red,
0 287.5px red,
0 -287.5px red;
}
}
</style>
</head>
<body>
<div id="letsgo">
<div id="doit"></div>
<div class="child"></div>
</div>
</body>
</html>
I know this is an old post, but if anyone is looking for another solution without absolute positioning, you can use margin and translate. Something like this:
0% {
margin-left: 100%;
transform: translateX(0%);
}
100% {
margin-left: 50%;
transform: translateX(-50%);
}
As Samih says, you can not animate properties between 2 non numeric values.
One posible way to do it is centering the div using left property (so you need absolute positioning) combined with margin:
#letsgo{
height: 600px;
width: 500px;
border: 2px solid #64BBF0;
border-radius: 2px;
margin: auto;
position: absolute;
box-shadow: 5px 5px 2px #64BBF0;
-webkit-animation-fill-mode: forwards;
-webkit-animation-name: miku;
-webkit-animation-duration: 3s;
-webkit-animation-iteration-count: infinite;
}
#-webkit-keyframes miku{
0% { margin-left: 0px;
left: 100%; }
100% { margin-left: -250px;
left: 50%; }
}
fiddle
I know it's just old question, but, you can also use calc() sinc you know width of centered element.
#letsgo {
margin-left:100%;
transition:all 1s;
}
#letsgo.animated {
margin-left:calc((100vw - 500px)/2);
}
Related
This question already has an answer here:
How to keep origin in center of image in scale animation?
(1 answer)
Closed 1 year ago.
So I'm trying to implement a loader that spins in the middle of the screen I have used transform:translate earlier do this ex:
position: absolute;
left:50%;
top:50%;
transform: translate(-50%,-50%);
I tried to implement something similar but instead of getting centered the top left appears to be in the center. Here's my code
HTML
<section class="waitwrapper" v-else>
<div class="loader"></div>
</section>
CSS
.waitwrapper{
background-color: #455879;
position: relative;
width: 98vw;
height: 97vh;
}
.loader{
border: 16px solid #f3f3f3;
border-top: 16px solid #455879; /* w3schools loader */
border-radius: 50%;
width: 20%;
aspect-ratio:1;
animation: spin 2s linear infinite;
position: absolute;
left:50%;
top:50%;
transform: translate(-50%,-50%);
}
#keyframes spin {
0% { transform: rotate(0deg); }
100% { transform: rotate(360deg); }
}
One trusted way to centralize one item is to use display: flex with justify-content: center and align-items: center in the parent element.
*, *::before, *::after{
box-sizing:border-box;
}
.waitwrapper{
background-color: #455879;
width: 98vw;
height: 97vh;
display:flex;
justify-content:center;
align-items:center
}
.loader{
border: 16px solid #f3f3f3;
border-top: 16px solid #455879; /* w3schools loader */
border-radius: 50%;
width: 20%;
aspect-ratio:1;
animation: spin 2s linear infinite;
}
#keyframes spin {
0% { transform: rotate(0deg); }
100% { transform: rotate(360deg); }
}
<section class="waitwrapper" v-else>
<div class="loader"></div>
</section>
But why your code doesn't work very well? I must tell you when you change transform property in your animation actually you overwrite it. And because of it transform: translate(-50%, -50%);, doesn't work enymore. For solve that problem you can use below solution
.waitwrapper{
background-color: #455879;
position: relative;
width: 98vw;
height: 97vh;
}
.loader{
border: 16px solid #f3f3f3;
border-top: 16px solid #455879; /* w3schools loader */
border-radius: 50%;
width: 20%;
aspect-ratio:1;
animation: spin 2s linear infinite;
position: absolute;
left:50%;
top:50%;
/* transform:translate(-50%,-50%); */
}
#keyframes spin {
0%{
transform: translate(-50%, -50%) rotate(0deg);
}
100% {
transform: translate(-50%, -50%) rotate(360deg);
}
}
<section class="waitwrapper" v-else>
<div class="loader"></div>
</section>
Don't use transform. Use display: flex; on the parent and margin: auto; on the spinner element — to center it both horizontally and vertically.
See the code comments for the needed changes:
/* Quick reset */ * {margin: 0; box-sizing: border-box; }
.loader-wrapper {
background-color: #455879;
position: fixed; /* why relative? use fixed! Should cover the page? */
z-index: 9999; /* overlay other elements */
width: 100vw;
height: 100vh;
display: flex; /* use display flex */
}
.loader {
height: 20%; /* use height instead of width */
aspect-ratio: 1;
margin: auto; /* center inside the flex parent */
border: 10px solid #f3f3f3;
border-top-color: transparent; /* use transparent instead */
border-radius: 50%;
animation: spin 2s linear infinite;
}
#keyframes spin {
to { transform: rotate(1turn); }
}
<section class="loader-wrapper">
<div class="loader"></div>
</section>
Here is one of the ways how to center position-absolute element with width set:
position: absolute;
margin-left: auto;
margin-right: auto;
margin-top: auto;
margin-bottom: auto;
left: 0;
right: 0;
top:0;
bottom:0;
width:20%;
Complete snippet:
.waitwrapper{
background-color: #455879;
position: relative;
width: 98vw;
height: 97vh;
}
.loader{
border: 16px solid #f3f3f3;
border-top: 16px solid #455879; /* w3schools loader */
border-radius: 50%;
aspect-ratio:1;
animation: spin 2s linear infinite;
position: absolute;
margin-left: auto;
margin-right: auto;
margin-top: auto;
margin-bottom: auto;
left: 0;
right: 0;
top:0;
bottom:0;
width:20%;
}
#keyframes spin {
0% { transform: rotate(0deg); }
100% { transform: rotate(360deg); }
}
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
</head>
<body>
<section class="waitwrapper" v-else>
<div class="loader"></div>
</section>
</body>
</html>
This question already has answers here:
Position absolute but relative to parent
(5 answers)
Closed 2 years ago.
here is my attempt to have overlay animation effect but overlay is not hiding after getting out of the underlying div- 'overflowTest'
#overflowTest {
background: #ff0000;
color: white;
padding: 15px;
width: 150px;
height: 100px;
overflow: hidden;
text-shadow: 6px 6px 5px black;
}
#box{
position: absolute;
width: 60px;
height: 60px;
border: 5px solid black;
animation-name: go;
animation-duration: 6s;
animation-fill-mode: forwards;
animation-iteration-count: infinite;
transform: rotate(45deg);
}
#keyframes go {
0%{
border: 3px solid red;
}
100%{
border: 3px solid red;
transform: translateX(200px);
}
}
<div id="overflowTest"><div id="box"></div><div id="hel">This is demo text to test overlay animation on it</div></div>
please help in hiding the overlay when it is outside the 'overflowTest' div
You need to add position: relative; to the parent #overflowTest.
An Element with position: absolute; will behave absolute to the first parent with a relative position. If no other is declared as relative, it will behave absolute to the page itself, which was happening before.
#overflowTest {
position: relative;
background: #ff0000;
color: white;
padding: 15px;
width: 150px;
height: 100px;
overflow: hidden;
text-shadow: 6px 6px 5px black;
}
#box{
position: absolute;
width: 60px;
height: 60px;
border: 5px solid black;
animation-name: go;
animation-duration: 6s;
animation-fill-mode: forwards;
animation-iteration-count: infinite;
transform: rotate(45deg);
}
#keyframes go {
0%{
border: 3px solid #ffaaaa;
}
100%{
border: 3px solid #ffaaaa;
transform: translateX(200px);
}
}
<div id="overflowTest">
<div id="box"></div>
<div id="hel">This is demo text to test overlay animation on it</div>
</div>
Hope that is what you are looking for!
The property you should use is z-index.
Setting z-index:-1; will help you get the desired result. z-index works only when position property is also added.
Try this,
#overflowTest {
background: #ff0000;
color: white;
padding: 15px;
width: 150px;
height: 100px;
overflow: hidden;
text-shadow: 6px 6px 5px black;
}
#box{
position: absolute;
width: 60px;
height: 60px;
border: 5px solid black;
animation-name: go;
animation-duration: 6s;
animation-fill-mode: forwards;
animation-iteration-count: infinite;
transform: rotate(45deg);
z-index:-1;
}
#keyframes go {
0%{
border: 3px solid red;
}
100%{
border: 3px solid red;
transform: translateX(200px);
}
}
<div id="overflowTest"><div id="box"></div><div id="hel">This is demo text to test overlay animation on it</div></div>
Hope it helps.!! Happy Coding!!
I first tried implementing it through two triangles. And got a satisfactory output
#wrapper {
margin-left: 40vw;
margin-top: 20vh;
}
#fidgetu {
width: 0;
height: 0;
position: absolute;
margin-top: 3vh;
border-left: 50px solid transparent;
border-right: 50px solid transparent;
border-bottom: 100px solid red;
animation: rotate 2s linear infinite;
}
#fidgetd {
width: 0;
height: 0;
position: absolute;
margin-top: 3vh;
border-left: 50px solid transparent;
border-right: 50px solid transparent;
border-top: 100px solid red;
animation: rotate 2s linear infinite;
}
#keyframes rotate {
from {
transform: rotate(0deg);
}
to {
transform: rotate(360deg);
}
}
<div id="wrapper">
<div id="fidgetu">
</div>
<div id="fidgetd">
</div>
</div>
I guess drawing a fidget spinner would require 4 div circles and 3 div rectangles to connect the central circle to the other three and a wrapper div (applying animate property to this div). But the positioning is messing up.
Now how do I position them appropriately such that the entire block rotates around its center?
Set an element as the base spinner, and then 3 childs of this one as the outer circles.
if the outer ones are positioned over the first one, just rotating the base elements will handle the rotation of the others.
A litlle tricky are the curves connecting the inner and the outer. I have set a solution, but there is some missalignment. It still needs a last adjustment on the pixel values (but it's hard to get it exactly)
.spinner, .outer {
width: 100px;
height: 100px;
border-radius: 50%;
position: absolute;
transform-style: preserve-3d;
}
.spinner {
background-color: teal;
border: solid 20px tomato;
margin: 100px;
animation: rotate 4s infinite linear;
}
.outer {
background-color: lightblue;
border: solid 20px blue;
left: -20px;
top: -20px;
}
.outer:before {
content: "";
position: absolute;
width: 150px;
height: 150px;
border-radius: 50%;
transform: translate(-91px, 104px);
box-shadow: 0px -55px 0px -33px blue;
}
.outer:after {
content: "";
position: absolute;
width: 150px;
height: 150px;
border-radius: 50%;
transform: translate(-83px, -156px);
box-shadow: 0px 55px 0px -33px blue;
}
.outer:nth-child(1) {
transform: translate3D(120px, 0px, -10px);
}
.outer:nth-child(2) {
transform: rotate(120deg) translate3D(120px, 0px, -10px);
}
.outer:nth-child(3) {
transform: rotate(240deg) translate3D(120px, 0px, -10px);
}
#keyframes rotate {
from {transform: rotate(0deg);}
to {transform: rotate(360deg);}
}
<div class="spinner">
<div class="outer"></div>
<div class="outer"></div>
<div class="outer"></div>
</div>
The title pretty much says it all but here is an example.
Let's say I have a CSS 'loading spinner' as below:
.spinner {
height: 50px;
width: 50px;
position: relative;
animation: rotate .6s infinite linear;
border-left: 6px solid #222;
border-right: 6px solid #222;
border-bottom: 6px solid #222;;
border-top: 6px solid #ccc;
border-radius: 100%;
}
#keyframes rotation {
from {
transform: rotate(0deg);
}
to {
transform: rotate(359deg);
}
}
I want to add a pseudo element to this - for example with content: 'loading...' before or after .spinner.
Is it possible to ensure the pseudo element does not inherit the animation from .spinner, or must a pseudo element always take what the parent has?
As the pseudo-element is a child element of the parent it will continue to get rotated as long as parent has the animation. Even setting animation: none on the pseudo element will have no effect.
The only way to make it look as though the child has no animation is to reverse the effect like shown in below snippet. What is being done is that the very same animation is added to the pseudo element but the animation-direction is set as reverse. This means that the pseudo get the exact reverse transform effect and thus would retain it in the same position.
.spinner {
height: 50px;
width: 50px;
position: relative;
animation: rotation .6s infinite linear;
border-left: 6px solid #222;
border-right: 6px solid #222;
border-bottom: 6px solid #222;
border-top: 6px solid #ccc;
border-radius: 100%;
}
.spinner:after {
position: absolute;
content: 'Loading..';
top: 0px;
left: 0px;
height: 100%;
width: 100%;
animation: rotation .6s infinite linear reverse; /* added this line */
}
#keyframes rotation {
from {
transform: rotate(0deg);
}
to {
transform: rotate(359deg);
}
}
<div class='spinner'></div>
The above snippet uses the default setting for transform-origin which is 50% 50% but if the child pseudo-element has padding and/or margin then the transform-origin setting has to be adjusted accordingly to avoid the pseudo-element from producing a shivering like effect. The calculation logic is provided in the below snippet.
.spinner {
height: 50px;
width: 50px;
position: relative;
animation: rotation .6s infinite linear;
border-left: 6px solid #222;
border-right: 6px solid #222;
border-bottom: 6px solid #222;
border-top: 6px solid #ccc;
border-radius: 100%;
}
.spinner.parent-padded-margin {
padding: 10px;
margin: 10px;
}
.spinner:after {
position: absolute;
content: 'Loading..';
top: 0px;
left: 0px;
height: 100%;
width: 100%;
animation: rotation .6s infinite linear reverse;
/* added this line */
}
.spinner.child-padded-margin:after {
padding: 10px 8px;
margin: 5px 4px;
transform-origin: calc(50% - 12px) calc(50% - 15px); /* calc(50% - ((padding-left + padding-right)/2 + margin-left)) calc(50% - ((padding-top + padding-bottom)/2 + margin-top)) */
}
.spinner.child-padded-margin-2:after {
padding: 10px 6px 16px 14px;
margin: 7px 12px 5px 10px;
transform-origin: calc(50% - 20px) calc(50% - 20px); /* calc(50% - ((padding-left + padding-right)/2 + margin-left)) calc(50% - ((padding-top + padding-bottom)/2 + margin-top)) */
}
#keyframes rotation {
from {
transform: rotate(0deg);
}
to {
transform: rotate(359deg);
}
}
<div class='spinner'></div>
<div class='spinner parent-padded-margin'></div>
<div class='spinner child-padded-margin'></div>
<div class='spinner child-padded-margin-2'></div>
Positioning the pseudo-element (using top,left,bottom,right ) also has affects the animation. It would also require the transform-origin to be modified accordinly in-order for the animation to work properly. A sample is available in the below snippet.
.spinner {
height: 50px;
width: 50px;
position: relative;
animation: rotation .6s infinite linear;
border-left: 6px solid #222;
border-right: 6px solid #222;
border-bottom: 6px solid #222;
border-top: 6px solid #ccc;
border-radius: 100%;
}
.spinner.parent-padded-margin {
padding: 10px;
margin: 10px;
}
.spinner:after {
position: absolute;
content: 'Loading..';
height: 100%;
width: 100%;
animation: rotation .6s infinite linear reverse; /* added this line */
}
.spinner.child-positioned{
margin-bottom: 40px;
}
.spinner.child-positioned:after {
top: 120%;
left: 2%;
transform-origin: calc(50% - 2%) calc(50% - 120%); /* basically need to subtract the distance from the left and top of the container */
}
.spinner.child-positioned-negative:after {
bottom: -120%;
right: -2%;
transform-origin: calc(50% - 2%) calc(50% - 120%); /* basically need to subtract the distance from the left and top of the container */
}
#keyframes rotation {
from {
transform: rotate(0deg);
}
to {
transform: rotate(359deg);
}
}
<div class='spinner child-positioned'></div>
<div class='spinner child-positioned-negative'></div>
Note: Both the above solutions work perfectly fine in latest versions of Chrome, Opera and Safari but are causing the text to have a slanted appearance in IE 11, Edge and Firefox. Firefox seems to require a separate animation which goes from rotate(-10deg) to rotate(-370deg) for FF while it gets more complex in IE.
The only alternate without setting the reverse animation on pseudo (child) element would be to make use of the method mentioned by Chris in his comment. That would mean setting borders and the animation directly to the pseudo element. This would mean that the parent's contents would remain unaffected as the parent won't get affected by a transform on the child.
.spinner {
height: 50px;
width: 50px;
position: relative;
}
.spinner:after {
position: absolute;
content: '';
top: 0px;
left: 0px;
height: 100%;
width: 100%;
animation: rotation .6s infinite linear;
border-left: 6px solid #222;
border-right: 6px solid #222;
border-bottom: 6px solid #222;
border-top: 6px solid #ccc;
border-radius: 100%;
}
#keyframes rotation {
from {
transform: rotate(0deg);
}
to {
transform: rotate(359deg);
}
}
<div class='spinner'>Loading...</div>
For completeness to the question alongside the comprehensive answer from #Harry I produced a version with the text below the spinner. The method of this is to use the .spinner as a canvas, put the actual spinning circle :before and the loading... in the :after as follows:
.spinner:before {
content: ' ';
display: block;
height: 50px;
width: 50px;
margin: 24px auto 6px auto;
animation: rotation .6s infinite linear;
border-left: 6px solid #222;
border-right: 6px solid #222;
border-bottom: 6px solid #222;;
border-top: 6px solid #ccc;
border-radius: 100%;
}
.spinner {
height: 100px;
width: 100px;
position: relative;
}
.spinner:after {
display: block;
text-align: center;
content: 'loading...';
}
#keyframes rotation {
from {
transform: rotate(0deg);
}
to {
transform: rotate(359deg);
}
}
<div class='spinner'></div>
This question already has answers here:
CSS3 Rotate Animation
(7 answers)
Closed 4 years ago.
I was wondering if it is possible to make a triangle that spins exactly from the center.
Codepen
html:
<div class="loader-wrapper">
<div class="loader"></div>
</div>
css:
.loader-wrapper {
width: 100%;
height: 100vh;
background-color: #11e;
}
#keyframes load {
0% {
transform: rotate(0deg);
}
100% {
transform: rotate(360deg);
}
}
.loader {
position: absolute;
top: 0;
bottom: 0;
left: 0;
right: 0;
margin: auto;
width: 0;
height: 0;
border-style: solid;
border-width: 0 100px 173.2px 100px;
border-color: transparent transparent #007bff transparent;
animation: 4s linear 0s infinite load;
}
A complete solution could be like this.
Simply saying, you should change the transform origin that match the actual center of the triangle (which is 66.66% by pure math).
Html:
<div class="loader">
<div class="loader-wrapper">
<div class="triangle"></div>
</div>
</div>
CSS:
.loader {
display: inline-block;
position: relative;
width: 100%;
height: 300px;
}
.loader-wrapper {
display: block;
position: absolute;
top: 50%;
left: 50%;
/* transform by half of its width & height */
transform: translate(-50%, -50%);
}
.triangle {
display: block;
position: relative;
width: 0;
height: 0;
border-color: transparent transparent #e44750 transparent;
border-width: 0px 100px 173.20508076px 100px;
border-style: solid;
transform-origin: 50% 66.66%;
animation: spin 3s infinite linear;
}
#keyframes spin {
0% {
transform: rotate(0deg);
}
100% {
transform: rotate(360deg);
}
}
The transform-origin property can be used to change the origin of the transformation point. just add transform-origin: 107px 111px; to your .loader class.
You'll need to do some tuning though, to get it perfect.
Try this:
.loader {
position: relative;
top: 50%;
transform: translate(0, -50%);
margin: auto;
width: 0;
height: 0;
border-style: solid;
border-width: 0 100px 173.2px 100px;
border-color: transparent transparent #007bff transparent;
animation: 4s linear 0s infinite load;
}
JSFiddle