Position absolute is not relative to its its parent CSS - html

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>

Related

overflow: hidden doesn't work on :after and :before pseudo elements

I am making this rounded scroll down button with an arrow inside. On hover I wanted to apply an animation that makes the arrow go from above to below the rounded div, and it should be hidden when outside the div.
I tried using overflow: hidden but for some reason it doesn't work. Does anyone has a solution for this please?
Codepen: https://codepen.io/RaphaelleD/pen/vYpqxpm
#keyframes tipUp {
0% {
transform: translateY(-10px) rotateZ(225deg);
}
100% {
transform: translateY(100px) rotateZ(225deg);
}
}
#keyframes lineUp {
0% {
transform: translateY(-10px);
}
100% {
transform: translateY(100px);
}
}
.scrolldown {
position: relative;
margin: 0 auto;
}
.scrolldown p {
font-size: 1rem;
font-weight: 600;
padding-bottom: 0.8rem;
text-align: center;
}
.scrolldown__arrow {
width: 6rem;
height: 6rem;
border: 6px solid black;
border-radius: 50%;
margin: 0 auto;
overflow: hidden;
}
.scrolldown__arrow:before {
position: absolute;
display: inline-block;
content: "";
background: black;
width: 10px;
height: 45px;
top: 50%;
left: 50%;
margin-top: -50px;
margin-left: -5px;
transform: translateY(50px);
}
.scrolldown__arrow:after {
position: absolute;
display: inline-block;
content: "";
width: 22px;
height: 22px;
color: black;
border-top: 9px solid;
border-left: 9px solid;
transform: rotateZ(45deg);
top: 50%;
left: 50%;
margin-top: -30px;
margin-left: -15.5px;
transform: translateY(50px) rotateZ(225deg);
}
.scrolldown__arrow:hover:before {
animation: lineUp 1s cubic-bezier(0, 0.6, 1, 0.4) infinite 0.5s;
}
.scrolldown__arrow:hover:after {
animation: tipUp 1s cubic-bezier(0, 0.6, 1, 0.4) infinite 0.5s;
}
}
}
<body>
<div class="scrolldown">
<p>SCROLL DOWN</p>
<div class="scrolldown__arrow"></div>
</div>
</body>
I believe this is because of position: absolute, which takes the arrow out of the normal flow. In order to kinda preserve it in the flow, I've added position: relative to the arrow parent, and had to adjust top position as well, seems to work as expected:
#keyframes tipUp {
0% {
transform: translateY(-10px) rotateZ(225deg);
}
100% {
transform: translateY(100px) rotateZ(225deg);
}
}
#keyframes lineUp {
0% {
transform: translateY(-10px);
}
100% {
transform: translateY(100px);
}
}
.scrolldown {
position: relative;
margin: 0 auto;
}
.scrolldown p {
font-size: 1rem;
font-weight: 600;
padding-bottom: 0.8rem;
text-align: center;
}
.scrolldown__arrow {
width: 6rem;
height: 6rem;
border: 6px solid black;
border-radius: 50%;
margin: 0 auto;
overflow: hidden;
position: relative;
}
.scrolldown__arrow:before {
position: absolute;
display: inline-block;
content: "";
background: black;
width: 10px;
height: 45px;
top: 25%;
left: 50%;
margin-top: -50px;
margin-left: -5px;
transform: translateY(50px);
}
.scrolldown__arrow:after {
position: absolute;
display: inline-block;
content: "";
width: 22px;
height: 22px;
color: black;
border-top: 9px solid;
border-left: 9px solid;
transform: rotateZ(45deg);
top: 25%;
left: 50%;
margin-top: -30px;
margin-left: -15.5px;
transform: translateY(50px) rotateZ(225deg);
}
.scrolldown__arrow:hover:before {
animation: lineUp 1s cubic-bezier(0, 0.6, 1, 0.4) infinite 0.5s;
}
.scrolldown__arrow:hover:after {
animation: tipUp 1s cubic-bezier(0, 0.6, 1, 0.4) infinite 0.5s;
}
}
}
<body>
<div class="scrolldown">
<p>SCROLL DOWN</p>
<div class="scrolldown__arrow"></div>
</div>
</body>

How to make 2 circles travelling in opposite directions?

