Why isn't my animation element centered? - html

I'm stuck on this for so long, why the car isn't swerve around the middle line with my animation? it seems like a bit off to the right?
.car {
width: 40px;
height: 60px;
background: #f00;
left: 50%;
transform: translate(-50%, 0);
animation: swerve 2s linear infinite;
top: 10%;
position: absolute;
}
#keyframes swerve {
0% {
transform: translate(-50%, 0);
}
50% {
transform: translate(50%, 0);
}
}
.road {
width: 200px;
background: black;
height: 500px;
display: block;
position: relative;
}
.road-middle {
border: 1px dotted #fff;
transform: rotate(90deg);
display: block;
position: relative;
top: 200px;
}
<div class='road'>
<span class="road-middle"></span>
<div class='car'></div>
</div>
Also how to control the length of the middle's border?

You use left:50% but don't calculate the car width. To fix this, you can alter the animation like this:
.car {
width: 40px;
height: 60px;
background: #f00;
left: 50%;
animation: swerve 2s linear infinite;
top: 10%;
position: absolute;
}
#keyframes swerve {
0% {
transform: translate(-50%, 0);
}
25% {
transform: translate(-100%, 0);
}
75% {
transform: translate(0%, 0);
}
100% {
transform: translate(-50%, 0);
}
}
.road{
width:200px;
background:black;
height:500px;
display:block;
position:relative;
}
.road-middle{
border: 1px dotted #fff;
transform: rotate(90deg);
display: block;
position: relative;
top: 200px;
}
<div class='road'>
<span class="road-middle"></span>
<div class='car'></div>
</div>
To control the length of the road-middle element, you can do the following:
.road-middle{
border: 1px dotted #fff;
display: block;
/* remove the rotation */
/*position the line */
position: absolute;
left:calc(50% - 1px);
/*controll the length of the line */
height:200px;
top:150px;
}
.car {
width: 40px;
height: 60px;
background: #f00;
left: 50%;
animation: swerve 2s linear infinite;
top: 10%;
position: absolute;
}
#keyframes swerve {
0% {
transform: translate(-50%, 0);
}
25% {
transform: translate(-100%, 0);
}
75% {
transform: translate(0%, 0);
}
100% {
transform: translate(-50%, 0);
}
}
.road{
width:200px;
background:black;
height:500px;
display:block;
position:relative;
}
.road-middle{
border: 1px dotted #fff;
display: block;
/* remove the rotation */
/*position the line */
position: absolute;
left:calc(50% - 1px);
/*controll the length of the line */
height:200px;
top:150px;
}
<div class='road'>
<span class="road-middle"></span>
<div class='car'></div>
</div>

the .car is not centered on the .road , change the css for the .car to this
.car{
left:0;
right:0;
margin:0 auto;
}
to change the length of the road-middle dotted line, do not rotate it, but instead make it with width:0 and height:100%, use this css :
.road-middle{
border: 1px dotted #fff;
display: block;
position: relative;
top: 0;
width:0px;
height:100%;
left:0;
right:0;
margin:0 auto;
}
See snippet below
.car {
width: 40px;
height: 60px;
background: #f00;
left: 0;
right:0;
margin:0 auto;
transform: translate(-50%, 0);
animation: swerve 2s linear infinite;
top: 10%;
position: absolute;
}
#keyframes swerve {
0% {
transform: translate(-50%, 0);
}
50% {
transform: translate(50%, 0);
}
}
.road {
width: 200px;
background: black;
height: 500px;
display: block;
position: relative;
}
.road-middle {
border: 1px dotted #fff;
display: block;
position: relative;
top: 0;
width:0px;
height:100%;
left:0;
right:0;
margin:0 auto;
}
<div class='road'>
<span class="road-middle"></span>
<div class='car'></div>
</div>

