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!!
Related
i tried to make this animation so it would pause when i hover on it but every time i do, only the div get paused and the pesudo elements don't so what did i do wrong?
i tried to change the property like making the background color change with hover and it works! so it seems that the problem is something related to the animation but i can't get my hand on it
This is my Css
.task1 {
/* box-sizing: border-box; */
width: 50px;
height: 50px;
margin: 50px auto;
border: #fca900 solid 5px;
border-left: transparent solid 5px;
border-radius: 50%;
position: relative;
-webkit-animation: rotate linear infinite 1s;
animation: rotate linear infinite 1s;
}
.task1::after {
content: "";
width: 70%;
height: 70%;
position: absolute;
top: 2.5px;
left: 2.5px;
border: #2090db solid 5px;
border-top: transparent solid 5px;
border-radius: 50%;
-webkit-animation: rotate linear infinite 1s;
animation: rotate linear infinite 1s;
}
.task1::before {
content: "";
width: 40%;
height: 40%;
position: absolute;
top: 10px;
left: 10px;
border: #e51758 solid 5px;
border-right: transparent solid 5px;
border-radius: 50%;
-webkit-animation: rotate linear infinite 1s;
animation: rotate linear infinite 1s;
}
#-webkit-keyframes rotate {
to {
transform: rotate(1turn);
}
}
#keyframes rotate {
to {
transform: rotate(1turn);
}
}
.task1:hover {
-webkit-animation-play-state: paused;
animation-play-state: paused;
}
<div class="task1"></div>
The pseudo elements are styled independently so you need to pause their animations on task1 being hovered as well.
.task1 {
/* box-sizing: border-box; */
width: 50px;
height: 50px;
margin: 50px auto;
border: #fca900 solid 5px;
border-left: transparent solid 5px;
border-radius: 50%;
position: relative;
-webkit-animation: rotate linear infinite 1s;
animation: rotate linear infinite 1s;
}
.task1::after {
content: "";
width: 70%;
height: 70%;
position: absolute;
top: 2.5px;
left: 2.5px;
border: #2090db solid 5px;
border-top: transparent solid 5px;
border-radius: 50%;
animation: rotate linear infinite 1s;
}
.task1::before {
content: "";
width: 40%;
height: 40%;
position: absolute;
top: 10px;
left: 10px;
border: #e51758 solid 5px;
border-right: transparent solid 5px;
border-radius: 50%;
animation: rotate linear infinite 1s;
}
#keyframes rotate {
to {
transform: rotate(1turn);
}
}
.task1:hover,
.task1:hover::after,
.task1:hover::before {
animation-play-state: paused;
}
<div class="task1"></div>
it's happening because you are only pausing task1 not it's pesudos just do this change to your code
.task1::before, .task1::after, .task1:hover {
-webkit-animation-play-state: paused;
animation-play-state: paused;
}
I am working on my project and I have added the image with border. I am rotating the border on hover but the problem is that, the image is also rotating.
#circle1 {
width: 210px;
height: 210px;
background-color: transparent;
border-radius: 100%;
border: 6px solid #337AB7;
border-left: 6px solid transparent;
overflow: hidden;
transform: rotate(50deg);
transition: linear 2s;
}
#circle1 .elementor-widget-container {
transform: rotate(-50deg);
background-color: transparent;
border-radius: 100%;
overflow: hidden;
transition: linear 2s;
}
#circle1:hover {
transform: rotate(410deg);
transition: linear 2s;
}
#circle1 .elementor-widget-container:hover {
transform: rotate(-410deg);
transition: linear 2s;
}
#circle1 img {
display: block;
}
<div id="circle1">
<div class="elementor-widget-container">
<div class="elementor-image">
<img src="https://i.ibb.co/WkdnS0f/BIcon-1.png" class="attachment-large size-large">
</div>
</div>
</div>
In this, on hover image is also rotating but I dont want to rotate the image, only border should rotate.
Just hover to the image frequently, you will see image is also rotating.
Any help is much appreciated.
Change this selector
#circle1 .elementor-widget-container:hover
to
#circle1:hover .elementor-widget-container
#circle1 {
width: 210px;
height: 210px;
background-color: transparent;
border-radius: 100%;
border: 6px solid #337AB7;
border-left: 6px solid transparent;
overflow: hidden;
transform: rotate(50deg);
transition: linear 2s;
}
#circle1 .elementor-widget-container {
transform: rotate(-50deg);
background-color: transparent;
border-radius: 100%;
overflow: hidden;
transition: linear 2s;
}
#circle1:hover {
transform: rotate(410deg);
transition: linear 2s;
}
#circle1:hover .elementor-widget-container {
transform: rotate(-410deg);
transition: linear 2s;
}
#circle1 img {
display: block;
}
<div id="circle1">
<div class="elementor-widget-container">
<div class="elementor-image">
<img src="https://i.ibb.co/WkdnS0f/BIcon-1.png" class="attachment-large size-large">
</div>
</div>
</div>
You could make both your HTML and CSS much simpler by using a pseudo element.
#circle1 {
position: relative;
}
#circle1::after {
content: "";
display: block;
width: 210px;
height: 210px;
background-color: transparent;
border-radius: 100%;
border: 6px solid #337AB7;
border-left: 6px solid transparent;
transform: rotate(50deg);
transition: linear 2s;
position: absolute;
top: -6px;
left: -6px;
}
#circle1:hover::after {
transform: rotate(410deg);
transition: linear 2s;
}
<div id="circle1">
<img src="https://i.ibb.co/WkdnS0f/BIcon-1.png" class="attachment-large size-large">
</div>
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>
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);
}