I'm making a HTML program where I want to have two circles traveling on a circular path, in opposite directions. That's the main idea. Here's my code so far (I followed this tutorial on circular movement coding, and stopped right at 8:35 when it's just the red circle in motion):
styles.css:
body{
margin: 0;
padding: 0;
}
.circle{
position: absolute;
top: 50%;
left: 50%;
transform: translate(-50%, -50%);
width: 400px;
height: 400px;
background: transparent;
border-radius: 50%;
border: 2px solid #262626;
}
.line{
width: 50%;
height: 2px;
background: transparent;
position: absolute;
top: calc(50% - 1px);
transform-origin: right;
animation: animate 1s linear infinite;
}
.line:before{
content: '';
position: absolute;
width: 20px;
height: 20px;
background: #f00;
border-radius: 50%;
top: -10px;
left: -11px;
}
#keyframes animate{
0%{
transform: rotate(0deg);
}
100%{
transform: rotate(360deg);
}
}
index.html:
<!DOCTYPE html>
<html>
<head>
<title>Two Circles in Circular Motion</title>
<link rel="stylesheet" href="style.css">
</head>
<body>
<div class = "circle">
<div class = "line"></div>
</div>
</body>
</html>
Right now I only have 1 circle. I want to create another one, and animate it so that it travels in the same circular path but in the opposite direction. I'm relatively new to CSS and HTML, so can someone please help? Thanks!
You can optimize your code and use only one div and its pseudo element for the small circles:
.circle {
position: absolute;
top: 50%;
left: 50%;
transform: translate(-50%, -50%);
width: 400px;
height: 400px;
border-radius: 50%;
border: 2px solid #262626;
/* place both item to the center */
display:grid;
align-content:center;
justify-content:center;
}
.circle::before,
.circle::after {
content: '';
grid-area:1/1; /* both will overlap */
width: 20px;
height: 20px;
background: #f00;
border-radius: 50%;
transform:rotate(0deg) translate(200px) rotate(0deg);
animation:animate 2s linear infinite;
}
.circle::after {
animation-direction:reverse; /* the opposite animation for the after */
background:blue;
}
#keyframes animate {
100% {transform:rotate(360deg) translate(200px) rotate(-360deg);}
}
<div class="circle">
</div>
Another solution is you could have made another line and used
animation-direction: reverse; on it.
Example;
body {
margin: 0;
padding: 0;
}
.circle {
position: absolute;
top: 50%;
left: 50%;
transform: translate(-50%, -50%);
width: 400px;
height: 400px;
background: transparent;
border-radius: 50%;
border: 2px solid #262626;
}
.line, .line2 {
width: 50%;
height: 2px;
background: transparent;
position: absolute;
top: calc(50% - 1px);
transform-origin: right;
animation: animate 1s linear infinite;
}
.line:before, .line2:before {
content: '';
position: absolute;
width: 20px;
height: 20px;
background: #f00;
border-radius: 50%;
top: -10px;
left: -11px;
}
.line2 {
animation-direction: reverse;
}
#keyframes animate {
0% {
transform: rotate(0deg);
}
100% {
transform: rotate(360deg);
}
}
<div class="circle">
<div class="line"></div>
<div class="line2"></div>
</div>
You also could have created another line (like I did in my example (line2)), and bound a different animation keyframe to it like below;
body {
margin: 0;
padding: 0;
}
.circle {
position: absolute;
top: 50%;
left: 50%;
transform: translate(-50%, -50%);
width: 400px;
height: 400px;
background: transparent;
border-radius: 50%;
border: 2px solid #262626;
}
.line {
width: 50%;
height: 2px;
background: transparent;
position: absolute;
top: calc(50% - 1px);
transform-origin: right;
animation: animate 1s linear infinite;
}
.line2 {
width: 50%;
height: 2px;
background: transparent;
position: absolute;
top: calc(50% - 1px);
transform-origin: right;
animation: animate2 1s linear infinite;
}
.line:before, .line2:before {
content: '';
position: absolute;
width: 20px;
height: 20px;
background: #f00;
border-radius: 50%;
top: -10px;
left: -11px;
}
#keyframes animate {
0% {
transform: rotate(0deg);
}
100% {
transform: rotate(360deg);
}
}
#keyframes animate2 {
0% {
transform: rotate(360deg);
}
100% {
transform: rotate(0deg);
}
}
<div class="circle">
<div class="line"></div>
<div class="line2"></div>
</div>
There are many possibilities to achieve what you are looking for :)
Because you say you are new to HTML and CSS I figured I'd show you some alternatives.

How do I make translateZ() working on grand-child element?