If you comment this 2 lines
transform: translate(-100%, 0);
animation: swerve 2s linear infinite;
you block isn't centered..
So replace by (or fix your first problem)
#keyframes swerve {
0% {
transform: translate(-100%, 0);
}
50% {
transform: translate(0%, 0);
}
}

Adding left: 50% aligns the leftmost edge of your element with the center. To align vertical center of your element with container's center you need to add negative margin equal to half that element's width, which pushes it back to left a little. E.g. here I have added margin-left: -20px; to your car and now it is in center:
.car {
width: 40px;
height: 60px;
background: #f00;
left: 50%;
transform: translate(-50%, 0);
animation: swerve 2s linear infinite;
top: 10%;
margin-left: -20px;
position: absolute;
}
#keyframes swerve {
0% {
transform: translate(-50%, 0);
}
50% {
transform: translate(50%, 0);
}
}
.road {
width: 200px;
background: black;
height: 500px;
display: block;
position: relative;
}
.road-middle {
border: 1px dotted #fff;
transform: rotate(90deg);
display: block;
position: relative;
top: 200px;
}
<div class='road'>
<span class="road-middle"></span>
<div class='car'></div>
</div>

Because you have mentioned the with 40px and moved the car from left by 50% which means your car is situated at 50%+40px to right. Try following code.
.car {
width: 18%;
height: 60px;
background: #f00;
left: 41%;
transform: translate(-50%, 0);
animation: swerve 2s linear infinite;
top: 10%;
position: absolute;
}
#keyframes swerve {
0% {
transform: translate(-50%, 0);
}
50% {
transform: translate(50%, 0);
}
}
.road {
width: 200px;
background: black;
height: 500px;
display: block;
position: relative;
}
.road-middle {
border: 1px dotted #fff;
transform: rotate(90deg);
display: block;
position: relative;
top: 200px;
}
<div class='road'>
<span class="road-middle"></span>
<div class='car'></div>
</div>

left: calc(50% - 20px);
You are not subtracting the car width

Related

How can I rotate an object(div) around a circle margin? Css only

