ArtsAutosBooksBusinessEducationEntertainmentFamilyFashionFoodGamesGenderHealthHolidaysHomeHubPagesPersonal FinancePetsPoliticsReligionSportsTechnologyTravel
  • »
  • Technology»
  • Internet & the Web

CSS3 Animations - Dotted Progress Bar

Updated on November 5, 2013
Source
Individual frames of the dotted progress bar made with CSS3.
Individual frames of the dotted progress bar made with CSS3. | Source

The Plan

The image (right side) is of the individual frames of the CSS3 animated progress bar. No, we are not using an image sprite to create the actual progress bar. I took a screen recording of the CSS in action and then exported the frames and put them together in Adobe Photoshop in order to give you an idea of what we're trying to accomplish.

I'll start by going over the different properties that we'll use and how to make them work in as many browsers as we can. Then, we'll jump into creating the elements step by step working toward our desired end result.

First of all, why would you want to use CSS to create your animation? Well, depending on the situation, there are some benefits:

  • It's one less HTTP request to the server for an image.
  • It takes a little less space than an image.
  • There's no worry about trying to preload the image before displaying it.
  • If you don't have a good application for creating images, this is a good alternative.

Besides that, it's just cool and think about what your friends will say! =o)


CSS3 Attributes Used

The attributes used to create the circle animation are:

  • border-radius
    • Border radius is used to round the corners of a box, set properly, you can make a circle out of a box, which is what we'll do to make our dots on the progress bar.
  • @keyframes
    • Use the key frames attribute to setup your animation and what should be happening at each point in the animation based on the percentage of completion.
  • animation
    • The animation property allows you to specify each of the following attributes in a single like similar to using border instead of border-top, border-bottom, etc.
  • animation-name
    • The name of the animation specified in the key frames attribute.
  • animation-duration
    • The length of the animation in seconds (s) or milliseconds (ms), whole numbers and decimal values can be used.
  • animation-timing-function
    • This basically defines your easing method for your animation. You can specify linear, ease, ease-in, ease-out, ease-in-out, cubic-bezier(0,0,0,0). I found this handy little site that can help you to determine a cubic-bezier if you want to go that route. Check out http://cubic-bezier.com/ just imagine the line as the speed of your animation.
  • animation-delay
    • Tells the animation how long to wait before starting. This time is defined in seconds (s) or milliseconds (ms).
  • animation-iteration-count
    • The number of times that animation should run before stopping. This can be a number or the term infinite which means it will never end.
  • animation-direction
    • Determines how the animation should play each time. The default is normal which means at the end, if it should loop, it will just start over. You can also use alternate which means the animation will alternate between revers and forward.
  • animation-play-state
    • You can specify paused or running, if you use paused, you will need to activate the animation with either CSS, like with the :hover or using JavaScript.

Browser Compatibility (Vendor Prefixes)

With CSS3 still being relatively new, not all browsers have full support for some of the features, while users in older browsers.

Usually when browser developers start to add new CSS attribute support, they require a vendor prefix. They do this as a method for testing the attribute and debugging support for that attribute. Once there is full support, the prefix is no longer required, but older browsers will still need that prefix so it is always a good practice to include prefixes when using CSS.

Here's a list of the vendor prefixes that I have found online, there may be more, or less now. The ones I use are in bold:

  • -ms- Microsoft
  • mso- Microsoft Office
  • -moz- Mozilla Foundation (Gecko-based browsers)
  • -o-, -xv- Opera Software
  • -atsc- Advanced Television Standards Committee
  • -wap- The WAP Forum
  • -webkit- Safari, Chrome (and other WebKit-based browsers)
  • -khtml- Konqueror browser
  • -apple- Webkit supports properties using the -apple- prefixes as well
  • prince- YesLogic
  • -ah- Antenna House
  • -hp- Hewlett Packard
  • -ro- Real Objects
  • -rim- Research In Motion
  • -tc- Tall Components

When it comes to deciding what browsers you should be concerned about designing for, nothing beats some good old traffic analytical data. I recommend Piwik it's free and you can host it on any hosting that support PHP.

If you don't have access to analytics for the site in question, the next best thing is to check out http://www.caniuse.com/ they have an extensive list of browser support and prefixes that are needed.

Now for the Fun Stuff!

Let's get started by first creating our elements to make up the progress bar. I've decided to just use a container with a unordered list that contains 10 items. The code for this is below.

<div id="Container">
    <ul>
        <li></li>
        <li></li>
        <li></li>
        <li></li>
        <li></li>
        <li></li>
        <li></li>
        <li></li>
        <li></li>
        <li></li>
    </ul>
</div>