I'm trying to get into CSS animations and I can't figure out how to "transform: translateZ(200px)" on the span element with the ".logo" class.
I want to have "Z-Text" floating on the yellow background of "#box3", I applied the preserve-3d transform-style but without any effect.. translateX and Y working fine though.
.container {
display: flex;
justify-content: center;
align-items: center;
position: relative;
height: 400px;
width: 400px;
border: 1px solid white;
}
#outer-box {
height: 100px;
width: 100px;
background-color: black;
transform-style: preserve-3d;
animation: spin 5s linear infinite;
}
#outer-box > div {
position: absolute;
}
#box2 {
height: 100px;
width: 100px;
top: -50px;
background-color: green;
transform: rotateX(0.25turn);
}
#box3 {
height: 100px;
width: 100px;
background-color: yellow;
top: 50px;
opacity: 0.5;
transform-style: preserve-3d;
transform: rotateX(0.25turn);
perspective: 1000px;
}
.logo {
position: absolute;
transform: translateZ(200px);
}
#box4 {
height: 100px;
width: 100px;
left: 50px;
background-color: blue;
opacity: 0.5;
transform: rotateY(0.25turn);
}
#keyframes spin {
0% {
transform: rotateY(0) rotateX(0deg);
}
50% {
transform: rotateY(180deg) rotateX(180deg);
}
75% {
transform: rotateY(270deg) rotateX(270deg);
}
100% {
transform: rotateY(359deg) rotateX(359deg);
}
}
<div class="container">
<div id="outer-box">
<div id="box2">Any Text</div>
<div id="box3">
<span class="logo">Z-Text</span>
</div>
<div id="box4">Some Text</div>
</div>
</div>
Any suggestions?

pure CSS drawing circle animation

I wrote a pure css drawing circle animation, but there's a little white space between the two half circles during the animation. (When the animation ends, they gone.)
Can anyone please tell me why does this happened?
My HTML:
.circle__box {
width: 200px;
height: 200px;
margin: 50px auto;
position: relative;
}
.circle__wrapper {
width: 100px;
height: 200px;
position: absolute;
top: 0;
overflow: hidden;
}
.circle__wrapper--right {
right: 0;
}
.circle__wrapper--left {
left: 0;
}
.circle__whole {
width: 160px;
height: 160px;
border: 20px solid transparent;
border-radius: 50%;
position: absolute;
top: 0;
transform: rotate(-135deg);
}
.circle__right {
border-top: 20px solid teal;
border-right: 20px solid teal;
right: 0;
animation: circleRight 5s linear forwards;
}
.circle__left {
border-bottom: 20px solid teal;
border-left: 20px solid teal;
left: 0;
animation: circleLeft 5s linear forwards;
}
#keyframes circleRight {
0% {
transform: rotate(-135deg);
}
50%,
100% {
transform: rotate(45deg);
}
}
#keyframes circleLeft {
0%,
50% {
transform: rotate(-135deg);
}
100% {
-webkit-transform: rotate(45deg);
}
}
<div class="circle__box">
<div class="circle__wrapper circle__wrapper--right">
<div class="circle__whole circle__right"></div>
</div>
<div class="circle__wrapper circle__wrapper--left">
<div class="circle__whole circle__left"></div>
</div>
</div>
My complete code goes here. Thank you.
Here it is, please check. It was because of you gave .circle-left and .circle-right left:0; and right:0; respectively, change it to left:1px; and right:1px; and you're done...
.circle__box {
width: 200px;
height: 200px;
margin: 50px auto;
position: relative;
}
.circle__wrapper {
width: 100px;
height: 200px;
position: absolute;
top: 0;
overflow: hidden;
}
.circle__wrapper--right {
right: 0;
}
.circle__wrapper--left {
left: 0;
}
.circle__whole {
width: 160px;
height: 160px;
border: 20px solid transparent;
border-radius: 50%;
position: absolute;
top: 0;
transform: rotate(-135deg);
}
.circle__right {
border-top: 20px solid teal;
border-right: 20px solid teal;
right: 1px;
animation: circleRight 5s linear forwards;
}
.circle__left {
border-bottom: 20px solid teal;
border-left: 20px solid teal;
left: 1px;
animation: circleLeft 5s linear forwards;
}
#keyframes circleRight {
0% {
transform: rotate(-135deg);
}
50%,
100% {
transform: rotate(45deg);
}
}
#keyframes circleLeft {
0%,
50% {
transform: rotate(-135deg);
}
100% {
-webkit-transform: rotate(45deg);
}
}
<div class="circle__box">
<div class="circle__wrapper circle__wrapper--right">
<div class="circle__whole circle__right"></div>
</div>
<div class="circle__wrapper circle__wrapper--left">
<div class="circle__whole circle__left"></div>
</div>
</div>
This is my solution:
.circle__wrapper--right { right: 0; margin-right: 20px;}
.circle__wrapper--left { left: 0; margin-left: 20px; }

Flex Container CSS : How to center div element?

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>