CSS positioning styles impact on the other objects - html

I am working a project on my favorite science stories animated using HTML. While I was working on it By just changing the position to fixed or nothing position of all my objects was changing. If you remove the position property from #Guy, you will notice that the image of Galileo will shift drastically. I just want to know why this happens.
:root {
--initX: 280px;
--initY: 70px;
--finalY: 600px;
}
body {
background-color: aqua;
padding: 0px;
margin: 0px;
}
#Guy {
z-index: 4;
height: 200px;
position: fixed;
width: auto;
transform: translate(800px, 450px);
}
#Galilo {
height: 50px;
width: auto;
z-index: -1;
transform: translate(290px, 5px) rotateZ(4deg);
}
#tower {
height: 650px;
width: 150px;
z-index: 0;
transform: translate(250px, 50px) rotateZ(4deg);
position: absolute;
background-color: grey;
}
#Lball {
height: 40px;
width: 40px;
z-index: 2;
border-radius: 50%;
transform: translate(var( --initX), var(--initY));
background-color: blue;
position: absolute;
animation: lite 2s linear 1s infinite forwards;
}
#Hball {
height: 50px;
width: 50px;
z-index: 3;
transform: translate(calc(var( --initX) + 75px), var(--initY));
border-radius: 50%;
background-color: red;
position: absolute;
animation: heavy 2s linear 1s infinite forwards;
}
#floor {
height: 25%;
width: 100%;
background-color: green;
position: absolute;
z-index: -1;
transform: translate(0px, 565px);
}
#hide {
height: 12%;
width: 100%;
background-color: green;
position: absolute;
z-index: 1;
transform: translate(0px, 650px);
}
#keyframes lite {
0% {
transform: translate(var( --initX), var(--initY))
}
90% {
transform: translate(var(--initX), calc(var(--finalY) + 12.5px))
}
100% {
transform: translate(var(--initX), calc(var(--finalY) + 12.5px))
}
}
#keyframes heavy {
0% {
transform: translate(calc(var( --initX) + 75px), var(--initY))
}
90% {
transform: translate(calc(var( --initX) + 75px), var(--finalY))
}
100% {
transform: translate(calc(var( --initX) + 75px), var(--finalY))
}
}
<div id="tower"></div>
<div id="Hball"></div>
<div id="Lball"></div>
<div id="floor"></div>
<div id="hide"></div>
<img src="stick fidure.png" alt="Dude thinking" id="Guy">
<img src="galileo-galilei.png" alt="gallilo" id="Galilo">
P.S.
The link for the image of Galileo is https://cdn.images.express.co.uk/img/dynamic/109/590x/galileo-galilei-819977.jpg and the stick figure was made in Paint 3D

position: fixed takes the element out of the document flow and places it in relation to the viewport/window. Usually that also causes this element to overlap other elements. The other elements however will be rearranged in a way like the fixed element wouldn't be there (it's not in the document flow). So adding/removing position: fixed to/from an element will have all these effects on the overall document.

Related

I can't make the 3/4 circle and i have to use one div only so how can i make it as the example in the link below