I want to move the blue container around the circle (with it's bottom margin if possible). What I succeded until now is to move it by it's center(still not so smooth).
Does css has any option to translate & rotate in a circle direction? What I tried was to translate and rotate at the same time by using this three points (top, right, and top-right) of the circle, because I only need it to rotate 90 deg.
#mainContent{ position: relative;
display: block;
width: 100vw;
border: none;
margin: 0 auto;
height: 100vh;
overflow: visible;
background: black;
}
#circle{
position: absolute;
left: 50%;
top: 50%;
background: red;
border-radius: 50%;
width: 100px;
height: 100px;
transform: translate(-50%, -50%);
}
.container{
position: absolute;
left: 50%;
top: 50%;
background: pink;
width: 100px;
height: 100px;
transform: translate(-50%, -50%);
}
#element{
position: absolute;
top: 50%;
left: 50%;
width: 20px;
height: 60px;
background: blue;
transform-origin: center;
transform: translate(-50%, -50%);
animation: orbit 3s linear infinite;
}
#keyframes orbit{
0% {
transform-origin: center;
transform: translate(-50%, calc(-50% - 50px)) rotate(0deg);
}
50%{
transform-origin: center;
transform: translate(calc(-50% + 35.35px), calc(-50% - 35.35px)) rotate(45deg);
}
100% {
transform-origin: center;
transform: translate(calc(-50% + 50px), -50%) rotate(90deg);
}
}
*{
margin: 0;
}
<div id="mainContent">
<div class="container"></div>
<div id="circle"></div>
<div id="element"></div>
</div>
You have to play with the transform-origin
#mainContent {
position: relative;
display: block;
width: 100vw;
border: none;
margin: 0 auto;
height: 100vh;
overflow: visible;
background: black;
}
#circle {
position: absolute;
left: 50%;
top: 50%;
background: red;
border-radius: 50%;
width: 100px;
height: 100px;
transform: translate(-50%, -50%);
}
.container {
position: absolute;
left: 50%;
top: 50%;
background: pink;
width: 100px;
height: 100px;
transform: translate(-50%, -50%);
}
#element {
position: absolute;
top: 50%;
left: calc(50% - 10px);
width: 20px;
height: 60px;
background: blue;
transform-origin: top center;
animation: orbit 3s linear infinite;
}
#keyframes orbit {
to {
transform: rotate(360deg);
}
}
* {
margin: 0;
}
<div id="mainContent">
<div class="container"></div>
<div id="circle"></div>
<div id="element"></div>
</div>
If i understand right, you need to set the translate-origin to the side which the blue rectangle reach the center of the red circle, check the snipet:
(hover the red circle to hide the blue rectangle)
div {
position: relative;
width: 200px;
height: 200px;
margin: 10em auto;
}
.round {
border-radius: 100%;
background: red;
}
.round:hover + .rectangle{background:transparent;}
.rectangle {
width: 100%;
height: 20px;
background: blue;
position: absolute;
top: 0;
bottom: 0;
right: 50%;
margin: auto;
transform-origin: right;
transform: rotate(0deg);
animation: orbit 3s linear infinite;
}
.moon{
width:50px;height:50px;
background:white;
border:1px solid gray;
border-radius:100%;
position:absolute;
top:0;
bottom:0;
margin:auto;
}
#keyframes orbit {
0% {
transform: rotate(0deg);
}
50% {
transform: rotate(180deg);
}
100% {
transform: rotate(359deg);
}
}
<div>
<div class="round"></div>
<div class="rectangle">
<div class="moon"></div>
</div>
</div>
Don't center the element but put it on the top side and then adjust the transform-origin to make it at the center of the circle:
#mainContent {
position: relative;
margin: 0 auto;
height: 100vh;
overflow: visible;
background: black;
}
#circle {
position: absolute;
left: 50%;
top: 50%;
background: red;
border-radius: 50%;
width: 100px;
height: 100px;
transform: translate(-50%, -50%);
}
.container {
position: absolute;
left: 50%;
top: 50%;
background: pink;
width: 100px;
height: 100px;
transform: translate(-50%, -50%);
}
#element {
position: absolute;
top: calc(50% - 80px); /* 80 = (60 + 100)/2*/
left: calc(50% - 10px);
width: 20px;
height: 60px;
background: blue;
transform-origin: 50% calc(100% + 20px); /* 20 = (100 - 60)/2 */
animation: orbit 3s linear infinite;
}
#keyframes orbit {
100% {
transform: rotate(360deg);
}
}
* {
margin: 0;
}
<div id="mainContent">
<div class="container"></div>
<div id="circle"></div>
<div id="element"></div>
</div>

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.

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>

Sphere revolving around another sphere- CSS

