Making a Slick MobileApp Website with jQuery & CSS

Demo Download

As a web developer, you have to bring creativity and attention to detail to your work. It is often the little things that leave a lasting impression to a visitor. Be it a lovable character illustration, or unique slideshow, it is usually not the information you present that is memorable, but the way you present it.

Today we are making a complete jQuery & CSS website for a fictional mobile application. It is going to feature semantic markup and a progressively enhanced slideshow effect. It will allow the user to see four of the most popular smartphones running the mobile app.

Step 1 - XHTML

When building websites it is important that you lay your code in a semantic way. This would include using tags for what they were supposed to be used for. You should use headings for titles, paragraphs for text (instead of generic divs) and lists where applicable.

mobileapp.html

<div id="page">

    <h1 id="logoh1"><a href="/" id="logo">MobileApp - the most useful mobile app!</a></h1>

    <div id="phoneCarousel">
        <div class="previous arrow"></div>
        <div class="next arrow"></div>

        <div id="stage">
            <img id="iphone" class="default" src="img/phones/iphone.png" width="270" height="400" alt="iPhone" />
            <img id="nexus" src="img/phones/nexus_one.png" width="270" height="400" alt="Nexus One" />
            <img id="nokia" src="img/phones/nokia.png" width="270" height="400" alt="Nokia" />
            <img id="blackberry" src="img/phones/blackberry.png" width="270" height="400" alt="BlackBerry" />
        </div>
    </div>

    <img class="availableAppStore" src="img/available_on_the_appstore.png" width="230" height="80" alt="Available on the Appstore" />

    <div class="text">
        <h3><img src="img/thumb.png" alt="MobileApp" width="114" height="114" class="thumb" />A wonderful app</h3>
        <p>Lorem ipsum dolor sit amet.. </p>
    </div>

    <div class="text">
        <h3><img src="img/thumb.png" alt="MobileApp" width="114" height="114" class="thumb" />More awesome facts</h3>
        <p>Lorem ipsum dolor sit amet.. </p>
    </div>

</div>

This is all the markup that is used to display the website. The h1 heading holds a hyperlink which is styled as the logo (the logo image is set as the background of the hyperlink and a negative text indent is used to hide the text of the link).

After this we have the #phoneCarousel div and inside it are the arrows and the stage. The phone images inside the stage are rotated with jQuery as you will see in a moment.

Lastly we have the Available on the Appstore badge, and two blocks of text.

i1.jpg

Step 2 - CSS

CSS is responsible for converting our semantic markup into a true website. Take a closer look at the #stage styles in the second part of the code, as these are what make the animation possible.

styles.css - Part 1

body{
    font-size:14px;
    color:#515151;
    background:url('img/bg.png') repeat-x #f6f8f9;
    font-family:'Myriad Pro',Arial, Helvetica, sans-serif;
}

#logoh1{ margin:40px 0 0;}

#page{
    /* This the main container div */
    width:1000px;
    min-height:700px;
    margin:0 auto;
    background:url('img/bokeh.jpg') no-repeat 0 120px;
    position:relative;
    padding-top:1px;
}

#phoneCarousel{
    /*  This is the carousel section, it
        contains the stage and the arrows */
    height:390px;
    margin:90px auto 120px;
    position:relative;
    width:800px;
}

#phoneCarousel .arrow{
    /* The two arrows */
    width:44px;
    height:44px;
    background:url('img/arrows.png') no-repeat;
    position:absolute;
    top:50%;
    margin-top:-22px;
    left:0;
    cursor:pointer;
}

#phoneCarousel .next{
    /* Individual styles for the next icon */
    background-position:right top;
    left:auto;
    right:0;
}

/* Hover styles */

#phoneCarousel .arrow:hover{
    background-position:left bottom;
}

#phoneCarousel .next:hover{
    background-position:right bottom;
}

After defining the body styles we can move on to styling the #page div, which holds everything together. Its background image is offset 120px vertically, so it matches the background of the body, filling the full width of the page.

Next is the #phoneCarousel div. It has a relative positioning applied, so the stage (where all the animations take place) can be properly centered. The previous/next arrows are styled as well.

styles.css - Part 2

#logo{
    background:url('img/logo.png') no-repeat;
    height:40px;
    text-indent:-9999px;
    width:210px;
    display:block;
}

#stage{
    /* The stage contains the animated phone images */
    left:50%;
    margin-left:-350px;
    position:absolute;
    width:700px;
    height:100%;
}

#stage img{
    /* Hiding all the images by default */
    display:none;
}

#stage .default{
    /*  This class is applied only to the iphone img by default
        and it is the only one visible if JS is disabled */
    display:block;
    left:50%;
    margin-left:-135px;
    position:absolute;
}

#stage .animationReady{
    /* This class is assigned to the images on load */
    display:block;
    position:absolute;
    top:0;
    left:0;
}

.text{  margin-top:70px;width:700px;}

.text p,
.text h3{
    padding-bottom:15px;
    line-height:1.4;
    text-align:justify;
}

.text h3{   font-size:30px;}
.text p{    font-size:20px;}

.thumb{ float:left;margin-right:40px;}

.availableAppStore{float:right;}

In the second part of the stylesheet, we continue with the #stage styles. The phone pictures are hidden by default, so if JavaScript is disabled, the user is not left with a bunch of scattered images.