here is the shape i want to do enter link description here
P.S.I am still learning the front-end stuff so could you pls help me with this assignment.
Here is the HTML code <div>Elzero</div>
here is the CSS code i tried to do with
* {
box-sizing: border-box;
}
div {
width: 200px;
height: 200px;
background-color: #eee;
margin: 80px auto;
color: black;
font-size: 50px;
font-weight: bold;
text-align: center;
line-height: 200px;
border-radius: 50%;
}
::after {
content: "";
width: 200px;
height: 200px;
background-color: #03a9f4;
margin: 80px auto;
border-radius: 50%;
position: absolute;
transform: translate(-190px, -80px);
z-index: -1;
}
::before {
content: "";
width: 200px;
height: 200px;
background-color: #e91e63;
margin: 80px auto;
border-radius: 50%;
position: absolute;
top: 0px;
z-index: -2;
}
div:hover {
transition: all 0.5s;
transform: rotate(180deg);
}
As you are constrained to use just one div, this snippet builds on your idea of having the pseudo elements but creating them with conic-gradient backgrounds and the 'main' div having the light gray circular background created using a radial gradient. That way it creates these 3 shapes.
and overlays them to give the impression of 3/4 circles. It then uses CSS animation to rotate them on hover.
Obviously you will want to play with the dimensions, the animations timings and directions to get exactly what you want but this should give a start.
* {
box-sizing: border-box;
}
div {
width: 200px;
height: 200px;
background-image: radial-gradient(#eee 0 55%, transparent 55% 100%);
margin: 80px auto;
color: black;
font-size: 50px;
font-weight: bold;
text-align: center;
line-height: 200px;
border-radius: 50%;
position: relative;
}
div::after {
content: "";
width: 200px;
height: 200px;
border-radius: 50%;
position: absolute;
top: 0;
left: 0;
z-index: -2;
background-image: conic-gradient(#03a9f4 0deg 45deg, white 45deg 135deg, #03a9f4 135deg 360deg);
}
div::before {
content: "";
width: calc(100% - 10%);
height: calc(100% - 10%);
position: absolute;
border-radius: 50%;
position: absolute;
top: 5%;
left: 5%;
z-index: -1;
background-image: conic-gradient(#e91e63 0, #e91e63 225deg, white 225deg, white 315deg, #e91e63 315deg, #e91e63 360deg);
}
div:hover::after {
animation: rot .4s linear;
}
div:hover::before {
animation: rot .4s linear;
animation-delay: .1s;
animation-direction: reverse;
}
#keyframes rot {
0% {
transform: rotate(0);
}
25% {
transform: rotate(180deg);
}
50% {
transform: rotate(180deg);
}
75% {
transform: rotate(0);
}
100% {}
}
<div>Elzero
</div>
also here is example in less:
https://codepen.io/nikitahl/pen/XooBXd
if you want to use css here is a converter:
https://jsonformatter.org/less-to-css

Animating a div's width with transform property

Basically, I want my div to show from left to right by altering it's width. But when transform: translate(-50%,-50%); is present, the div's width animates from it's center to the assigned position.
I can't really change the position to anything but absolute since the div is placed in a specific spot.
.Container{
z-index: 100;
position: absolute;
top: 50%;
left: 50%;
transform: translate(-50%,-50%);
height: 150px;
animation: Animate 3s forwards;
}
.Container:after{
content: '';
position: absolute;
top: 0;
left: 90%;
width: 200px;
height: 150px;
background-color: rgb(110, 110, 110);
transform: skew(-35deg);
transform-origin: 100% 0;
z-index: 99;
}
#keyframes Animate{
from{
width: 0px;
}
to{
width: 250px;
background-color: red;
}
}
<div class="Container">
<div class="projDescription">
<h2>Hi</h2>
<p>Hello</p>
<br>
Help?
</div>
</div>
Would it be better if I used Jquery instead?
Also, I'll ask this here too since it has to do with the same div; can I animate the :after pseudo element? It's mostly just there to give the div an angled style, and I know I could've just used something else to style it. But I was just curious if it is possible.
Just remove the transform property from your .Container class and use calc() if you know the exact value of the width and height
.Container{
z-index: 100;
position: absolute;
top: calc(50% - 75px);
left: calc(50% - 125px);
height: 150px;
animation: Animate 3s forwards;
}
.Container:after{
content:'';
position: absolute;
top: 0;
left: 90%;
width: 200px;
height: 150px;
background-color: rgb(110, 110, 110);
transform: skew(-35deg);
transform-origin: 100% 0;
z-index: 99;
}
#keyframes Animate{
from{
width: 0px;
}
to{
width: 250px;
background-color: red;
}
}
I'd move some attributes to inner classes and made small modifications to achieve it; and also I used scale for width expansion animation instead of animation width property, to avoid an unnecessary reflow
.Container{
z-index: 100;
position: absolute;
top: 50%;
left: 50%;
transform: translate(-50%,-50%);
width: 250px;
height: 150px;
}
.projDescription{
height: 100%;
transform: scaleX(0);
position: absolute;
top: 0;
width:100% ;
animation: Animate 3s forwards;
}
.Container:after{
content: '';
position: absolute;
top: 0;
left: 90%;
width: 200px;
height: 100%;
box-sizing: border-box;
background-color: rgb(110, 110, 110);
transform: skew(-35deg) translateX(-50%);
transform-origin: 100% 0;
z-index: 99;
animation: move 3s forwards;
}
#keyframes Animate{
to{
transform: scaleX(1);
background-color: red;
}
}
#keyframes move{
to{
transform: skew(-35deg) translateX(0%);
}
}
<div class="Container">
<div class="projDescription">
<h2>Hi</h2>
<p>Hello</p>
Help?
</div>
</div>

