Click here to Skip to main content
65,938 articles
CodeProject is changing. Read more.
Articles / web / CSS3

Animating through CSS

5.00/5 (6 votes)
4 Jun 2014CPOL5 min read 26.5K   101  
Using CSS to animate a Solar System

Introduction

After doing an HTML exercise on how to build a solar system (see CodeCademy), I thought to myself "this can be more animated, the positions being less absolute and no images". For that reason, I've decided to build this short tip/trick that hopefully will help everyone to exercise their CSS3 skills. If you get stuck, the same code will be provided for reference.

Image 1

Important

CSS3 is not supported on all Browsers. Please check CSS3 compatibility if you have any trouble as you go through the steps. My best advice here is for you to make sure you are using the latest version of your browser.

Objectives

My objectives here are quite simple:

  1. HTML

    • Have a quick look at the basics: Divs and formatting
    • Plan design to do less on CSS: IDs, Classes and styling
  2. CSS

    • Postions (absolute and relative): Some uses for each
    • CSS3 Borders: Making things round
    • Gradient Colors and Shadows: Reducing the need for images
    • Animations: Replacing JavaScript on basic stuff

Solar System

Step 1: HTML

The first thing we are going to do is to write our HTML. I understand that it is not the conventional way to do it for some people, but for the new guys it will be helpful (and cool :)) to see the changes happening as we add the CSS after that. So, here is the first part of the code:

HTML
<!-- We are going to have 4 stars shinning on the background -->
<div id="StarA" class="Stars"></div>
<div id="StarB" class="Stars"></div>
<div id="StarC" class="Stars"></div>
<div id="StarD" class="Stars"></div>

<!-- And a comet passing by the system -->
<div id="Comet"></div>    

As you can see, each div has an identifier and we are adding them because each will have properties set in a specific way for them. For those who have shared properties (stars) we are assigning a class to them. By doing that, we can reduce the amount of rework in case there is a change.

For the next part, we are adding the solar system.

HTML
<!-- This div will act as a container for the solar system -->
<div id="StarSystem">
    <!-- The orbit will have a planet going around it and an the next orbit closer to the sun. -->
    <div class="Orbit">

        <!-- The planet's logic works in a similar way to the stars. -->
        <div id="WhitePlanet" class="Planet"></div>
        
        <div class="Orbit">

            <div id="BluePlanet" class="Planet"></div>

            <div class="Orbit">

                <div id="GreenPlanet" class="Planet"></div>

                <div class="Orbit">
                    
                    <div id="OrangePlanet" class="Planet"></div>
                    
                    <div class="Orbit">

                        <div id="RedPlanet" class="Planet"></div>
                            
                            <!-- Yes, I know that the sun is a star, but here we will be treating it differently. -->
                            <div id="Sun"> 
                            </div>
                    </div>
                </div>
            </div>
        </div>
    </div>
</div>    

Without further explanation, can you understand what we are doing? This is a good moment to stop and reflect on it.

This second part is actually not so difficult. If you really think, we are doing the same as getting a box and placing an item and a smaller box in it. Or if you have ever made or drawn a solar system, we are getting a space and defining orbits proportionally smaller to the previous one. Can you figure the idea behind the sun div? Basically, we are trying to make sure it won't burn the planet in its innermost orbit.

This concludes the HTML part of our project. As you may have noticed, it looks a bit weird, but that is only because there is no CSS applied to it.

Step 2: CSS

Here is where things will take form. In a CSS file or a style tag, type the following:

CSS
*{
    /*This is a good way to check how/where everything is placed, 
    /*just make sure to comment or remove it at the end 
    /*because 1 px per item can eventually cause distortion.
    /*border: 1px dashed yellow;*/
    
    /*Removes the margin space from all tags.*/
    margin:0px;
}

body{
    /*The space will be black and take the whole screen.*/
    background-color: black;
    height:100%;
    width:100%;
}

/* A container for the sun, orbits and planets*/
#StarSystem{
    margin: auto;
    width: 450px;
    height: 450px;
}

#StarA{
    top:100px;
    left:850px;
}

#StarB{
    top:120px;
    left:550px;
}

#StarC{
    top:150px;
    left:800px;
}

#StarD{
    top:300px;
    left:440px;
}

.Stars{
    position:absolute;
    
    border-radius: 50%;
    
    height:10px;
    width:10px;
    
    background: -webkit-radial-gradient(white, lightblue, blue); /* Safari 5.1 to 6.0 */
    background: -o-radial-gradient(white, lightblue, blue); /* For Opera 11.6 to 12.0 */
    background: -moz-radial-gradient(white, lightblue, blue); /* For Firefox 3.6 to 15 */
    background: radial-gradient(white, lightblue, blue); /* Standard syntax (must be last) */
    
    -webkit-animation: twinkle 3s infinite ease-in-out alternate;
    animation: twinkle 3s infinite ease-in-out alternate;    
}