As you will see in the next step, the animation is achieved through changing the top and left CSS properties. For this to work, the images must be absolutely positioned. This is why the .animatonReady class is assigned on load with jQuery (if JS is disabled, this style would not be applied).

Lastly we style the text blocks, which explain details about our fictional MobileApp.

i2.png

Step 3 - jQuery

When you click on one of the arrows, an animation starts, which uses sine and cosine calculations to move and scale down the images, creating the illusion of a circular movement. It is not as complicated as it sounds, as you can see for yourself from the code below.

script.js

$(document).ready(function(){

    var deg=0;

    /* Storing all the images into a variable */

    var images  = $('#stage img').removeClass('default').addClass('animationReady');
    var dim     = { width:images.width(),height:images.height()};

    var cnt = images.length;

    /* Finding the centers of the animation container: */
    var centerX = $('#stage').width()/2;
    var centerY = $('#stage').height()/2 - dim.height/2;

    function rotate(step,total){
        // This function will loop through all the phone images, and rotate them
        // with "step" degrees (10 in this implementation) till total > 0

        /* Increment the degrees: */
        deg+=step;

        var eSin,eCos,newWidth,newHeight,q;

        /* Loop through all the images: */
        for(var i=0;i<cnt;i++){

            /* Calculate the sine and cosine for the i-th image */

            q = ((360/cnt)*i+deg)*Math.PI/180;
            eSin        = Math.sin(q);
            eCos        = Math.cos(q);

            /*
            /   With the sine value, we can calculate the vertical movement,
            /   and the cosine will give us the horizontal movement.
            */

            q = (0.6+eSin*0.4);
            newWidth    = q*dim.width;
            newHeight   = q*dim.height;

            /*
            /   We are using the calculated sine value (which is in the range
            /   of -1 to 1) to calculate the opacity and z-index. The
            /   frontmost image has a sine value of 1, while the backmost
            /   one has a sine value of -1.
            */

            // eq() extracts the image at the i-th position:

            images.eq(i).css({
                top         : centerY+15*eSin,
                left        : centerX+200*eCos,
                opacity     : 0.8+eSin*0.2,
                marginLeft  : -newWidth/2,
                zIndex      : Math.round(80+eSin*20)
            }).width(newWidth).height(newHeight);
        }

        total-=Math.abs(step);
        if(total<=0) return false;

        // Setting the function to be run again in 40 milliseconds (equals to 25 frames per second):
        setTimeout(function(){rotate(step,total)},40);

    }

    // Running the animation once at load time (and moving the iPhone into view):
    rotate(10,360/cnt);

    $('#phoneCarousel .previous').click(function(){
        // 360/cnt lets us distribute the phones evenly in a circle
        rotate(-10,360/cnt);
    });

    $('#phoneCarousel .next').click(function(){
        rotate(10,360/cnt);
    });
});

To start an animation you just need to call the rotate function with two arguments - a step, and a total rotation, both of which are numbers. Step can be negative, which would mean that the rotation is run in the opposite way. Each time the function is run, total is decremented with the absolute value of the step, and once it reaches zero the animation is stopped.

In a number of places in this code, you can see that I've used a specific calculation - 360/cnt. This is done to distribute the phones evenly (360 being the number of degrees in a circle). This way you can add or remove images and they will be properly animated.

i3.jpg

With this our Slick MobleApp Website is complete!

Wrapping it up

Today we made a complete jQuery & CSS website for a fictional mobile application. You are free to modify the code and use it any way you see fit. If you liked the tutorial be sure to subscribe to our RSS feed, follow us on twitter, or leave a comment in the section below.

Bootstrap Studio

The revolutionary web design tool for creating responsive websites and apps.

Learn more

Related Articles

vipin sahu

Awesome as always . Gr8 work

wow !

Gadget Guy

Wonderful tutorial, as always.

Really good! Well done.

Awesome tutorial !! many thank for tutorial

As always never loose ideas for new toys for us to play...

Thanks for sharing this great tutorial. Totally useful.

Ionut Popa

Hi,
Where did you get the formulas for the transformation?

WOW...smooth move on the rolling...aw aw aw
its cutez my friend...hihihi :D

Abhijeet

Very Nice One. Thanx for the Tutorial

Maximilien

Nice! Thanks for sharing ;)

superb, thanks man

Nice tutorial. Thank so much!

the buttom mobile picture is black in IE8 but Thank so much.

Martin Angelov

Thank you for the great comments!

@deawx, It appears that IE does not like to animate transparent pngs with an opacity animation. You can fix this by commenting line 55 of script.js

Jeffikus

What license is this released under?

Paul Anthony Webb

That is one [ very well ] put together site! Nice work.

nice!!

Nicely made!

You might wanna add a blur() function to the click trigger so you avoid text-selection in firefox (when you press a button twice) ;-)

Another super tutorial, WOW!

Sebastian

Hello.

I have a question:
Is there a possibility to readout the current item (which is in the front of the animation)?
For example, when you click on the next button, the alternative text of the image where displayed in a div-field under the animation.

Thanks in advance

Sebastian

Martin

You truly are a genius. One silly question - how does the arrow.png work ? Can I use any arrows of 86/60 and should it be two arrows - right and left ?

Shamim Arafat Rocky

I used this plugin for five images. worked fantastically.
but i got a small problem
i added 5 images instead of 4 images.
for which.. i cant get same view for all images
here is the site

www.rangsmobile.com.bd

please help

Can anyone solve the problem of 5 or more images?