I am trying to create a pure CSS design of a sphere revolving(orbiting) around another sphere. Like a moon orbiting the sun to be precise. The image of the earth fits in properly into the sphere of earth. But the image of moon does not fit into the sphere of moon.
The image attached might help to understand my question better
Below is my CSS script
.center {
position: absolute;
top: 50%;
left: 50%;
transform: translate(-50%, -50%);
width: 200px;
height: 200px;
border-radius: 50%;
background: transparent;
}
.center .earth {
position: absolute;
top: 0;
width: 200px;
height: 200px;
background-image: url(https://www.publicdomainpictures.net/pictures/90000/velka/earth-map.jpg);
margin: 3em auto;
border-radius: 50%;
background-size: 630px;
animation: spin 30s linear alternate infinite;
box-shadow: inset 20px 0 80px 6px rgba(0, 0, 0, 1);
color: #000;``
}
.center .earth .moon {
position: absolute;
top: calc(50% - 1px);
left: 50%;
width: 200px;
height: 2px;
transform-origin: left;
border-radius: 50%;
/*animation: rotate 10s linear infinite;*/
}
.center .earth .moon::before {
content: url(moon.jpg);
position: absolute;
top: -25px;
right: 0;
width: 50px;
height: 50px;
background: #fff;
border-radius: 50%;
/*animation: rotate 10s linear infinite;*/
}
#keyframes rotate {
0% {
transform: rotate(0deg);
}
100% {
transform: rotate(360deg);
}
}
#keyframes spin {
100% {
background-position: 100%;
}
}
Make this change content: "";
to background-image: url(moon.jpg);
and remove background: #fff from classname .center .earth .moon::before
body {
background: black;
}
.center {
position: absolute;
top: 50%;
left: 50%;
transform: translate(-50%, -50%);
width: 200px;
height: 200px;
border-radius: 50%;
background: transparent;
}
.center .earth {
position: absolute;
top: 0;
width: 200px;
height: 200px;
background-image: url(https://www.publicdomainpictures.net/pictures/90000/velka/earth-map.jpg);
margin: 3em auto;
border-radius: 50%;
background-size: 630px;
animation: spin 30s linear alternate infinite;
box-shadow: inset 20px 0 80px 6px rgba(0, 0, 0, 1);
color: #000;``
}
.center .earth .moon {
position: absolute;
top: calc(50% - 1px);
left: 50%;
width: 200px;
height: 2px;
transform-origin: left;
border-radius: 50%;
/*animation: rotate 10s linear infinite;*/
}
.center .earth .moon::before {
content: "";
background-image: url(https://encrypted-tbn0.gstatic.com/images?q=tbn:ANd9GcRsvjrANMGI8aBJSFbsHteVa04rcB1IjjNsbrhm8vTLflfpiG133g);
position: absolute;
top: -25px;
right: 0;
width: 50px;
height: 50px;
border-radius: 50%;
/*animation: rotate 10s linear infinite;*/
}
#keyframes rotate {
0% {
transform: rotate(0deg);
}
100% {
transform: rotate(360deg);
}
}
#keyframes spin {
100% {
background-position: 100%;
}
}
<div class="center">
<div class="earth">
<div class="moon">
</div>
</div>
</div>

CSS Transforms Inheritance Issue