Masking an object to make it appear as if it goes behind the item it's rotating around

I'm trying to make a 'dot' orbit around another object (circle) but due to the z-index the dot always appears above the circle it is meant orbiting around.
CodePen link: https://codepen.io/moy/pen/ROVZXd?editors=1100
Ideally the 2nd half of the animation would take place behind the object so it's not seen until it comes out the other side - is that possible?
I thought about fading out the object that is moving around but I don't think that would give a smooth/masked effect?
A bit stuck as to how I'd mask this area as I can't see a way the CSS would know it's meant to be hidden. I thought maybe I could change the z-index 50% though the animation it and reset it at 0%/100% but that doesn't appear to do anything.
Any ideas? Thanks in advance!
.earth {
background: white;
border: 1px solid black;
border-radius: 50%;
display: block;
height: 100px;
margin: 30px auto;
position: relative;
width: 100px;
z-index: 20;
}
.orbit {
border: 2px #eee transparent;
border-radius: 50%;
height: 140px;
margin: auto;
position: absolute;
top: -20px;
left: -20px;
transform: rotateZ(60deg) rotateY(60deg);
transform-style: preserve-3d;
width: 140px;
z-index: 10;
}
.orbit .moon {
animation: move ease-in-out infinite;
animation-duration: 2s;
background: black;
border-radius: 50%;
height: 15px;
margin: auto;
position: absolute;
top: 0;
left: 0;
right: 0;
bottom: 0;
width: 15px;
z-index: 10;
}
#keyframes move {
0% {
transform: rotateZ(-90deg) translateX(70px) rotateZ(90deg) rotateY(-70deg); z-index: 20;
}
50% {
z-index: -20;
}
100% {
transform: rotateZ(270deg) translateX(70px) rotateZ(-270deg) rotateY(-70deg); z-index: 20;
}
}
<div class="earth">
<div class="orbit">
<div class="moon"></div>
</div>
</div>
I seem to have solved this by adding a negative z-index to an animation applied to the parent .orbit
Link: https://codepen.io/moy/pen/wZdpRw?editors=1100
I initially applied this at 50% through the animation as that should be the furthest away the dot is before it comes back behind the larger circle. However this didn't work, setting it on 100% did work. Not entirely sure why but it seems to work!
The initial issue was due to the fact that you are applying z-index to the parent element and doing so it will impossible to make the child to move behind it (Why elements with any z-index value can never cover its child?) thus changin z-index is useless
Even if you remove the z-index from the parent you still have the transform that is also creating a stacking context making impossible to the child element to move behind so you cannot make the .moon to move behind the .earth.
The only way to do it (like you already noticed) is to remove z-index from the .earth to avoid the earth creating a stacking context and animate z-index of orbit to make the orbit AND the moon moving behind the earth (not only the moon).
Add some coloration to better see this:
.earth {
background: white;
border: 1px solid black;
border-radius: 50%;
display: block;
height: 100px;
margin: 60px auto;
position: relative;
width: 100px;
}
.orbit {
animation: hide ease-in-out infinite;
animation-duration: 2s;
background:red;
border-radius: 50%;
height: 140px;
margin: auto;
position: absolute;
top: -20px;
left: -20px;
transform: rotateZ(60deg) rotateY(60deg);
transform-style: preserve-3d;
width: 140px;
}
.orbit .moon {
animation: move ease-in-out infinite;
animation-duration: 2s;
background: black;
border-radius: 50%;
height: 15px;
margin: auto;
position: absolute;
top: 0;
left: 0;
right: 0;
bottom: 0;
width: 15px;
}
#keyframes move {
0% {
transform: rotateZ(-90deg) translateX(70px) rotateZ(90deg) rotateY(-70deg);
}
100% {
transform: rotateZ(270deg) translateX(70px) rotateZ(-270deg) rotateY(-70deg);
}
}
#keyframes hide {
0% {
z-index: 20;
}
100% {
z-index: -20;
}
}
<div class="earth">
<div class="orbit">
<div class="moon"></div>
</div>
</div>
Now if you add back z-index to earth it will stop working because of the stacking context:
.earth {
background: white;
border: 1px solid black;
border-radius: 50%;
display: block;
height: 100px;
margin: 60px auto;
position: relative;
width: 100px;
z-index:2;
}
.orbit {
animation: hide ease-in-out infinite;
animation-duration: 2s;
background:red;
border-radius: 50%;
height: 140px;
margin: auto;
position: absolute;
top: -20px;
left: -20px;
transform: rotateZ(60deg) rotateY(60deg);
transform-style: preserve-3d;
width: 140px;
}
.orbit .moon {
animation: move ease-in-out infinite;
animation-duration: 2s;
background: black;
border-radius: 50%;
height: 15px;
margin: auto;
position: absolute;
top: 0;
left: 0;
right: 0;
bottom: 0;
width: 15px;
}
#keyframes move {
0% {
transform: rotateZ(-90deg) translateX(70px) rotateZ(90deg) rotateY(-70deg);
}
100% {
transform: rotateZ(270deg) translateX(70px) rotateZ(-270deg) rotateY(-70deg);
}
}
#keyframes hide {
0% {
z-index: 20;
}
100% {
z-index: -20;
}
}
<div class="earth">
<div class="orbit">
<div class="moon"></div>
</div>
</div>
You can try key-framing the opacity:
.earth {
background: white;
border: 1px solid black;
border-radius: 50%;
display: block;
height: 100px;
margin: 30px auto;
position: relative;
width: 100px;
z-index: 20;
}
.orbit {
border: 2px #eee transparent;
border-radius: 50%;
height: 140px;
margin: auto;
position: absolute;
top: -20px;
left: -20px;
transform: rotateZ(60deg) rotateY(60deg);
transform-style: preserve-3d;
width: 140px;
z-index: 10;
}
.orbit .moon {
animation: move ease-in-out infinite;
animation-duration: 2s;
background: black;
border-radius: 50%;
height: 15px;
margin: auto;
position: absolute;
top: 0;
left: 0;
right: 0;
bottom: 0;
width: 15px;
z-index: 10;
}
#keyframes move {
0% {
transform: rotateZ(-90deg) translateX(70px) rotateZ(90deg) rotateY(-70deg); opacity: 1;
}
56% {
opacity: 1;
}
58% {
opacity: 0;
}
77% {
opacity: 0;
}
78% {
opacity: 1;
}
100% {
transform: rotateZ(270deg) translateX(70px) rotateZ(-270deg) rotateY(-70deg); opacity: 1;
}
}
<div class="earth">
<div class="orbit">
<div class="moon"></div>
</div>
</div>

