I needed spinning effect on hover of that square, what i can get is written below.
HTML
<div class="mainSquare">
<div class="firstInnerSquare">
<div class="lastInnerSquare">
Hello
</div>
</div>
</div>
CSS
.mainSquare{
width:160px;
height:160px;
background:black;
margin: 50px auto;
padding:25px;
}
.firstInnerSquare{
width:110px;
height:110px;
background:red;
padding:25px;
}
.lastInnerSquare{
text-align:center;
width:110px;
padding: 46px 0px;
background:white;
}
Fiddle
Hope to get help.
You can do this by using a single element and two pseudos. Make the 2 pseudo elements larger than the container element, position them behind the container and add a rotate animation to them.
Note: This is only a base sample that would help you get started. I would leave the fine tuning part for you to handle. You can read more about the CSS animation properties in this MDN page.
.shape {
position: relative; /* used to position the pseudos relative to the parent */
height: 100px;
width: 100px;
background: white;
border: 1px solid;
margin: 100px; /* required because children are larger than parent */
}
.shape:after,
.shape:before {
position: absolute;
content: '';
}
.shape:before {
height: 125%; /* make one pseudo 25% larger than parent */
width: 125%;
top: -12.5%; /* 25/2 to make sure its center is same as the parent's */
left: -12.5%; /* 25/2 to make sure its center is same as the parent's */
background: red;
z-index: -1; /* send it behind the parent */
}
.shape:after {
height: 150%; /* make this pseudo larger than the parent and the other pseudo */
width: 150%;
top: -25%; /* 50/2 to make sure its center is same as the parent's */
left: -25%; /* 50/2 to make sure its center is same as the parent's */
background: black;
z-index: -2; /* send it behind both the parent and other pseudo */
}
/* add animation when hovering on parent */
.shape:hover:before {
animation: rotate 3s linear infinite;
}
.shape:hover:after {
animation: rotate-rev 3s linear infinite;
}
#keyframes rotate {
to {
transform: rotate(359deg); /* some browsers don't display spin when it is 360 deg */
}
}
#keyframes rotate-rev {
to {
transform: rotate(-359deg); /* reverse direction rotate */
}
}
<div class='shape'></div>
Here's one with the original structure and just one keyframe statement:
All that needs changing, per div, is the animation duration and direction. The "middle" div's timing needs to be 50% of the outer/inner.
.mainSquare {
width: 160px;
height: 160px;
background: black;
margin: 50px auto;
padding: 25px;
animation: spin 2s infinite linear;
}
.firstInnerSquare {
width: 110px;
height: 110px;
background: red;
padding: 25px;
animation: spin 1s infinite linear reverse;
}
.lastInnerSquare {
text-align: center;
width: 110px;
padding: 46px 0px;
background: white;
animation: spin 2s infinite linear;
}
#keyframes spin {
to {
transform: rotate(1turn);
}
}
<div class="mainSquare">
<div class="firstInnerSquare">
<div class="lastInnerSquare">
Hello
</div>
</div>
</div>
Related
Closed. This question needs debugging details. It is not currently accepting answers.
Edit the question to include desired behavior, a specific problem or error, and the shortest code necessary to reproduce the problem. This will help others answer the question.
Closed 4 months ago.
Improve this question
I have been wondering how to animate an HTML element using CSS
I have no idea how to do so...
I tried to use the animate keyword.
you can't just animate anything by just adding animate keyword you have to add keyframes and tell the element from where it should start and where it should end. read about css animation. here are some resources.
w3school
mozilla webdocs
here is a sample snippet to you can see and get an idea of it works from this snippet.
* {
font-family: cursive;
}
h1 {
text-align: center;
}
/* all css animation properties */
/* animation-name
animation-duration
animation-timing-function
animation-delay
animation-iteration-count
animation-direction
animation-fill-mode
animation-play-state */
/* CSS animations shorthand property */
/* animation: name duration timing-function delay iteration-count direction fill-mode; */
/* From To Transitions */
.from_to {
height: 250px;
width: 250px;
animation-name: unrivalledking;
animation-duration: 1s;
animation-timing-function: ease-in;
animation-delay: 0;
animation-iteration-count: 10;
animation-direction: normal;
animation-fill-mode: forwards;
/* CSS animations shorthand property */
/* animation: unrivalledking 1s ease-in 0 4 alternate forwards; */
}
/*
#keyframes identifier (write animation name instead of identifier) {
} */
#keyframes unrivalledking {
from {
background-color: red;
margin-left: 0;
}
to {
background-color: orange;
margin-left: 30%;
}
}
/* Percent Keyframes */
.percent {
margin-left: 20%;
margin-bottom: 500px;
height: 250px;
width: 250px;
position: relative;
animation: unrivalledking2 3s linear 0s infinite normal forwards;
}
.percent::after {
content: "This is it";
color: white;
font-size: 20px;
margin-left: 70px;
}
#keyframes unrivalledking2 {
0% {
background-color: red;
top: 0;
left: 0;
rotate: 0deg;
}
25% {
background-color: rgba(255, 0, 0, 0.5);
top: 0;
left: 250px;
rotate: 90deg;
}
50% {
background-color: orange;
top: 250px;
rotate: 180deg;
left: 250px;
}
75% {
background-color: rgba(255, 166, 0, 0.5);
top: 250px;
rotate: 270deg;
left: 0px;
}
100% {
background-color: red;
top: 0px;
rotate: 360deg;
left: 0px;
}
}
<body>
<h1>CSS Animations</h1>
<hr />
<h2>From-To Keyframes Animations</h2>
<div class="from_to"></div>
<hr />
<h2>Percent Keyframes Animations</h2>
<div class="percent"></div>
</body>
I'm trying to create a loading DIV that has a border that looks like an indeterminate progress ring spinner.
I'm pretty close based on one of the examples on https://css-tricks.com/gradient-borders-in-css/
This is great when the border doesn't rotate. When you set the border in the :before element to match the transparent border in the gradient-box element then the static gradient border looks perfect.
However, once the animation is added, because the whole :before element rotates you get a pretty odd effect - as shown in the example below.
.gradient-box {
display: flex;
align-items: center;
width: 90%;
margin: auto;
max-width: 22em;
position: relative;
padding: 30% 2em;
box-sizing: border-box;
border: 5px solid blue;
color: #FFF;
background: #000;
background-clip: padding-box; /* !importanté */
border: solid 5px transparent; /* !importanté */
border-radius: 1em;
}
.gradient-box:before {
content: '';
position: absolute;
top: 0; right: 0; bottom: 0; left: 0;
z-index: -1;
margin: -35px; /* !importanté */
border-radius: inherit; /* !importanté */
background: conic-gradient(#0000ff00, #ff0000ff);
-webkit-animation: rotate-border 5s linear infinite;
-moz-animation: rotate-border 5s linear infinite;
-o-animation: rotate-border 5s linear infinite;
animation: rotate-border 3s linear infinite;
}
#keyframes rotate-border {
to {
transform: rotate(360deg);
}
}
html { height: 100%; background: #000; display: flex; }
body { margin: auto; }
<!DOCTYPE HTML>
<html>
<head>
<meta charset="utf-8">
<title>Loading DIV Test</title>
</head>
<body>
<div id="loadingBox" class="gradient-box">
<p>Loading.</p>
</div>
</body>
I've tried playing about with overflow: hidden; but the border just disappears.. is there any way to 'mask' the :before element in a way that whatever is behind this loading Div is still visible behind it and so that the border stays as its intended width?
Basically, my goal is that the colour gradient in the border rotates to give the effect of a spinning/rotating edge.
I like your original idea with using overflow: hidden, but to make it work I had to include an extra wrapper div.
The outer wrapper defines a padding which serves as the display area for the gradient border
The inner div is just the content box with a black background
.loading-box-container {
--size: 200px;
--radius: 10px;
position: relative;
width: var(--size);
height: var(--size);
padding: var(--radius);
border-radius: var(--radius);
overflow: hidden;
}
.loading-box {
position: relative;
width: 100%;
height: 100%;
display: flex;
align-items: center;
justify-content: center;
color: #fff;
background: #000;
border-radius: var(--radius);
}
.loading-box-container::before {
content: '';
width: 150%; /* The upscaling allows the box to fill its container even when rotated */
height: 150%;
position: absolute;
top: -25%; left: -25%;
background: conic-gradient(#0000ff00, #ff0000ff);
animation: rotate-border 5s linear infinite;
}
#keyframes rotate-border {
to {
transform: rotate(360deg);
}
}
<div class="loading-box-container">
<div class="loading-box">
<p>Loading</p>
</div>
</div>
An alternative: Using #property
There's a much more elegant solution using #property, but unfortunately it only works on Chrome. I'm including here in case one day it becomes more universally supported or support for other browsers isn't important for your use case.
The conic-gradient function has a parameter that allows you to specify at what angle the gradient starts. If we can animate just that parameter, perhaps using a CSS variable, then we can animate the border with just a single div and without actually rotating anything.
Unfortunately, without some hinting the browser doesn't know how to transition a CSS variable. Therefore, we use #property to indicate the variable is an angle, telling the browser how to transition it.
#property --rotation {
syntax: '<angle>';
initial-value: 0deg;
inherits: false;
}
.loading-box {
--size: 200px;
--radius: 10px;
position: relative;
width: var(--size);
height: var(--size);
display: flex;
align-items: center;
justify-content: center;
color: #fff;
background: #000;
border-radius: var(--radius);
margin: var(--radius);
}
.loading-box::before {
--rotation: 0deg;
content: '';
width: calc(100% + 2 * var(--radius));
height: calc(100% + 2 * var(--radius));
border-radius: var(--radius);
position: absolute;
top: calc(-1 * var(--radius)); left: calc(-1 * var(--radius));
background: conic-gradient(from var(--rotation), #0000ff00, #ff0000ff);
animation: rotate-border 5s linear infinite;
z-index: -1;
}
#keyframes rotate-border {
to {
--rotation: 360deg;
}
}
<div class="loading-box">
<p>Loading</p>
</div>
CanIUse for #property indicates this will only work in Chrome and Edge as of this post.
Hi is this what you are looking for?
What I did was I added a new div which will be the "mask" as well as a container div for both the mask and the loadingBox.
I then sized the mask to be a little larger than your visible area, make it a transparent background, and then gave it a large outline the same color as your background to effectively mask out a border. I then fiddled with z-indexs of the mask, the loadingbox and the before. I also added some actual borders on mask to box it out into a nice shape.
Take a look:
.gradient-box {
display: flex;
align-items: center;
width: 90%;
margin: auto;
max-width: 22em;
position: relative;
padding: 30% 2em;
box-sizing: border-box;
border: 5px solid blue;
color: #FFF;
background: #000;
background-clip: padding-box; /* !importanté */
border: solid 5px transparent; /* !importanté */
border-radius: 1em;
}
.gradient-box:before {
content: '';
position: absolute;
top: 0; right: 0; bottom: 0; left: 0;
z-index: -3;
margin: -35px; /* !importanté */
border-radius: inherit; /* !importanté */
background: conic-gradient(#0000ff00, #ff0000ff);
-webkit-animation: rotate-border 5s linear infinite;
-moz-animation: rotate-border 5s linear infinite;
-o-animation: rotate-border 5s linear infinite;
animation: rotate-border 3s linear infinite;
}
#keyframes rotate-border {
to {
transform: rotate(360deg);
}
}
html { height: 100%; background: #000; display: flex; }
body { margin: auto; }
.mask {
position: absolute;
box-sizing: border-box;
background-color: transparent;
outline: 65px solid black;
height: 100%;
width: 100%;
border: 2px solid black;
border-left: 7px solid black;
border-right: 7px solid black;
z-index: -1;
}
.container {
position: relative;
}
<!DOCTYPE HTML>
<html>
<head>
<meta charset="utf-8">
<title>Loading DIV Test</title>
</head>
<body>
<div class="container">
<div class="mask"></div>
<div id="loadingBox" class="gradient-box">
<p>Loading.</p>
</div>
</div>
</body>
I want to put a spinner inside a div that contains a video.
This video takes a few seconds to display as it is hosted on aws.
I have managed to make the spinner but it takes up the whole page. I can't get it to adapt to the div it is entered in.
#cover-div-spin {
position:fixed;
width:100%;
left:0;right:0;top:0;bottom:0;
background-color: rgba(0,0,0,0.7);
z-index:2;
/*display:none;*/
}
/* Safari */
#-webkit-keyframes spin {
from {-webkit-transform:rotate(0deg);}
to {-webkit-transform:rotate(360deg);}
}
#keyframes spin {
from {transform:rotate(0deg);}
to {transform:rotate(360deg);}
}
#cover-div-spin::after {
/*position: fixed;*/
left: 50%;
top: 50%;
border: 16px solid #f3f3f3;
border-radius: 50%;
border-top: 16px solid #c4040c;
width: 100px;
height: 100px;
-webkit-animation: spin 2s linear infinite; /* Safari */
animation: spin 2s linear infinite;
content:'';
display:block;
position:absolute;
left:48%;top:40%;
-webkit-animation: spin .8s linear infinite;
animation: spin .8s linear infinite;
}
<div class="col-md-4" style="background:orange;">
<span><b>Example</b></span>
<div align="center" class="embed-responsive embed-responsive-16by9">
<div id="cover-div-spin"></div>
<video class="embed-responsive-item" src="" controls muted></video>
</div>
</div>
https://jsfiddle.net/JorgePalaciosZaratiegui/pdzm1ano/17/
Any ideas to solve this?
Thanks in advance.
First, your #cover-div-spin should have an absolute position instead of a fixed one.
To understand more about positionning, let's read the MDN docs:
position: absolute
The element is removed from the normal document flow, and no space is
created for the element in the page layout. It is positioned relative
to its closest positioned ancestor, if any; otherwise, it is placed
relative to the initial containing block.
position: fixed
The element is removed from the normal document flow, and no space is
created for the element in the page layout. It is positioned relative
to the initial containing block established by the viewport
I've also changed hte #cover-div-spin display:flex;, it will allow us to easily center the spinner.
#cover-div-spin {
position:absolute; /* absolute instead of fixed */
width:100%;
left:0;right:0;top:0;bottom:0;
background-color: rgba(0,0,0,0.7);
z-index:2;
display: flex; /* Allow us to easily center the spinner */
align-items: center; /* Vertical alignement */
justify-content: center; /* Horizontal alignement */
}
/* Safari */
#-webkit-keyframes spin {
from {-webkit-transform:rotate(0deg);}
to {-webkit-transform:rotate(360deg);}
}
#keyframes spin {
from {transform:rotate(0deg);}
to {transform:rotate(360deg);}
}
#cover-div-spin::after {
/* Removed all position rules */
border: 16px solid #f3f3f3;
border-radius: 50%;
border-top: 16px solid #c4040c;
width: 100px;
height: 100px;
-webkit-animation: spin 2s linear infinite; /* Safari */
animation: spin 2s linear infinite;
content:'';
display:block;
-webkit-animation: spin .8s linear infinite;
animation: spin .8s linear infinite;
}
<link href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/css/bootstrap.min.css" rel="stylesheet"/>
<div class="col-md-4" style="background:orange;">
<span><b>Example</b></span>
<div align="center" class="embed-responsive embed-responsive-16by9">
<div id="cover-div-spin"></div>
<video class="embed-responsive-item" src="" controls muted></video>
</div>
</div>
to be exact center, the left and top cannot be full 50%, but, 50% - half the width of the spinner (on your case the spinner is 100px, so half is 50px), like this (i just change the left & top, and remove duplicate left and top at the bottom)
#cover-div-spin::after {
/*position: fixed;*/
left: calc(50% - 50px);
top: calc(50% - 50px);
border: 16px solid #f3f3f3;
border-radius: 50%;
border-top: 16px solid #c4040c;
width: 100px;
height: 100px;
-webkit-animation: spin 2s linear infinite; /* Safari */
animation: spin 2s linear infinite;
content:'';
display:block;
position:absolute;
/* left:48%; top:40%; remove this */
-webkit-animation: spin .8s linear infinite;
animation: spin .8s linear infinite;
}
and if you want to make the spinner only on the div, just change the position on #cover-div-spin to absolute, like this
#cover-div-spin {
position:absolute;
}
#cover-div-spin::after {
left:50%;
top:50%;
transform:translate(-50%, 50%);
}
you have to just add this 3 line in #cover-div-spin::after otherwise all code lines are perfect.
when we move any element 50% top and left we have to minus the element -50% which ever the side we use.
if we want to align vertically center then it will be like top:50%; trasnfrom:translateY(-50%); and if we need to center horizontally then left:50%; trasnfrom:translateX(-50%); and if we need to center both horizontal and vertical then you can use above code;
Something like the following example could help.
.col-md-4,
.embed-responsive {
display: flex;
align-items: center;
align-content: center;
justify-content: center;
flex-flow: column;
}
.col-md-4 span {
height: 100%;
}
.col-md-4 {
height: 12rem;
}
#-webkit-keyframes spin {
from {
-webkit-transform: rotate(0deg);
}
to {
-webkit-transform: rotate(360deg);
}
}
#keyframes spin {
from {
transform: rotate(0deg);
}
to {
transform: rotate(360deg);
}
}
#cover-div-spin {
background-color: transparent;
z-index: 2;
width: 8rem;
height: 8rem;
position: absolute;
}
#cover-div-spin::after {
border: 1rem solid #f3f3f3;
border-radius: 50%;
border-top: 1rem solid #c4040c;
width: 6rem;
height: 6rem;
align-self: center;
content: '';
display: inline-flex;
-webkit-animation: spin .8s linear infinite;
animation: spin .8s linear infinite;
}
.embed-responsive-item {
z-index: 1;
top: 2rem;
position: absolute;
}
<div class="col-md-4" style="background:orange;">
<span><b>Example</b></span>
<div id="cover-div-spin"></div>
<div class="embed-responsive embed-responsive-16by9">
<video class="embed-responsive-item" src="" controls muted></video>
</div>
</div>
I am attempting to "orbit" two separate divs in circular motion around a center, however I am having trouble getting the two divs to follow the same circular path in my CSS animation.
.container {
width: 500px;
height: 500px;
display: flex;
align-items: center;
justify-content: center;
}
.box {
background-color: pink;
width: 100px;
height: 100px;
animation: battle 6s linear infinite;
position: absolute;
margin: 10px;
}
#keyframes battle {
from {
transform: rotate(0deg) translateX(150px) rotate(0deg);
}
to {
transform: rotate(360deg) translateX(150px) rotate(-360deg);
}
}
<div class="container">
<div class="box">
</div>
<div class="box">
</div>
</div>
Jsfiddle
Let your parent element be the guide;
When the goal is to rotate in a consistent spacing around a center (as opposed to say an "elliptical orbit" that is more of an oval pattern) than the easiest technique is to provide a parent to set a consistent boundary and attach children within it to use its position as their animation path. The goal is to just supply an illusion of individual elements orbiting in sync when in reality just one is rotating with its default transform-origin of center acting as the guide for the children "orbiting" within it.
In our case we took a parent whose equal circumference is roughly the size of the "orbit desired" and we gave it a border-radius of 50% to create a circle. This makes no point on the element less than or greater distance from the other. We make it a position: relative element so that we can apply position: absolute to any children of it. In this example we use pseudo elements but they could just as easily be additional DOM node elements like divs.
By fixing our children to specific points on the parent we create the equal distance from the X/Y of the parent's transform-origin center we desire and apply the rotate transform to spin the parent. However if we only did that then the children would also follow that path and not keep vertical (as it is assumed is desired) so we simply re-use the same animation applied to the parent but in reverse to offset its rotation. The result is a parent element spinning one direction, and the children in the other to create the effect seen in the example. Hope this helps!
#rotator {
position: relative;
width: 7rem;
height: 7rem;
animation: rotations 6s linear infinite;
border: 1px orange dashed;
border-radius: 50%;
margin: 3rem;
}
#rotator:before, #rotator:after {
position: absolute;
content: '';
display: block;
height: 3rem;
width: 3rem;
animation: inherit;
animation-direction: reverse;
}
#rotator:before {
background-color: red;
top: -.25rem;
left: -.25rem;
}
#rotator:after {
background-color: green;
bottom: -.25rem;
right: -.25rem;
}
#keyframes rotations {
to { transform: rotate(360deg) }
}
<div id="rotator"></div>
Something I did many years ago might be close to what you are looking for:
// Base
body {
background: #252525;
}
// Keyframes
#keyframes rotateClockwise {
100% {
transform: rotate(360deg);
}
}
#keyframes rotateCounterClockwise {
100% {
transform: rotate(-360deg);
}
}
// Ring
.ring {
position: relative;
left: 50%;
top: 50px;
margin-left: -100px;
height: 200px;
width: 200px;
border: 10px solid #666;
border-radius: 50%;
}
// Dots
.dot {
position: absolute;
height: 250px;
width: 40px;
top: -25px;
left: 50%;
margin-left: -20px;
&:before {
display: block;
content: '';
height: 40px;
width: 40px;
border-radius: 50%;
box-shadow: 0 2px 3px rgba(0,0,0,.1);
}
}
.dot--one {
animation: rotateClockwise 4s linear infinite;
&:before {
background: #e6a933;
}
}
.dot--two {
animation: rotateCounterClockwise 2s linear infinite;
&:before {
background: #e63348;
}
}
.dot--three {
animation: rotateClockwise 7s linear infinite;
&:before {
background: #70b942;
}
}
.dot--four {
animation: rotateCounterClockwise 12s linear infinite;
&:before {
background: #009ee3;
}
}
<div class="ring">
<div class="dot dot--one"></div>
<div class="dot dot--two"></div>
<div class="dot dot--three"></div>
<div class="dot dot--four"></div>
</div>
https://codepen.io/seanstopnik/pen/93f9cbcbcf9b38684bfc75f38c9c4db3
I have a problem, I want to make my login page background image rotated. I have problem with style code because of following code ;
body{font-family:Arial, Helvetica, sans-serif;font-size:13px;background:#020307 url(/media/images/bg.jpg) no-repeat ;background-position:top center ;color:#fff;}
And in that i need to insert this code ;
#myDIV {
margin: auto;
border: 1px solid black;
width: 200px;
height: 100px;
background-color: coral;
color: white;
-webkit-animation: mymove 5s infinite; /* Chrome, Safari, Opera */
animation: mymove 5s infinite;
}
/* Chrome, Safari, Opera */
#-webkit-keyframes mymove {
50% {-webkit-transform: rotate(180deg);}
}
/* Standard syntax */
#keyframes mymove {
50% {transform: rotate(180deg);}
}
I know i cant right now just add the secound code in first code, but i try to combine them but it rotate all the background content not the background image. Can someone please give me a tips how to make it work only on background image ? Right now i need to just option to rotate background image. Will configure the code later to my specifications.
Thanx and sorry for bad English!
You can do like following way:
body{
font-family:Arial, Helvetica, sans-serif;
font-size:13px;
position: relative;
height:500px;
width:100%;
}
body::before {
animation: 5s ease 0s normal none infinite running mymove;
background: #020307 url(/media/images/bg.jpg) no-repeat scroll center top;
color: #fff;
content: "";
height: 100%;
position: absolute;
width: 100%;
z-index: -9999;
}
#myDIV {
margin: auto;
border: 1px solid black;
width: 200px;
height: 100px;
background-color: coral;
color: white;
}
Here is your edited code. Check Fiddle