The following HTML5 and CSS3 animation is giving me two different issues and I've not been able to find previous answers to the question that have worked on my code. I'm curious if I'm doing something completely wrong here.
I have tried the solutions in this question, and this one with no results.
The two issues:
1.) The moon orbit transforms fine; the moon, as a child element, transforms as well. I attempt to apply the opposite transform but it doesn't appear to have any effect.
2.) I'm trying to alter the z-index so the moon goes behind the planet. The orbit border is temporary so no worries there but no matter what I set the z-index to I can't get the effect.
body {
height: 100%;
top: 0px;
bottom: 0px;
margin-top: 300px;
background-color: #143856;
}
.moonorbit {
position: relative;
top: -249px;
left: 309px;
width: 500px;
height: 500px;
border: 2px solid white;
border-radius: 50%;
-moz-transform: rotateX(75deg);
-webkit-transform: rotateX(75deg);
-o-transform: rotateX(75deg);
-ms-transform: rotateX(75deg);
transform: rotateX(75deg);
}
.mooncontainer {
position: absolute;
top: 175px;
left: 175px;
width: 150px !important;
height: 150px;
-moz-transform: rotateX(-75deg);
-webkit-transform: rotateX(-75deg);
-o-transform: rotateX(-75deg);
-ms-transform: rotateX(-75deg);
transform: rotateX(-75deg);
animation: moon-orbit 10s linear infinite;
}
.moon {
width: 150px !important;
height: 150px;
border-radius: 50%;
background: red url(img/planets_MOON.png) no-repeat;
background-size: cover;
animation: rotate 10s linear infinite;
}
.earth {
position: absolute;
width: 417px;
top: 100px;
left: 350px;
z-index: 0;
height: 209px;
}
.earth .planet {
/*width: 417px !important;
height: 417px;*/
width: 300px !important;
height: 300px;
background: yellow url(img/planets_EARTH.png) no-repeat;
background-size: cover;
border-radius: 50%;
margin: 0 auto;
}
/*Moon Orbit*/
#keyframes moon-orbit {
0% {
transform: rotateZ(0deg) translateX(250px);
}
100% {
transform: rotateZ(360deg) translateX(250px);
}
}
#keyframes rotate {
0% {
z-index: 5;
transform: rotateZ(0deg);
}
25% {
z-index: -5;
}
50% {
z-index: -5;
}
75% {
z-index: 5;
}
100% {
z-index: 5;
transform: rotateZ(-360deg);
}
}
<body>
<div class="earth">
<div class="planet"></div>
</div>
<div class="moonorbit">
<div class="mooncontainer">
<div class="moon"></div>
</div>
</div>
</body>
About your first issue, you are applying the technique ok. But there are 2 transformations that you need to correct, the one from the animation of the circle, that you have done, and the one from the inclination of the orbit (the rotateX(75deg)
This would be your demo with the correction applied
body {
height: 60%;
top: 0px;
bottom: 0px;
margin-top: 300px;
background-color: #143856;
}
.moonorbit {
position: relative;
top: -300px;
left: 209px;
width: 500px;
height: 500px;
border: 2px solid white;
border-radius: 50%;
transform: rotateX(75deg);
transform-style: preserve-3d;
}
.mooncontainer {
position: absolute;
top: 175px;
left: 175px;
width: 150px !important;
height: 150px;
-webkit-transform: rotateX(-75deg);
transform: rotateX(-75deg);
animation: moon-orbit 10s linear infinite;
transform-style: preserve-3d;
}
.moon {
width: 150px !important;
height: 150px;
border-radius: 50%;
background-color: white;
background-size: cover;
animation: rotate 10s linear infinite;
transform-style: preserve-3d;
}
.earth {
position: absolute;
width: 417px;
top: 100px;
left: 250px;
z-index: 0;
height: 209px;
}
.earth .planet {
/*width: 417px !important;
height: 417px;*/
width: 300px !important;
height: 300px;
background-color: lightgreen;
background-size: cover;
border-radius: 50%;
margin: 0 auto;
}
/*Moon Orbit*/
#keyframes moon-orbit {
0% {
transform: rotateZ(0deg) translateX(250px);
}
100% {
transform: rotateZ(360deg) translateX(250px);
}
}
#keyframes rotate {
0% {
transform: rotateZ(0deg) rotateX(-75deg); /* added rotateX(-75deg) to compensate */
}
100% {
transform: rotateZ(-360deg) rotateX(-75deg);
}
}
<div class="earth">
<div class="planet"></div>
</div>
<div class="moonorbit">
<div class="mooncontainer">
<div class="moon"></div>
</div>
</div>
About the second issue, your best bet is to work all the time in 3d, so it will be automatically solved. Another technique that makes it simpler is to chain the transforms. In my demo I have chained everything, so it's easier to get the control (and you have a simpler HTML
body {
height: 60%;
top: 0px;
bottom: 0px;
background-color: #143856;
}
.moon {
width: 150px;
height: 150px;
border-radius: 50%;
background: url(http://i.stack.imgur.com/L3IE5.jpg);
background-size: 120%;
background-position: center center;
animation: rotate 10s linear infinite;
transform-style: preserve-3d;
margin: auto;
position: absolute;
left: 0px;
right: 0px;
top: 0px;
bottom: 0px;
}
.earth {
position: absolute;
width: 300px;
height: 300px;
background: url(http://i.stack.imgur.com/5sqwZ.jpg);
background-size: 140%;
background-position: center center;
border-radius: 50%;
margin: 100px 200px;
perspective: 1500px;
transform-style: preserve-3d;
}
#keyframes rotate {
0% {
transform: rotateX(-75deg) rotateZ(0deg) translateX(300px) rotateZ(0deg) rotateX(75deg);
}
100% {
transform: rotateX(-75deg) rotateZ(-360deg) translateX(300px) rotateZ(360deg) rotateX(75deg);
}
}
<div class="earth">
<div class="moon"></div>
</div>
Trying to fix this with z-index will end in failure 70% all the time. lol See what I did there? Anyways, your best bet is to do this with a keyframes. Create a keyframe to draw out your path and to be honest you will need other things that would take a while to explain but How about I'll post my code here and the DEMO and you will be able to see the difference?
HTML
<div id="universe" class="scale-stretched">
<div id="solar-system" class="earth">
<div id="earth" class="orbit">
<div class="pos">
<div class="planet"> </div>
</div>
</div>
<div id="sun"> </div>
</div>
</div>
CSS
#universe {
z-index: 1;
position: absolute;
overflow: hidden;
width: 100%;
height: 100%;
background-position: center 40%;
background-repeat: no-repeat;
background-size: cover; }
#solar-system {
position: absolute;
width: 100%;
height: 100%;
transform-style: preserve-3d; }
.orbit {
position: absolute;
top: 50%;
left: 50%;
border: 1px solid rgba(255, 255, 255, 0.2);
border-radius: 50%;
transform-style: preserve-3d;
animation-name: orbit;
animation-iteration-count: infinite;
animation-timing-function: linear; }
.orbit .orbit {
animation-name: suborbit; }
.pos {
position: absolute;
top: 50%;
width: 2em;
height: 2em;
margin-top: -1em;
margin-left: -1em;
transform-style: preserve-3d;
animation-name: invert;
animation-iteration-count: infinite;
animation-timing-function: linear; }
#sun, .planet, #earth{
position: absolute;
top: 50%;
left: 50%;
width: 1em;
height: 1em;
margin-top: -0.5em;
margin-left: -0.5em;
border-radius: 50%;
transform-style: preserve-3d; }
#sun {
background-color: #FB7209;
background-repeat: no-repeat;
background-size: cover;
box-shadow: 0 0 60px rgba(255, 160, 60, 0.4); }
.planet {
background-color: #202020;
background-repeat: no-repeat;
background-size: cover;
animation-iteration-count: infinite;
animation-timing-function: linear; }
.ring {
position: absolute;
top: 50%;
left: 50%;
border-radius: 50%; }
#earth {
z-index: 8; }
#sun {
z-index: 1; }
#keyframes orbit {
0% {
transform: rotateZ(0deg); }
100% {
transform: rotateZ(-360deg); } }
#keyframes invert {
0% {
transform: rotateX(-90deg) rotateY(360deg) rotateZ(0deg); }
100% {
transform: rotateX(-90deg) rotateY(0deg) rotateZ(0deg); } }
.view-3D #solar-system {
transform: rotateX(75deg); }
.view-3D #sun {
transform: rotateX(-90deg); }
#earth .pos,
#earth .planet,
#earth.orbit {
animation-duration: 12.00021s; }
#earth .orbit .pos,
#earth .orbit {
animation-duration: 0.89764s; }
.scale-stretched #sun {
font-size: 24em; }
.scale-stretched #earth .planet {
font-size: 3.92em; }
.scale-stretched #earth.orbit {
width: 56em;
height: 56em;
margin-top: -28em;
margin-left: -28em; }
body { background: #000; }
#sun { background: yellow; }
#earth .planet { background: blue; }
And some simple jQuery to get the 3D effect so it looks 2D but moves 3D
$(window).load(function(){
var body = $("body"),
universe = $("#universe"),
solarsys = $("#solar-system");
var init = function() {
body.removeClass('view-2D opening').addClass("view-3D").delay(2000).queue(function() {
$(this).removeClass('hide-UI').addClass("set-speed");
$(this).dequeue();
});
};
init();
});
Here is a DEMO
I think if you use my code you'll probably be better off than fixing yours. Just a suggestion ;)