Using transform to center a div along with animation [duplicate] - html

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>

Related

How to get css animation to scale to appropriate screen size

I'm trying to make an animation for a webpage I'm tinkering with at the moment. I want the animation of a ball to start from the bottom of the screen, go to the middle, then expand to the whole page. I'm having a problem when it comes to the expanding part. When it expands since I'm using transform: scale it expands beyond the width and height of the viewport causing me to scroll. How is it possible to make it fit into the viewport and not having to scroll. I tried putting it in a container and putting overflow:hidden but it doesn't seem to work. Here is my code
<!DOCTYPE html>
<html>
<head>
<link rel="stylesheet" type="text/css" href="ballcopy.css">
<meta name="veiwport" content="width=device-width, initial-scale=1.0">
</head>
<body>
<main>
<div class="ball"></div>
</main>
</body>
</html>
*, *::after, *::before {box-sizing: inherit;}
html{
box-sizing: border-box;
}
body{
margin: 0;
padding: 0;
}
.ball{
background-color: #eb8c28;
width: 100px;
height: 100px;
border-radius: 0%;
position: absolute;
bottom: 0%;
left: 50%;
animation: rise;
animation-duration: 2s;
animation-iteration-count: 1;
animation-fill-mode: forwards;
}
#keyframes rise{
0%{
border-radius: 50%;
}
50%{
border-radius: 50%;
transform:translateY(-400px);
}
75%{
border-radius: 40%;
}
80%{
border-radius: 30%;
}
90%{
border-radius:20%;
}
100%{
transform: scale(20,20);
}
}
```
body{
height: 100vh;
width: 100vw;
overflow: hidden;
}
this fixes it so that your animation doesn't overflow and make you scroll.
For overflow: hidden to work on main you need to set position: relative and a height:
*,
*::after,
*::before {
box-sizing: inherit;
}
html {
box-sizing: border-box;
}
body {
margin: 0;
padding: 0;
}
main {
position: relative;
height: 100vh;
overflow: hidden;
}
.ball {
background-color: #eb8c28;
width: 100px;
height: 100px;
border-radius: 0%;
position: absolute;
bottom: 0%;
left: 50%;
animation: rise;
animation-duration: 2s;
animation-iteration-count: 1;
animation-fill-mode: forwards;
}
#keyframes rise {
0% {
border-radius: 50%;
}
50% {
border-radius: 50%;
transform: translateY(-100%);
}
75% {
border-radius: 40%;
}
80% {
border-radius: 30%;
}
90% {
border-radius: 20%;
}
100% {
transform: scale(20, 20);
}
}
<main>
<div class="ball"></div>
</main>
Or you could set overflow: hidden on the body:
*,
*::after,
*::before {
box-sizing: inherit;
}
html {
box-sizing: border-box;
}
body {
margin: 0;
padding: 0;
overflow: hidden;
}
.ball {
background-color: #eb8c28;
width: 100px;
height: 100px;
border-radius: 0%;
position: absolute;
bottom: 0%;
left: 50%;
animation: rise;
animation-duration: 2s;
animation-iteration-count: 1;
animation-fill-mode: forwards;
}
#keyframes rise {
0% {
border-radius: 50%;
}
50% {
border-radius: 50%;
transform: translateY(-100%);
}
75% {
border-radius: 40%;
}
80% {
border-radius: 30%;
}
90% {
border-radius: 20%;
}
100% {
transform: scale(20, 20);
}
}
<main>
<div class="ball"></div>
</main>
Also, it's a good idea to set transform: translateY to a relative value so it's scalable to different screen-sizes as well, i.e. transform: translateY(-100%)

How to create a CSS loader with gradient border and transparency?

I'm trying to do a loader with HTML and CSS I have the loader done but there's an issue when I have information behind the center of the loader the information doesn't show and the reason is because I have background: white; that I need to avoid showing the gradient because if I remove the white color and put transparent the gradient appears.
So I need to fix the problem when I have something behind the loader
.loader {
display: flex;
justify-content: center;
position: fixed;
top: 50%;
left: 50%;
z-index: 10;
}
.loader .circle {
background-image:linear-gradient(90deg, #a03297, #e90b5a);
width: 80px;
height: 80px;
border-style: solid;
border-color: transparent;
border-radius: 50%;
border-width: 1px;
animation: rot 2s linear infinite;
padding: 10px;
box-sizing: content-box;
}
.circle > div {
background:white;
height: 100%;
width: 100%;
border-style: solid;
border-color:transparent;
border-radius: 50%;
border-width: 1px;
}
#keyframes rot {
0% { transform: rotate(0deg) }
100% { transform: rotate(360deg); }
}
<div class="loader">
<div class="circle">
<div></div>
</div>
</div>
<p style="text-align: center; margin-top: 140px;">aaaaaaasssssssssssssssssçççççççççççççççççççççççççççççççççççççççççssssssss</p>
Use mask to make the inner part transparent:
.loader {
background:linear-gradient(yellow, #e90b5a);
/* Show only 10px from the border */
-webkit-mask:radial-gradient(farthest-side,#0000 calc(100% - 10px),#fff 0);
mask:radial-gradient(farthest-side,#0000 calc(100% - 10px),#fff 0);
border-radius: 50%;
position: fixed;
inset : calc(50% - 50px);
animation: rot 2s linear infinite;
}
#keyframes rot {
100% { transform: rotate(360deg); }
}
body {
background:linear-gradient(to right,grey,white)
}
<div class="loader"></div>

Text and loader not in the middle

I have a problem with my text and "loader". I want them to be in the MIDDLE but they are centred in the top.
.loader {
margin: auto;
border: 16px solid #f3f3f3;
/* Light grey */
border-top: 16px solid #3498db;
/* Blue */
border-radius: 50%;
width: 120px;
height: 120px;
animation: spin 2s linear infinite;
}
#keyframes spin {
0% {
transform: rotate(0deg);
}
100% {
transform: rotate(360deg);
}
}
.WebEntTxt {
color: white;
line-height: 1.5;
text-align: center;
text-decoration: none;
}
<div class="loader"></div>
<h1 class="WebEntTxt">You are entering PUBGpot! Please wait!</h1>
How can I get them to be in the CENTER of the screen, NOT in the TOP?
Since you want both text and spinner in middle, add a wrapper around both of them. Then,
Just add position fixed to wrapper, if you want it to position in center of the entire window. Then bring it to the center by adding left 50% and top 50%. Then you have to offset half of its original width and height using translate transform.
#wrapper {
position: fixed;
top: 50%;
left: 50%;
transform: translate(-50%, -50%);
}
.loader {
margin: auto;
border: 16px solid #f3f3f3;
/* Light grey */
border-top: 16px solid #3498db;
/* Blue */
border-radius: 50%;
width: 120px;
height: 120px;
animation: spin 2s linear infinite;
}
#keyframes spin {
0% {
transform: rotate(0deg);
}
100% {
transform: rotate(360deg);
}
}
.WebEntTxt {
color: red;
line-height: 1.5;
text-align: center;
text-decoration: none;
}
<body class="Background" background="Background.jpg">
<div id="wrapper">
<div class="loader"></div>
<h1 class="WebEntTxt">You are entering PUBGpot! Please wait!</h1>
</div>
<!-- jQuery (necessary for Bootstrap's JavaScript plugins) -->
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.12.4/jquery.min.js"></script>
<!-- Include all compiled plugins (below), or include individual files as needed -->
<script src="js/bootstrap.min.js"></script>
</body>
Using Flexbox here, this is best way to align element.
<!DOCTYPE html>
<html>
<head>
<style>
body{
display: flex;
height: 100vh;
align-items: center;
justify-content: center;
}
.loader {
margin: auto;
border: 16px solid #f3f3f3;
/* Light grey */
border-top: 16px solid #3498db;
/* Blue */
border-radius: 50%;
width: 120px;
height: 120px;
animation: spin 2s linear infinite;
display: flex;
align-self: center;
}
#keyframes spin {
0% {
transform: rotate(0deg);
}
100% {
transform: rotate(360deg);
}
}
.WebEntTxt {
color: white;
line-height: 1.5;
text-align: center;
text-decoration: none;
}
</style>
</head>
<body class="Background" background="Background.jpg">
<div class="loader"></div>
<!-- <h1 class="WebEntTxt">You are entering PUBGpot! Please wait!</h1> -->
<!-- jQuery (necessary for Bootstrap's JavaScript plugins) -->
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.12.4/jquery.min.js"></script>
<!-- Include all compiled plugins (below), or include individual files as needed -->
<script src="js/bootstrap.min.js"></script>
</body>
</html>
Without the need of putting any absolute values in the positioning - as other answers suggest-, you can use translate().
.loading-wrapper {
position: fixed;
top: 50%;
left: 50%;
display: flex;
flex-direction: column;
align-items: center;
transform: translate(-50%, -50%);
}
.loader {
border: 16px solid #f3f3f3;
/* Light grey */
border-top: 16px solid #3498db;
/* Blue */
border-radius: 50%;
width: 120px;
height: 120px;
animation: spin 2s linear infinite;
}
#keyframes spin {
0% {
transform: rotate(0deg);
}
100% {
transform: rotate(360deg);
}
}
.WebEntTxt {
color: red;
line-height: 1.5;
text-align: center;
text-decoration: none;
}
<div class="loading-wrapper">
<div class="loader"></div>
<h1 class="WebEntTxt">You are entering PUBGpot! Please wait!</h1>
</div>

How to center a div (CSS loader)

JS Fiddle: fiddle and here is the code:
.loader {
border: 16px solid #f3f3f3;
border-radius: 50%;
border-top: 16px solid #3498db;
width: 120px;
height: 120px;
-webkit-animation: spin 2s linear infinite;
animation: spin 2s linear infinite;
}
#-webkit-keyframes spin {
0% { -webkit-transform: rotate(0deg); }
100% { -webkit-transform: rotate(360deg); }
}
#keyframes spin {
0% { transform: rotate(0deg); }
100% { transform: rotate(360deg); }
}
<div class="loader"></div>
How do I centre it horizontally & vertically?
I tried:
position:absolute;
left:50%;
top:50%;
transform:translate(-50%,-50%);
But transform:translate(-50%,-50%); do not work
Give below css to .loader class:
margin:auto;
left:0;
right:0;
top:0;
bottom:0;
position:fixed;
.loader {
border: 16px solid #f3f3f3;
border-radius: 50%;
border-top: 16px solid #3498db;
width: 120px;
height: 120px;
-webkit-animation: spin 2s linear infinite;
animation: spin 2s linear infinite;
margin:auto;
left:0;
right:0;
top:0;
bottom:0;
position:fixed;
}
#-webkit-keyframes spin {
0% { -webkit-transform: rotate(0deg); }
100% { -webkit-transform: rotate(360deg); }
}
#keyframes spin {
0% { transform: rotate(0deg); }
100% { transform: rotate(360deg); }
}
<div class="loader"></div>
You can make it position:absolute;
and give it:
top:0;
left:0;
right:0;
bottom:0;
to make it both vertically and horizontally aligned into the middle.
body {
overflow:hidden;
}
.loader {
border: 16px solid #f3f3f3;
border-radius: 50%;
border-top: 16px solid #3498db;
width: 120px;
height: 120px;
-webkit-animation: spin 2s linear infinite;
animation: spin 2s linear infinite;
margin:auto;
top:0;
left:0;
bottom:0;
right:0;
position:absolute;
}
#-webkit-keyframes spin {
0% { -webkit-transform: rotate(0deg); }
100% { -webkit-transform: rotate(360deg); }
}
#keyframes spin {
0% { transform: rotate(0deg); }
100% { transform: rotate(360deg); }
}
<div class="loader"></div>
Easiest way to center element using CSS is by using flexbox. No hacks required.
if need to set parent container with display: flex.
<div class="container">
<div class="item">
Aligned Item
<div>
</div>
CSS:
.container {
display: flex;
align-items: center;
justify-content: center;
}
.item {
width: 200px;
height: 200px;
}
All elements with class item will be centrally aligned.
More details can be found at
https://philipwalton.github.io/solved-by-flexbox/demos/vertical-centering/
Several ways to do it.
Using flexbox. This would work in any container anywhere on the page.
body { /* or some wrapper, if you plan to have other things in body */
min-height: 100vh; /* this just expands the body height so the vertical alignment is visible in the snippet */
display: flex;
justify-content: center; /* center horizontally */
align-items: center; /* center vertically */
}
.loader {
border: 16px solid #f3f3f3;
border-radius: 50%;
border-top: 16px solid #3498db;
width: 120px;
height: 120px;
animation: spin 2s linear infinite;
}
#keyframes spin {
0% { transform: rotate(0deg); }
100% { transform: rotate(360deg); }
}
<div class="loader"></div>
Using position: absolute. This centers the div relative to the document, not loader's parent element.
.loader {
border: 16px solid #f3f3f3;
border-radius: 50%;
border-top: 16px solid #3498db;
width: 120px;
height: 120px;
animation: spin 2s linear infinite;
/* i added this: */
position: absolute;
left: calc(50% - 120px / 2); /* 50 % of body width minus half of .loader size… */
top: calc(50% - 120px / 2); /* …and the same thing with height */
}
#keyframes spin {
0% { transform: rotate(0deg); }
100% { transform: rotate(360deg); }
}
<div class="loader"></div>
Please add body {height: 100vh;} and update the css of loader div as the following:
.loader {
border: 16px solid #f3f3f3;
border-radius: 50%;
border-top: 16px solid #3498db;
width: 120px;
height: 120px;
-webkit-animation: spin 2s linear infinite;
animation: spin 2s linear infinite;
margin: auto;
position: absolute;
left: 0;
right: 0;
top: 0;
bottom: 0;
}
https://jsfiddle.net/7baw2rmp/

CSS spinning triangle from center [duplicate]

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