Now we need to setup the basic styles for our progress bar.

  1. Setup the width and height of our container.
  2. Remove the list styling.
  3. Make the list items float to the left.
  4. Set list items width and height.
  5. Give them a base background color.
  6. Make them round by giving them a border radius of 5px on all sides.
  7. Finally, we'll specify the animation properties. Since each item is going to be animated, there is no reason to specify this separately.
    • The animation name is "circ" which will will specify later.
    • We'll have this animation go for 1 second
    • We won't use any kind of easing so linear will do.
    • This animation needs to play continuously so we'll set count to infinite.
    • We'll leave direction set to normal.
    • And we want this animation to start immediately.

Note: You could make a vertical scroll bar by removing the margin and not putting in the float left.

Note: Try removing the border radius on all items to have a square bar, or only add it to the left and right outside edges for a different effect.

Note: If you're using this as a progress bar, like it's intended, then you'll want to pause the animation and only run it when the progress bar is visible.

#Container{
    width: 200px;
    height: 10px;
}


ul{
    list-style-type: none;
}

ul li{
    float: left;
    width: 10px;
    height: 10px;
    background-color: #ffffff;
    border-radius: 5px;

    /* the name will be specifed in @keyframes */
    animation-name: circ;

    /* 1 second long */
    animation-duration: 1s;

    /* no easing */
    animation-timing-function: linear;

    /* never ending loop */
    animation-iteration-count: infinite;

    /* no alternating */ 
    animation-direction: normal;

    /* start automatically */
    animation-play-state: running; 

    /* browser support */
    -moz-animation-name: circ;
    -moz-animation-duration: 1s;
    -moz-animation-timing-function: linear;
    -moz-animation-iteration-count: infinite;
    -moz-animation-direction: normal;
    -moz-animation-play-state: running;

    -webkit-animation-name: circ;
    -webkit-animation-duration: 1s;
    -webkit-animation-timing-function: linear;
    -webkit-animation-iteration-count: infinite;
    -webkit-animation-direction: normal;
    -webkit-animation-play-state: running;
}

Now, in order to avoid just getting a bunch of blinking dots, we need to offset the animation. We do this by specifying a delay for each item.

I'm using the :nth-child() selector, which you'll want to make sure it is supported for the browsers you're planning on designing for.

li:nth-child(1){
    animation-delay: 0.1s;
    -moz-animation-delay: 0.1s;
    -webkit-animation-delay: 0.1s;
}
li:nth-child(2){
    animation-delay: 0.2s;
    -moz-animation-delay: 0.2s;
    -webkit-animation-delay: 0.2s;
}
li:nth-child(3){
    animation-delay: 0.3s;
    -moz-animation-delay: 0.3s;
    -webkit-animation-delay: 0.3s;
}
li:nth-child(4){
    animation-delay: 0.4s;
    -moz-animation-delay: 0.4s;
    -webkit-animation-delay: 0.4s;
}
li:nth-child(5){
    animation-delay: 0.5s;
    -moz-animation-delay: 0.5s;
    -webkit-animation-delay: 0.5s;
}
li:nth-child(6){
    animation-delay: 0.6s;
    -moz-animation-delay: 0.6s;
    -webkit-animation-delay: 0.6s;
}
li:nth-child(7){
    animation-delay: 0.7s;
    -moz-animation-delay: 0.7s;
    -webkit-animation-delay: 0.7s;
}
li:nth-child(8){
    animation-delay: 0.8s;
    -moz-animation-delay: 0.8s;
    -webkit-animation-delay: 0.8s;
}
li:nth-child(9){
    animation-delay: 0.9s;
    -moz-animation-delay: 0.9s;
    -webkit-animation-delay: 0.9s;
}
li:nth-child(10){
    animation-delay: 1s;
    -moz-animation-delay: 1s;
    -webkit-animation-delay: 1s;
}