Animate a skewed element in the skew angle in CSS

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>

CSS animations transitioning from behind other elements broken in Firefox

Here's a simple example of what I mean.
HTML
<div class="main-container">
<div class="ht-tx1"></div>
<div class="headtest"></div>
<div class="ht-tx2"></div>
</div>
CSS
.main-container {
width: 100%;
height: 200px;
margin: 250px 0 0 0;
position: relative;
background-color: yellow;
}
.headtest {
font-family: 'quicksand', helvetica;
background-color: #a2aba2;
width: 100%;
height: 200px;
position: absolute;
top: 0;
right: 0;
}
.ht-tx1 {
width: 100%;
height: 20px;
text-align: center;
background-color: #000;
animation: test-ani1 2s forwards;
position: absolute;
top: 0;
right: 0;
}
.ht-tx2 {
width: 100%;
height: 20px;
text-align: center;
background-color: #000;
animation: test-ani2 2s forwards;
position: absolute;
bottom: 0;
right: 0;
}
#keyframes test-ani1 {
100% {
transform: translateY(-20px);
}
}
#keyframes test-ani2 {
100% {
transform: translateY(20px);
}
}
-
If you view in Chrome, both black bars slide out perfectly. The one transitioning from behind, and the one in front.
If you view it in Firefox, the bar transitioning from behind is broken. It sometimes works, but mostly it ignores the slide animation and just appears at the end of the animation duration.
I've re-created this a number of times and it seems that items that transition from behind another element are broken in firefox.
I've tried using -moz- which doesn't work. IS there anything else you can think of?
I've tried it without the absolute positioning, with z-indexs. and nothing seems to work.
EDIT ----
I appreciate work-around ideas, but I'd really like to know the route cause of this if anyone knows?
Thanks very much.
It seems Firefox is inconsistent when animate the transform property, and I can't say why (yet), most likely a bug though.
Here is 2 workarounds to achieve the same effect
.main-container {
width: 100%;
height: 200px;
margin: 50px 0 0 0;
position: relative;
background-color: yellow;
}
.headtest {
font-family: 'quicksand', helvetica;
background-color: #a2aba2;
width: 100%;
height: 200px;
position: absolute;
top: 0;
right: 0;
}
.ht-tx1 {
width: 100%;
height: 20px;
text-align: center;
background-color: #000;
animation: test-ani1 2s forwards;
position: absolute;
top: 0;
right: 0;
}
.ht-tx2 {
width: 100%;
height: 20px;
text-align: center;
background-color: #000;
animation: test-ani2 2s forwards;
position: absolute;
bottom: 0;
right: 0;
}
#keyframes test-ani1 {
0% {
transform: translateY(-1px);
}
0.1% {
transform: translateY(0px);
}
100% {
transform: translateY(-20px);
}
}
#keyframes test-ani2 {
100% {
transform: translateY(20px);
}
}
<div class="main-container">
<div class="ht-tx1"></div>
<div class="headtest"></div>
<div class="ht-tx2"></div>
</div>
.main-container {
width: 100%;
height: 200px;
margin: 50px 0 0 0;
position: relative;
background-color: yellow;
}
.headtest {
font-family: 'quicksand', helvetica;
background-color: #a2aba2;
width: 100%;
height: 200px;
position: absolute;
top: 0;
right: 0;
}
.ht-tx1 {
width: 100%;
height: 20px;
text-align: center;
background-color: #000;
animation: test-ani1 2s forwards;
position: absolute;
top: 0;
right: 0;
}
.ht-tx2 {
width: 100%;
height: 0px;
text-align: center;
background-color: #000;
animation: test-ani2 2s forwards;
position: absolute;
bottom: 0;
right: 0;
}
#keyframes test-ani1 {
100% {
top: -20px;
}
}
#keyframes test-ani2 {
100% {
height: 20px;
bottom: -20px;
}
}
<div class="main-container">
<div class="ht-tx1"></div>
<div class="headtest"></div>
<div class="ht-tx2"></div>
</div>
The solution relies on the z-index property of your elements: if you don't specify it the elements lay out one on top of the others, following the flow of the HTML document, when their "position" is set to "absolute". So "ht-txt1" is underneath "headtest" and "ht-tx2" is on top of "headtest".
To correct this "ht-tx1" and "ht-tx2" should take a "z-index" value of -1, so they are hidden underneath "headtest".
As for FF compatibility you need to prefix your "transform" effect with -moz-, check http://caniuse.com/#feat=transforms2d for more details.
Here's the CSS style code:
.main-container {
width: 100%;
height: 200px;
margin: 250px 0 0 0;
position: relative;
background-color: yellow;
}
.headtest {
font-family: 'quicksand', helvetica;
background-color: #a2aba2;
width: 100%;
height: 200px;
position: absolute;
top: 0;
right: 0;
}
.ht-tx1 {
width: 100%;
height: 20px;
text-align: center;
background-color: #000;
animation: test-ani1 2s forwards;
position: absolute;
top: 0;
right: 0;
z-index: -1;
}
.ht-tx2 {
width: 100%;
height: 20px;
text-align: center;
background-color: #000;
animation: test-ani2 2s forwards;
position: absolute;
bottom: 0;
right: 0;
z-index: -1;
}
#keyframes test-ani1 {
100% {
-ms-transform: translateY(-20px);
-webkit-transform: translateY(-20px);
-moz-transform: translateY(-20px);
transform: translateY(-20px);
}
}
#keyframes test-ani2 {
100% {
-ms-transform: translateY(20px);
-webkit-transform: translateY(20px);
-moz-transform: translateY(20px);
transform: translateY(20px);
}
}