@-webkit-keyframes twinkle {
    0% { box-shadow: 0 0 50px white; }
    50% { box-shadow: 0 0 100px white; }
    100% { box-shadow: 0 0 180px white; }
}  

@keyframes twinkle {
    0% { box-shadow: 0 0 50px white; }
    50% { box-shadow: 0 0 100px white; }
    100% { box-shadow: 0 0 180px white; }
}   

This can seem to be a lot, but everything up to the "Stars" class should be quite straightforward considering that it is mostly positioning of the items. At the .Stars, you can see that the position was changed to absolute, this is done to have the stars always at the same place and regardless of any other objects as well as having them not interfering with them.

Still at the Stars class, there are some new CSS3 features as well. The first one being the border-radius, which allows to change an item from having slightly round borders to being actually a circle. Additionally, you can see that there is a gradient effect (you might need to make the stars a bit bigger for that!), which is quite useful and avoids the need of having to use an image to achieve this result.

Last but not least, the animation allows basic movements without the need for JavaScript. It definitely does not replace it, but this attribute can be quite useful if you want to get some basic stuff done quickly. I don't think that the compatibility should be much of an issue any longer. But it is interesting to always keep the extra stuff to guarantee most people will see the same as the developer.

This is a good point to check the code and compare it with what was previous to starting the CSS styling. After that, we can add the following:

CSS
.Planet {
    border-radius:50%;
    height:5%;
    width:5%;
    position: relative;
    left:30%;
}

#RedPlanet{
    background-color:red;
}

#OrangePlanet{
    background-color:orange;
}

#GreenPlanet{
    background-color:green;
}

#BluePlanet{
    background-color:blue;
}

#WhitePlanet{
    background-color:white;
}

.Orbit{      
    height:80%;
    width:80%;
    margin:5% 10% 10% 10%;
    border-radius:50%;
    border: 0.5px dotted green;
        
    -webkit-animation: spin-left 20s linear infinite;
    animation: spin-left 20s linear infinite;
}

#Sun {
    position:relative;

    margin:20% auto;
    
    border-radius: inherit;

    height:50%;
    width:50%;
    
    background-color:yellow;    
    
    -webkit-animation: shine 4s infinite ease-in-out alternate;
    animation: shine 4s infinite ease-in-out alternate;
}

/*For Chrome, Safari and Opera */
@-webkit-keyframes spin-left {
  100% {
    -webkit-transform: rotate(-360deg);
       -moz-transform: rotate(-360deg);
        -ms-transform: rotate(-360deg);
         -o-transform: rotate(-360deg);
            transform: rotate(-360deg);
  }
}

/*Standard Syntax for other browsers*/
@keyframes spin-left {
  100% {
    -webkit-transform: rotate(-360deg);
       -moz-transform: rotate(-360deg);
        -ms-transform: rotate(-360deg);
         -o-transform: rotate(-360deg);
            transform: rotate(-360deg);
  }
}

/*For Chrome, Safari and Opera */
@-webkit-keyframes shine {
    0% { box-shadow: 0 0 30px yellow; }
    50% { box-shadow: 0 0 80px yellow; }
    100% { box-shadow: 0 0 150px yellow; }
}

/*Standard Syntax for other browsers*/
@keyframes shine {
    0% { box-shadow: 0 0 30px yellow; }
    50% { box-shadow: 0 0 80px yellow; }
    100% { box-shadow: 0 0 150px yellow; }
}    

Our coding part is getting bigger each time, isn't it? But that is just because we have seen most of this stuff. There is a planet class that will provide all attributes that are common between the planets and the ID that will give specific stuff (in our example it is only the color) to each planet.

The border-radius is there again to make things round and I tried to have everything measured as a proportional size. This way, the only requirement to increase and decrease the size of our system is to set the width and height in the #StarSystem and all items will resize accordingly. A special note goes to the Orbit class, can you figure out?

The animation (I would need a whole article just about them) may look a bit difficult, but they are actually quite simple. spin-left rotates counter clock wise while shine uses another of CSS's new feature, the box-shadow, which is very useful for a variety of stuff.

Conclusion

Doing this small solar system using no images and trying to use as much CSS3 as possible was fun, sometimes frustrating, all the time amazing and impressive when we think I didn't have to use JavaScript at all. If you enjoy it, please have a look at:

They are my source for this project and the last one was the base of everything. Without it, I wouldn't have wondered, how else can I build/change it so it is less dependable on images, use classes, and proportional growth of things. I've added the source of this project to the article and there is a small extra for anyone who would like to continue working on it. Have fun!

License

This article, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)