Finally, it's time to build the animation! This part is actually quite easy.

  1. 0% = Set the animation to start with a background of white (#ffffff)
  2. 50% = Halfway through the animation the background should be blue (#0097ea)
  3. 100% = By the end of the animation, the background color should be white again.

@keyframes circ{
    0% {background: #ffffff;}
    50% {background: #0097ea;}
    100% {background: #ffffff;}
}
@-moz-keyframes circ{
    0% {background: #ffffff;}
    50% {background: #0097ea;}
    100% {background: #ffffff;}
}
@-webkit-keyframes circ{
    0% {background: #ffffff;}
    50% {background: #0097ea;}
    100% {background: #ffffff;}
}

Enjoy!

Well That was fun! I've put the complete code below, copy & paste, and play around!

Complete Code

<!DOCTYPE html>
<html>
    <head>
        <title></title>
        <meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
        <style type="text/css">

            #Container{
                width: 200px;
                height: 10px;
            }
            ul{
                list-style-type: none;
            }
            ul li{
                float: left;
                width: 10px;
                height: 10px;
                background-color: #ffffff;
                border-radius: 5px;
                animation-name: circ;
                animation-duration: 1s;
                animation-timing-function: linear;
                animation-iteration-count: infinite;
                animation-direction: normal;
                animation-play-state: running;

                -moz-animation-name: circ;
                -moz-animation-duration: 1s;
                -moz-animation-timing-function: linear;
                -moz-animation-iteration-count: infinite;
                -moz-animation-direction: normal;
                -moz-animation-play-state: running;

                -webkit-animation-name: circ;
                -webkit-animation-duration: 1s;
                -webkit-animation-timing-function: linear;
                -webkit-animation-iteration-count: infinite;
                -webkit-animation-direction: normal;
                -webkit-animation-play-state: running;
            }
            li:nth-child(1){
                animation-delay: 0.1s;
                -moz-animation-delay: 0.1s;
                -webkit-animation-delay: 0.1s;
            }
            li:nth-child(2){
                animation-delay: 0.2s;
                -moz-animation-delay: 0.2s;
                -webkit-animation-delay: 0.2s;
            }
            li:nth-child(3){
                animation-delay: 0.3s;
                -moz-animation-delay: 0.3s;
                -webkit-animation-delay: 0.3s;
            }
            li:nth-child(4){
                animation-delay: 0.4s;
                -moz-animation-delay: 0.4s;
                -webkit-animation-delay: 0.4s;
            }
            li:nth-child(5){
                animation-delay: 0.5s;
                -moz-animation-delay: 0.5s;
                -webkit-animation-delay: 0.5s;
            }
            li:nth-child(6){
                animation-delay: 0.6s;
                -moz-animation-delay: 0.6s;
                -webkit-animation-delay: 0.6s;
            }
            li:nth-child(7){
                animation-delay: 0.7s;
                -moz-animation-delay: 0.7s;
                -webkit-animation-delay: 0.7s;
            }
            li:nth-child(8){
                animation-delay: 0.8s;
                -moz-animation-delay: 0.8s;
                -webkit-animation-delay: 0.8s;
            }
            li:nth-child(9){
                animation-delay: 0.9s;
                -moz-animation-delay: 0.9s;
                -webkit-animation-delay: 0.9s;
            }
            li:nth-child(10){
                animation-delay: 1s;
                -moz-animation-delay: 1s;
                -webkit-animation-delay: 1s;
            }

            @keyframes circ{
                0% {background: #ffffff;}
                50% {background: #0097ea;}
                100% {background: #ffffff;}
            }
            @-moz-keyframes circ{
                0% {background: #ffffff;}
                50% {background: #0097ea;}
                100% {background: #ffffff;}
            }
            @-webkit-keyframes circ{
                0% {background: #ffffff;}
                50% {background: #0097ea;}
                100% {background: #ffffff;} 
            }
        </style>
    </head>
    <body>
        <div id="Container">
            <ul>
                <li></li>
                <li></li>
                <li></li>
                <li></li>
                <li></li>
                <li></li>
                <li></li>
                <li></li>
                <li></li>
                <li></li>
            </ul>
        </div>
    </body>
</html>

Share Your Creations

If you create a cool CSS3 animation, create the tutorial and give me a link and I'll add you to this page.

Comments

    0 of 8192 characters used
    Post Comment

    • g33kco profile image
      Author

      Mark Lewis 3 years ago from Riverton, WY

      Thank you for catching my mistakes! I'd love to see what you create at some time as well.

    • ssiddique profile image

      Shahid Siddique 3 years ago from Kansas

      Thank you Bro for your help appreciated.

    • g33kco profile image
      Author

      Mark Lewis 3 years ago from Riverton, WY

      Terribly sorry. In the process of creating this tutorial, I should have included the proper vendor prefixes in order to make sure that this would work on as many browsers as possible. I have made the corrections to the code above. Copy and past that and it should work fine, I tested it using the same methods you mentioned.

    • ssiddique profile image

      Shahid Siddique 3 years ago from Kansas

      I am sure my IE is not updated but my Chrome version is Version 30.0.1599.101 m which I guess is latest.

      I have copied your code and pasted it to new .HTML file on my local machine and ran just by double clicking. Do I have to access it through localhost or something?? thank you.

    • g33kco profile image
      Author

      Mark Lewis 3 years ago from Riverton, WY

      ssiddique:

      I've tested the code on Firefox, Google Chrome, Opera, Safari, and IE 10. Here's a break down of what browser version started supporting animtion:

      Firefox: 23+

      IE: 10+

      Chrome: 29+

      Safari: 5.1+

      Opera: 17+

      iOS Safari: 3.2+

      Opera Mini: none as of yet

      Android Browser: 2.1+

      Blackberry: 7.0+

      IE Mobile: 10+

      I also noticed that I forgot the webkit version of the animation tag. I have added that back in.

    • ssiddique profile image

      Shahid Siddique 3 years ago from Kansas

      Nicely done but I noticed that it only works for FireFox. Am I doing something wrong?