I have the following HTML/CSS code and I have an issue to center the content inside a flex container. The result is :
In my mind, I would like to center the ring inside the flex container AND center the text (temperature) and the CSS animation (arrow) just after the temperature inside the ring animation.
How to do this?
body {
background-color: #0d74ff;
}
.container {
padding: 20px;
}
.flexwrap {
display: flex;
flex-wrap: wrap;
}
.cell {
position: relative;
height: 200px;
width: 200px;
border: 1px solid rgba(0, 0, 0, 0.25);
}
.loader-ring {
width: 150px;
height: 150px;
}
.loader-ring-light {
width: 150px;
height: 150px;
border-radius: 150px;
box-shadow: 0 4px 0 #ffffff inset;
animation: rotate-360 6s linear infinite;
}
.loader-text {
font-weight: bold;
font-size: 2em;
}
.scroll-down {
border: 2px solid #fff;
border-radius: 100px;
width: 30px;
height: 30px;
}
.scroll-down i {
display: block;
border-radius: 100px;
transition: all 0.4s ease;
width: 100%;
height: 100%;
background-size: 0 auto;
animation: pulse 1.5s 0s infinite normal ease forwards;
background-image: url("https://jamesmuspratt.com/codepen/img/arrow-down.svg");
background-repeat: no-repeat;
}
#keyframes rotate-360 {
from {
transform: rotate(0);
}
to {
transform: rotate(360deg);
}
}
#keyframes pulse {
0% {
opacity: 0;
background-position: center top;
background-size: 0 auto;
}
10% {
opacity: 0;
}
50% {
opacity: 1;
background-size: 75% auto;
}
90% {
opacity: 0;
}
100% {
opacity: 0;
background-position: center bottom;
background-size: 0 auto;
}
}
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/meyer-reset/2.0/reset.min.css">
<div class="container">
<div class="flexwrap">
<div class="cell">
<div class='loader-ring'>
<div class='loader-ring-light'></div>
<div class='loader-ring-track'>
<div class='loader-text'>26.6°</div>
<div class="scroll-down"><i></i></div>
</div>
</div>
</div>
</div>
</div>
You don't need so many blocks here. You need absolute positioning because elements will need to stack on each other. Also for centering absolutely positioned elements you need this styles
.loader-ring,
.loader-ring-track {
position: absolute;
top: 50%;
left: 50%;
transform: translate(-50%, -50%);
}
Demo:
body {
background-color: #0d74ff;
}
.container {
padding: 20px;
}
.cell {
position: relative;
height: 200px;
width: 200px;
border: 1px solid rgba(0, 0, 0, 0.25);
}
/* center absolutely positioned items */
/* both vertically and horizontally */
.loader-ring,
.loader-ring-track {
position: absolute;
top: 50%;
left: 50%;
transform: translate(-50%, -50%);
}
.loader-ring-track {
display: flex; /* new */
}
.loader-ring {
width: 150px;
height: 150px;
}
.loader-ring-light {
width: 150px;
height: 150px;
border-radius: 150px;
box-shadow: 0 4px 0 #ffffff inset;
animation: rotate-360 6s linear infinite;
}
.loader-text {
font-weight: bold;
font-size: 2em;
}
.scroll-down {
border: 2px solid #fff;
border-radius: 100px;
width: 30px;
height: 30px;
}
.scroll-down i {
display: block;
border-radius: 100px;
transition: all 0.4s ease;
width: 100%;
height: 100%;
background-size: 0 auto;
animation: pulse 1.5s 0s infinite normal ease forwards;
background-image: url("https://jamesmuspratt.com/codepen/img/arrow-down.svg");
background-repeat: no-repeat;
}
#keyframes rotate-360 {
from {
transform: rotate(0);
}
to {
transform: rotate(360deg);
}
}
#keyframes pulse {
0% {
opacity: 0;
background-position: center top;
background-size: 0 auto;
}
10% {
opacity: 0;
}
50% {
opacity: 1;
background-size: 75% auto;
}
90% {
opacity: 0;
}
100% {
opacity: 0;
background-position: center bottom;
background-size: 0 auto;
}
}
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/meyer-reset/2.0/reset.min.css">
<div class="cell">
<div class='loader-ring'>
<div class='loader-ring-light'></div>
<div class='loader-ring-track'>
<div class='loader-text'>26.6°</div>
<div class="scroll-down"><i></i></div>
</div>
</div>
</div>
Related
I am studying CSS animation. I want my animation moving one by one, as I don't know JS I want to do it by CSS only. How can I do this? I faced the problem of rules from and to in animations, when I change them the animations don't work as expected.
I have the following HTML
body {
margin: 0;
background: grey;
}
main {
font-family: Open Sans;
text-transform: uppercase;
line-height: 1;
position: absolute;
width: 100%;
height: 100%;
overflow: hidden;
background: transparent;
}
.animation {
width: 20em;
height: 4em;
margin: 1em auto;
position: relative;
}
.squares {
margin: auto;
background: red;
/* display: flex;
flex-wrap: wrap;
justify-content: center;*/
}
.small_square {
width: 10px;
height: 10px;
background-color: white;
text-align: center;
display: block;
text-align: center;
position: relative;
margin: 0;
padding: 0;
left: 48%;
animation: appearance_small 1s ease-in-out;
animation: move_around 3s ease-in-out;
*/
}
.big_square {
margin: auto;
width: 40px;
height: 40px;
background-color: black;
display: block;
position: relative;
top: 30px;
animation: appearance_big 1.3s ease-in-out;
animation-delay: 2s;
animation: spin 3s ease-in-out;
forwards;
}
#keyframes appearance_big {
0% {
transform: scale(0%);
}
100% {
opacity: 1;
}
}
#keyframes appearance_small {
0% {
opacity: 0;
transform: scale(0%);
top: 50px;
}
100% {
opacity: 1;
top: 0px;
}
}
#keyframes spin {
from {
transform: rotate(0deg);
}
to {
transform: rotate(180deg);
}
}
#keyframes move_around {
from {
transform: translate(50%, 50px) rotate(0turn) translate(-50%, -50px);
}
to {
transform: translate(50%, 50px) rotate(0.50turn) translate(-0%, -50px);
}
<main>
<div id="animation" class="animation">
<div class="squares">
<div class="small_square"></div>
<div class="big_square"></div>
</div>
</main>
I have loader designed and I positioned it to center with top:0 left:0 z:10 and text-align:center. Its not positioning to center of the page. I also added a text called Loading But its's not showing up.
#container-sleftpinner {
background: #ffffff;
color: #666666;
position: fixed;
height: 100%;
width: 100%;
z-index: 10;
top: 0;
left: 0;
text-align: center;
opacity: .80;
}
.loader,
.loader:before,
.loader:after {
background: grey;
-webkit-animation: load1 1s infinite ease-in-out;
animation: load1 1s infinite ease-in-out;
width: 1em;
height: 4em;
}
.loader {
color: grey;
background-repeat: no-repeat;
background-position: center;
position: fixed;
display: block;
left: 0;
right: 0;
top: 0;
bottom: 0;
text-indent: -9999em;
margin: 88px auto;
position: relative;
font-size: 11px;
-webkit-transform: translateZ(0);
-ms-transform: translateZ(0);
transform: translateZ(0);
-webkit-animation-delay: -0.16s;
animation-delay: -0.16s;
}
.loader:before,
.loader:after {
position: absolute;
top: 0;
content: '';
}
.loader:before {
left: -1.5em;
-webkit-animation-delay: -0.32s;
animation-delay: -0.32s;
}
.loader:after {
left: 1.5em;
}
.loader p {
position: absolute;
left: 0;
right: 0;
bottom: 50%;
display: inline-block;
text-align: center;
margin-bottom: -5em;
}
#-webkit-keyframes load1 {
0%,
80%,
100% {
box-shadow: 0 0;
height: 4em;
}
40% {
box-shadow: 0 -2em;
height: 5em;
}
}
#keyframes load1 {
0%,
80%,
100% {
box-shadow: 0 0;
height: 4em;
}
40% {
box-shadow: 0 -2em;
height: 5em;
}
}
<div id="container-spinner" style="display:block;">
<div class="loader">
<p>Loading...</p>
</div>
</div>
Based upon your code.
give the .container-spinner class the following and the content will center.
I changed the display to be flex and made sure to give it hight:100vh to fill the page and all that left is to center it vertically and horizontally using justify-content and align-items ( don't forget to remove the inline style to get this to work)
.container-spinner {
display: flex;
justify-content: center;
align-items: center;
width: 100%;
height: 100vh;
}
Edit
based upon your request. Here is the working code with the text showing up and all the changes to the HTML and CSS.
.container-spinner {
display: flex;
flex-direction: column;
justify-content: center;
align-items: center;
text-align: center;
height: 100vh;
}
#container-sleftpinner {
background: #ffffff;
color: #666666;
position: fixed;
height: 100%;
width: 100%;
z-index: 10;
top: 0;
left: 0;
text-align: center;
opacity: 0.8;
}
.loader,
.loader:before,
.loader:after {
background: grey;
-webkit-animation: load1 1s infinite ease-in-out;
animation: load1 1s infinite ease-in-out;
width: 1em;
height: 4em;
}
.loader {
color: grey;
background-repeat: no-repeat;
background-position: center;
text-indent: -9999em;
margin: 10px auto;
font-size: 11px;
-webkit-transform: translateZ(0);
-ms-transform: translateZ(0);
transform: translateZ(0);
-webkit-animation-delay: -0.16s;
animation-delay: -0.16s;
}
.loader:before,
.loader:after {
position: absolute;
top: 0;
content: "";
}
.loader:before {
left: -1.5em;
-webkit-animation-delay: -0.32s;
animation-delay: -0.32s;
}
.loader:after {
left: 1.5em;
}
.container-spinner p {
text-align: center;
}
#-webkit-keyframes load1 {
0%,
80%,
100% {
box-shadow: 0 0;
height: 4em;
}
40% {
box-shadow: 0 -2em;
height: 5em;
}
}
#keyframes load1 {
0%,
80%,
100% {
box-shadow: 0 0;
height: 4em;
}
40% {
box-shadow: 0 -2em;
height: 5em;
}
}
<div class="container-spinner">
<div class="loader">
</div>
<p>Loading...</p>
</div>
If that doesn't work please let me know.
I have created this loader, I want to place it in the center of its parent. So in the parent
element I am using
display: flex;
align-items: center;
justify-content:center;
but this is not working. Any help?
.empty-container {
height: 100px;
border: 1px solid gray;
}
.container {
height: calc(100% - 100px);
border: 1px solid red;
display: flex;
align-items: center;
justify-content: center;
}
.component-loader {
position: relative;
text-align: center;
transition: opacity .7s;
border: 1px solid gray;
height: 90px;
width: 90px;
}
.loader-spinner:before {
content: "";
height: 90px;
width: 90px;
margin: -15px auto auto -15px;
position: absolute;
top: 160px;
left: calc(50% - 45px);
border-width: 8px;
border-style: solid;
border-color: green #ccc #ccc;
border-radius: 100%;
animation: rotation .7s infinite linear;
}
/* Safari */
#-webkit-keyframes rotation {
0% {
-webkit-transform: rotate(0deg);
}
100% {
-webkit-transform: rotate(360deg);
}
}
#keyframes rotation {
0% {
transform: rotate(0deg);
}
100% {
transform: rotate(360deg);
}
}
<div style="height: 600px">
<div class="empty-container"></div>
<div class="container">
<div class="component-loader">
<div class="loader-spinner"></div>
</div>
</div>
</div>
.empty-container {
height: 100px;
border: 1px solid gray;
}
.container {
height: calc(100% - 100px);
border: 1px solid red;
position: relative;
}
.component-loader {
position: absolute;
left: 50%;
top: 50%;
transform: translate(-50%, -50%);
}
.loader-spinner:before {
content: "";
height: 90px;
width: 90px;
position: absolute;
top: 0;
left: 0;
border-width: 8px;
border-style: solid;
border-color: green #ccc #ccc;
border-radius: 100%;
animation: rotation .7s infinite linear;
}
/* Safari */
#-webkit-keyframes rotation {
0% {
-webkit-transform: rotate(0deg);
}
100% {
-webkit-transform: rotate(360deg);
}
}
#keyframes rotation {
0% {
transform: rotate(0deg);
}
100% {
transform: rotate(360deg);
}
}
<div style="height: 600px">
<div class="empty-container"></div>
<div class="container">
<div class="component-loader">
<div class="loader-spinner"></div>
</div>
</div>
</div>
Try this code, the parent element of your .loader-spinner:before is .loader-spinner.
.empty-container {
height: 100px;
border: 1px solid gray;
}
.container {
height: calc(100% - 100px);
border: 1px solid red;
display: flex;
align-items: centre;
justify-content: centre;
}
.component-loader {
position: relative;
}
.loader-spinner{
position: relative;
height: 90px;
width: 90px;
text-align: center;
transition: opacity .7s;
border: 1px solid gray;
}
.loader-spinner:before {
content: "";
height: 90px;
width: 90px;
position: absolute;
top: 0;
left: 0;
border-width: 8px;
border-style: solid;
border-color: green #ccc #ccc;
border-radius: 100%;
animation: rotation .7s infinite linear;
}
/* Safari */
#-webkit-keyframes rotation {
0% {
-webkit-transform: rotate(0deg);
}
100% {
-webkit-transform: rotate(360deg);
}
}
#keyframes rotation {
0% {
transform: rotate(0deg);
}
100% {
transform: rotate(360deg);
}
}
<div style="height: 600px">
<div class="empty-container"></div>
<div class="container">
<div class="component-loader">
<div class="loader-spinner"></div>
</div>
</div>
</div>
*{
box-sizing: border-box;
}
.empty-container {
height: 100px;
border: 1px solid gray;
}
.container {
height: calc(100% - 100px);
border: 1px solid red;
display: flex;
position: relative;
}
.component-loader{
border: 1px solid gray;
position: absolute;
height: 90px;
width: 90px;
left: 0;
right: 0;
top: 0;
bottom: 0;
margin: auto;
}
.loader-spinner:before {
content: "";
margin: 0;
position: absolute;
top: 0;
left: 0;
right: 0;
bottom: 0;
border-width: 8px;
border-style: solid;
border-color: green #ccc #ccc;
border-radius: 100%;
animation: rotation .7s infinite linear;
}
#-webkit-keyframes rotation {
0% {
-webkit-transform: rotate(0deg);
}
100% {
-webkit-transform: rotate(360deg);
}
}
#keyframes rotation {
0% {
transform: rotate(0deg);
}
100% {
transform: rotate(360deg);
}
}
<div style="height: 600px">
<div class="empty-container"></div>
<div class="container">
<div class="component-loader">
<div class="loader-spinner"></div>
</div>
</div>
</div>
So I'm doing this for some lines on my webpage.
#keyframes dropHeader {
0% {
height: 0px;
}
100% {
height: 100%;
}
}
.slant-decor {
left: 50%;
height: 100%;
position: fixed;
display: inline-flex;
animation-name: dropHeader;
animation-iteration-count: 1;
animation-timing-function: ease-out;
animation-duration: 0.6s;
}
.slant-decor:after {
width: 5px;
height: 100%;
background-color: rgba(0, 0, 0, 0.55);
content: "";
position: relative;
margin-left: -5px;
transform: skewX(-30deg);
display: inline-block;
}
.slant-decor div {
width: 19px;
height: 100%;
display: inline-block;
margin-left: -4px;
-ms-transform: skewX(-30deg); /* IE 9 */
-webkit-transform: skewX(-30deg); /* Safari */
transform: skewX(-30deg); /* Standard syntax */
}
.decor-orange {
background-color: orange;
}
.decor-red {
background-color: red;
}
.decor-green {
background-color: green;
}
<div class="slant-decor">
<div class="decor-red"></div>
<div class="decor-orange"></div>
<div class="decor-green"></div>
</div>
As of right now, the animation on .slant-decor works fine, however - as you can see, it causes a kind of a weird effect on the lines. What I'd like to achieve is that the animation follow the skew angle aswell, creating an effect where the lines would slide in from the top of the page, at the right angle. How could I achieve this?
If my understanding is correct, setting a transform-origin: right top would produce the effect that you are looking for. The default value for transform-origin is 50% 50% (the center-mid point of the element). When you animate the height, this point is constantly changing and hence creates that weird effect. If the transform-origin is set to a point that is fixed then that problem would be avoided.
#keyframes dropHeader {
0% {
height: 0px;
}
100% {
height: 100%;
}
}
.slant-decor {
left: 50%;
height: 300px;
position: fixed;
display: inline-flex;
animation-name: dropHeader;
animation-iteration-count: 1;
animation-timing-function: ease-out;
animation-duration: 0.6s;
}
.slant-decor:after {
width: 5px;
height: 100%;
background-color: rgba(0, 0, 0, 0.55);
content: "";
position: relative;
margin-left: -5px;
transform-origin: right top;
transform: skewX(-30deg);
display: inline-block;
}
.slant-decor div {
width: 19px;
height: 100%;
display: inline-block;
margin-left: -4px;
transform-origin: right top;
transform: skewX(-30deg);
}
.decor-orange {
background-color: orange;
}
.decor-red {
background-color: red;
}
.decor-green {
background-color: green;
}
<div class="slant-decor">
<div class="decor-red"></div>
<div class="decor-orange"></div>
<div class="decor-green"></div>
</div>
I want to have an expanding radius that starts from the center of the div instead of it starting on the top left of the div.
Imagine the button has a pulsing outline that goes outwards. That pulsing outline should start from the middle of the div and go out.
See example here: https://jsbin.com/dinehoqaro/edit?html,css,output
You can see that the expansion is starting from the top left.
.circle {
background-color: white;
border: 1px solid red;
border-radius: 50%;
width: 50px;
height: 50px;
animation: pulse 1s infinte;
-webkit-animation: pulse 1.2s infinite;
}
button {
background-color: green;
border: none;
border-radius: 50%;
width: 50px;
height: 50px;
}
#-webkit-keyframes pulse {
from {
width: 50px;
height: 50px;
}
to {
width: 100px height: 100px;
}
}
#keyframes pulse {
from {
width: 50px;
height: 50px;
}
to {
width: 100px;
height: 100px;
}
}
<div class="circle"><button>click here</button></div>
Here's a general solution using CSS flexbox, transform and pseudo-elements.
body {
display: flex;
align-items: center;
justify-content: center;
background-color: lightyellow;
height: 100vh;
margin: 0;
}
#container {
display: flex;
align-items: center;
justify-content: center;
}
.sphere {
display: flex;
background: lightblue;
border-radius: 300px;
height: 100px;
width: 100px;
}
#container::after {
display: flex;
background: lightpink;
border-radius: 300px;
height: 250px;
width: 250px;
animation: pulsate 2.5s ease-out;
animation-iteration-count: infinite;
opacity: 0.0;
content: "";
z-index: -1;
margin: auto;
position: absolute;
top: 0;
left: 0;
right: 0;
bottom: 0;
}
#keyframes pulsate {
0% {
transform: scale(0.1, 0.1);
opacity: 0.0;
}
50% {
opacity: 1.0;
}
100% {
transform: scale(1.2, 1.2);
opacity: 0.0;
}
}
<div id="container">
<div class="sphere"></div>
</div>
jsFiddle
Also see this awesome solution by #harry: How to create a pulsing glow ring animation in CSS?