Home Blog Creating CSS animations (tutorial)

Creating CSS animations (tutorial)

Blog, February 26, 2015

light shadow css stars glowing glittering

From Russia with Love: an animated winter scene in CSS (tutorial)

Let’s take a break from website interfaces and just draw something nice in CSS. We are going to draw this beautiful winter-inspired picture.

See on JSfiddle.

In the article you will find a step-by-step instruction of creating this scene. The described code works on all webkit browsers (Chrome, Safari, Opera – last versions). To make it work in other browsers, instead of a prefix –webkit, you have to use other relevant prefixes (-moz, -ms, -o).

First, we create the scene and sky.

     <div class="scene"></div>

        .scene {
            position: relative;
            width: 800px;
            height: 600px;
            margin: 50px auto;
            overflow: hidden;
            background-image: -webkit-linear-gradient(top, #011428, #032a54);
        }

Using linear-gradient (top, #011428, #032a54) we created the scene continuous gradient from the top dark blue (#011428) down to lighter color (#032a54).

background css tutorial animation

Then, let’s draw snowdrifts. The basis for them will be ellipses that can be created by taking divs and giving them a border-radius: 50%.

   .ground {
            position: absolute;
            width: 770px;
            height: 200px;
            border-radius: 50%;
            background-color: #99a;
        }

css animation ellipse

Four ellipses should be placed at the bottom of the picture.

    <div class="ground back-1"></div>
    <div class="ground back-2"></div>
    <div class="ground front"></div>
    <div class="ground front-2"></div>
.ground {
    width: 400px;
    background-color: #f5f5f5;
    border-radius: 50%;
    width: 770px;
    height: 200px;
    position: absolute;
    bottom: 0;
    margin-bottom: -80px;
    right: 140px;
    background-color: #99a;
}
.ground.back-1 {left: 180px;}
.ground.front {margin-bottom: -124px;left: -27px;}
.ground.front-2 {margin-bottom: -109px;right: -508px;}

background shadow css animation

We make the snowdrifts more realistic by adding to the class .ground some shadow.

    box-shadow: 0 0 100px #457eb2 inset;

shadow css animation inside out

Let’s draw the moon and stars.

        <div class="moon"></div>
        <div class="stars">
            <div class="star"></div>
            <div class="star"></div>
            <div class="star"></div>
            <div class="star"></div>
            <div class="star"></div>
            <div class="star"></div>
            <div class="star"></div>
        </div>
.moon {
    position: absolute;
    width: 60px;
    height: 60px;
    top: 100px;
    left: 100px;
    background-color: #ffffaa;
    border-radius: 50%;
}

.stars {
    position: absolute;
    width: 100%;
    height: 100%;
}

.star {
    position: absolute;
    border-radius: 50%;
    width: 1px;
    height: 1px;
    background-color: #ffffff;
}

.star:nth-child(1) {top: 100px;left: 685px;}
.star:nth-child(2) {top: 37px;left: 537px;}
.star:nth-child(3) {top: 150px;left: 350px;}
.star:nth-child(4) {top: 50px;left: 320px;}
.star:nth-child(5) {top: 30px;left: 755px;}
.star:nth-child(6) {top: 70px;left: 483px;}
.star:nth-child(7) {top: 18px;left: 80px;}

moon stars animation css

Then we add the lighting (or glowing) effect to the moon.

box-shadow: 0 0 40px #ffffaa;

The same goes for the stars.

box-shadow: 0 0 10px 2px white;

light shadow css stars glowing glittering

Now, let’s build a house. It is made of a roof, walls, a window and a chimney. This can be done by making a page layout.

     <div class="house">
            <div class="chimney"></div>
            <div class="roof">
                <div class="roof-wall"></div>
            </div>
            <div class="wall"></div>
            <div class="window"></div>
        </div>
     .house {
            position: absolute;
            width: 300px;
            height: 365px;
            bottom: 50px;
            right: 110px;
        }

We draw the wall. The log house effect can be created with the help of a repeating gradient:

        .house .wall {
            width: 100%;
            height: 200px;
            position: absolute;
            bottom: 0;
            background-color: #180c00;
            background: repeating-linear-gradient(to bottom, #573808 0%,#3a1e12 15%);
        }

log shadow css animation tutorial

Now, it is a turn for a window. It will be done by div with a yellow background and a brown frame.

        .house .window {
            position: absolute;
            height: 70px;
            width: 65px;
            background-color: #cccc00;
            border: 5px solid #3a1e12;
            bottom: 53px;
            left: 110px;
            box-shadow: 0 0 5px black;
        }

window css animation

We add a frame and the glowing effect to it by using box-shadow.

       <div class="window">
            <div class="frame"></div>
            <div class="frame"></div>
            <div class="light"></div>
        </div>
       .house .window .frame:nth-child(1) {
            position: absolute;
            height: 100%;
            left: 50%;
            margin-left: -3px;
            width: 7px;
            background-color: #3a1e12;
        }

        .house .window .frame:nth-child(2) {
            position: absolute;
            width: 100%;
            top: 30%;
            height: 7px;
            background-color: #3a1e12;
        }

        .house .window .light {
            width: 100%;
            height: 100%;
            background-color: #ffff00;
            opacity: 0.5;
            box-shadow: 0 0 100px yellow;
        }

glowing window css animation

The process of building a roof starts with creating tile roofing using div border.

    .house .roof .roof-wall {
        position: absolute;
        width: 280px;
        height: 280px;
        background-color: #573808;
        left: 25px;
        top:60px;
        border: 5px solid #3a1e12;
        box-shadow: 0 0 30px black inset;
    }

roof css frame shadow

To make a wall paneling effect, a repeating gradient is once again used. Here it should be turned at 45 degrees.

background: repeating-linear-gradient(45deg, #573808 0%,#573808 5%,#3a1e12 5%,#3a1e12 5%,#3a1e12 5%,#573808 5%,#3a1e12 6%)

The roof is ready and should be placed on the top of the house turned at a 45 degree angle using transform: rotate(45deg) and cut-up in half using a container’s overflow: hidden.

        .house .roof {
            width: 340px;
            height: 170px;
            right: -20px;
            position: absolute;
            overflow: hidden;
        }

        .house .roof .roof-wall {
            position: absolute;
            width: 280px;
            height: 280px;
            background-color: #573808;
            -webkit-transform: rotate(45deg);
            left: 25px;
            top:60px;
            border: 5px solid #3a1e12;
            box-shadow: 0 0 30px black inset;
            background: repeating-linear-gradient(45deg, #573808 0%,#573808 5%,#3a1e12 5%,#3a1e12 5%,#3a1e12 5%,#573808 5%,#3a1e12 6%);
        }

almost ready house css layout animation

Then, a chimney is drawn with the help of a gradient.

        .house .chimney {
            position: absolute;
            height: 80px;
            width: 30px;
            top: 58px;
            left: 20px;
            background: linear-gradient(right, rgba(42,41,45,1) 0%,rgba(80,84,91,1) 36%,rgba(22,27,33,1) 100%);
        }

The chimney needs some surface roughness that can be created by overlapping of repeating brown gradients that turn into transparency.

        <div class="wall">
            <div class="crack"></div>
            <div class="crack"></div>
        </div>
        .house .wall .crack {
            position: absolute;
            width: 100%;
            height: 100%;
            opacity: 0.5;
            background: repeating-linear-gradient(3deg, rgba(0,0,0,0) 0%, rgba(0,0,0,0) 2%, rgba(0,0,0,0) 2%,#3a1e12 2%,#3a1e12 2%,#573808 2%,#3a1e12 3%);
        }

        .house .wall .crack:nth-child(2) {
            opacity: 0.3;
            background: repeating-linear-gradient(-4deg, rgba(0,0,0,0) 0%, rgba(0,0,0,0) 2%, rgba(0,0,0,0) 2%,#3a1e12 2%,#3a1e12 2%,#573808 2%,#3a1e12 3%);
        }

At this stage, we have got a very nice picture.

nice picture css animation

Now, it is a time to animate our static picture using animations. First, we make smoke clouds coming out of the chimney. Let’s draw a cloud of smoke. It will be a semi-transparent ellipse with a light box-shadow around it and a radial gradient.

        <div class="smoke-area">
            <div class="smoke"></div>
        </div>
        .smoke-area .smoke {
            position: absolute;
            width: 30px;
            height: 30px;
            border-radius: 50%;
            box-shadow: 0 0 20px lightgray;
            background: radial-gradient(ellipse at center, rgba(206,220,231,1) 33%,rgba(89,106,114,0) 100%);
            top: 120px;
            left: 20px;
        }

nice roof

Using key frames, we describe a trajectory of motion and transformation of this cloud. It will gradually grow bigger and more transparent.

        @-webkit-keyframes smoke-move {
            0% {top: 120px; left: 20px}
            20% {top: 107px; left: 25px}
            30% {top: 95px; left: 35px; opacity: 0.9}
            40% {top: 80px; left: 40px; }
            50% {top: 65px; left: 50px; }
            60% {top: 50px; left: 62px; }
            70% {top: 35px; left: 75px; }
            80% {top: 25px; left: 90px; }
            90% {top: 15px; left: 117px; }
            100% {top: 7px; left: 127px; opacity: 0; width: 90px; height: 60px}
        }

Now, we appoint the above-described animation to the cloud by adding to the class .smoke a property:

-webkit-animation: smoke-move 2.3s linear infinite

css animation easy simple tutorial

Great! We have a working chimney, but since in a full-fledged form it should emit a lot of smoke clouds without any interruption, we should add several of them to the layout.

    <div class="smoke-area">
        <div class="smoke"></div>
        <div class="smoke"></div>
        <div class="smoke"></div>
        <div class="smoke"></div>
        <div class="smoke"></div>
        <div class="smoke"></div>
        <div class="smoke"></div>
        <div class="smoke"></div>
    </div>

There are several smoke clouds now, but they are of no use at this point, because all of them are moving at the same time and along the same trajectory, and this all looks like a single cloud. Describing a new animation for each cloud is too boring and time-consuming. Some randomness in the motions would be great here, for example, using Math.random() with javascript. But since the goal is to create the scene using ONLY CSS, we have to take a different approach here. We can just apply the animation smoke-move to each element, but at different time intervals:

        .smoke-area .smoke:nth-child(2) {
            -webkit-animation: smoke-move 2.5s linear infinite
        }

        .smoke-area .smoke:nth-child(3) {
            -webkit-animation: smoke-move 2.7s linear infinite
        }

        .smoke-area .smoke:nth-child(4) {
            -webkit-animation: smoke-move 2.2s linear infinite
        }

        .smoke-area .smoke:nth-child(5) {
            -webkit-animation: smoke-move 2.1s linear infinite
        }

        .smoke-area .smoke:nth-child(6) {
            -webkit-animation: smoke-move 2s linear infinite
        }

        .smoke-area .smoke:nth-child(7) {
            -webkit-animation: smoke-move 2.9s linear infinite
        }

Now, smoke clouds are moving along the same trajectory, but at different time intervals that creates an illusion of a random motion:

animation clouds css

In some period of time, the animation cycle is going to repeat itself, but it will be hardly noticed, if the number of cycles is big enough. To find the longest cycle of motion, you have to choose relatively prime numbers for the animation time.

Let’s add some extra touch to our animation by creating falling stars. As previously, we start with only one and name it .meteor in div.meteors.

        <div class="meteors">
            <div class="meteor"></div>
        </div>
    .meteors {
        position: absolute;
        width: 100%;
        height: 100%;
    }

The description in CSS will start from the tail of the meteor. It will take the form of a white line that gradually becomes transparent.

    .meteor {
        position: absolute;
        top: 50px;
        left: 280px;
        width: 300px;
        height: 1px;
        -webkit-transform: rotate(-45deg);
        background-image: -webkit-linear-gradient(left, white, rgba(255,255,255,0));
    }

meteor animation css

Let’s draw a star at the end of the tail:

        .meteor:before {
            content: ' ';
            position: absolute;
            width: 4px;
            height: 5px;
            background-color: white;
            border-radius: 50%;
            box-shadow: 0 0 14px 4px white;
            margin-top: -2px;
        }

glowing star meteor css animation

In the description we are going to move it by changing spaces in-between and thus creating a flight effect rotated at 45 degrees. The meteor will fall and gradually disappear.

    @-webkit-keyframes meteor {
        0% {margin-top: -300px; margin-right: -300px; opacity: 1}
        8% {opacity: 0}
        10% {margin-top: 300px; margin-left: -600px; opacity: 0}
        100% {opacity: 0}
    }

So, let’s launch our meteor:

.meteor {top: 100px;left: 480px;-webkit-animation: meteor 10s linear infinite;}

animation meteor great tutorial russian programmers
We need more of them!

       <div class="meteors">
            <div class="meteor"></div>
            <div class="meteor"></div>
            <div class="meteor"></div>
        </div>
    .meteor:nth-child(1) {top: 100px;left: 480px;-webkit-animation: meteor 10s linear infinite;}
    .meteor:nth-child(2) {top: 200px;left: 280px;-webkit-animation: meteor 10s linear infinite;}
    .meteor:nth-child(3) {top: 250px;left: 790px;-webkit-animation: meteor 9s linear infinite;}

Here we go – the scene has been finally created!

ready animation css source code russian winter hous habra blog

Original in Russian