Beginner-Friendly Animated iPhone 6 UI Tutorial

Muna Mohamed - Jan 20 '18 - - Dev Community

Hey guys! I’m back with another beginner friendly tutorial where we’ll be creating an animated iPhone 6 user interface(UI) using HTML & SCSS.

The Sketch

So first we need to figure out the components that make up an iPhone 6. We have the:

  • iPhone outer shell
  • iPhone inner shell 
  • the top section(which contains the camera, speaker and light-sensor)
  • the middle section (which contains the screen)
  • the bottom section (which contains the home button) 

Once we’ve figured the logistics of what an iPhone 6 consists of, we can then go on to do a sketch of what our iPhone 6 will look like. This will act as our blueprint, helping us with figuring out what goes where in our HTML. 

HTML

<div class="container">
  <div class="container-inner">

    <!-- Above screen -->
    <div class="above-screen">
      <div class="above-screen-top">
          <div class="front-camera"></div>
      </div>
      <div class="above-screen-bottom">
          <div class="light-sensor"></div>
          <div class="speaker"></div>
      </div>
    </div>

    <!--Screen -->
    <div class="screen">
        <img id="apple-logo" src="https://s1.gifyu.com/images/image-jpg.448007.jpg" alt="apple logo">
        <img id="home-screen" src="https://s1.gifyu.com/images/pFIdZ.png" alt="home screen">
    </div>

    <!-- Home-button -->
    <div class="home-button"></div>
  </div>
</div>
Enter fullscreen mode Exit fullscreen mode

We start off with a container div which will be holding all of the components that make up an iPhone 6. Next is the container-inner div which will help us center the components within the container div.

Then we have split up the container-inner div into three sections that are on top of each other; above-screen, screen and home-button. 

The above-screen div will be at the top of the container-inner div and will contain the front-camera, the speaker and what I believe to be a light sensor (forgive me y’all, I’m strictly an android gal so no idea what it is). I’ve split the above-screen div into two div’s, top and bottom, which will respectively hold the front-camera, speaker and light-sensor.

The screen div will be in the middle and will take up the majority of the space, understandably. It contains two images; an image of the apple logo with a black background and a home screen background image. The screen div is where we’ll be applying the animation, using the two images.

Then we have the last section of the iPhone, which is the home-button.

SCSS 

On to the styling! 

Mixins

//Prefix mixins
@mixin flexbox {
  display: -webkit-box; 
  display: -moz-box;
  display: -ms-flexbox;
  display: -webkit-flex;
  display: flex;
}
@mixin flex-direction($value) {
 -webkit-box-orient: $value;
 -webkit-box-direction: $value;
 -ms-flex-direction: $value;
 flex-direction: $value;
}
@mixin align-items($value) {
 -webkit-box-align: $value;
 -ms-flex-align: $value;
  align-items: $value;
}
@mixin justify-content($value) {
 -webkit-box-pack: $value;
 -ms-flex-pack: $value;
 justify-content: $value;
}
Enter fullscreen mode Exit fullscreen mode

We’ll start with one of the many wonders of SCSS; mixins! For beginners who may not know what mixins are, mixins are blocks of reusable code which you write once, usually at the top of your stylesheet, which then gives you the ability to reuse that code throughout your stylesheet using @include and the name of the mixin. 

Because we’re using Flexbox in this tutorial (nothing too difficult, I promise!), we’ll start off our stylesheet with our mixins for the flexbox browser prefixes. Rather than typing the prefixes over and over again, we’ll create a mixin for each of the flexbox properties we’ll be using. This way we save on having to rewrite the prefixes and also keep our code to the minimum. 

As you can see, the vendor prefixes for flexbox properties are a little different from the standard vendor prefixes you add to CSS properties. 

I used Prepos(A compiler that will compile your SCSS code into CSS), which has a setting called Autoprefixer, which adds prefixes to your CSS as your SCSS code gets compiled. These are the vendor prefixes that Prepos provided for my flexbox properties. It's a handy compiler to use with Sublime (the text editor I use) and is free!

Container

.container {
  margin: 20px auto;
  width: 230px;
  height: 450px;
  border: 4px solid #C5AE87;
  border-radius: 25px;
  position: relative;
  z-index: -1;
}
Enter fullscreen mode Exit fullscreen mode

We’ll start with styling the container div.

I will explain the reasoning behind each of the properties that I have applied to the container div. 

margin: 20px auto → This applies a margin top and bottom of 20px along with margin right and margin left that is auto, which will center the container on the page horizontally.

width: 230px and height: 450px → The container will have a width of 230px and a height of 450px. These measurements are representative of an estimate of the dimensions of an iPhone 6. 

border: 4px solid #C5AE87 → This applies a border to the container div that is 4px and a gold-ish colour. This is representative of what a gold iPhone 6 looks like. 

border-radius: 25px → This gives the corners of the container div slightly rounded corners since iPhone 6’s have rounded corners. 

position: relative and z-index: -1 → This positions the container relative to the body and gives the container div a z-index of 1 because the container div will act as the base for the iPhone 6 components that we’ll be adding later on so that we can position them on top of the container div. 

Container-inner

.container {
  margin: 20px auto;
  width: 230px;
  height: 450px;
  border: 4px solid #C5AE87;
  border-radius: 25px;
  //background-color: #C5AE87;
  position: relative;
  z-index: -1;
  .container-inner {
    width: 100%;
    height: 99.8%;
    margin: 0.25% auto;
    border-radius: 20px;
    background-color: white;
    @include flexbox;
    @include flex-direction(column);
    @include align-center(center);
    position: relative;
    z-index: 1;
    overflow: hidden;
    }
 }
Enter fullscreen mode Exit fullscreen mode

Following the sketch above, the next element we need to style is the container-inner div. This is a container within the the container div which will hold the main elements of the screen. By having an inner container, it allows us to move our elements around easier without having to resort to adding padding and margins to each of the blocks later.

Since we are using SCSS, we are able to nest the container-inner div within the container div. Let’s see what properties we add to the container-inner div. 

width: 100% and height: 99.8% → The container-inner div will have a full width which will span across the container div and a height of 99.8%. The reason for this is that because we applied a border-radius to the container div earlier, we cannot have the container-inner div span the full height of the container div without the two overlapping. Therefore, we’ll be adding a margin top and bottom to avoid this. 

margin: 0.25% auto → This applies a margin top and bottom of 0.25% to the container-inner div and margin right and margin left of auto which will center the container-inner div horizontally in the container div.

border-radius: 20px → This is to round the edges of the container-inner div slightly. 

background-color: white → This turns the background color of the container-inner div to white.

@include flexbox → This applies the mixin called flexbox which we typed earlier. This mixin defines the container-inner div as a flex container and also applies all of the vendor prefixes needed for this to work in a number of browsers. 

@include flex-direction(column) → This includes the flex-direction mixin that we typed earlier. This will add the flex-direction CSS property and value as well as the vendor prefixes which are needed in order for this CSS property to work in different browsers. This defines the direction in which the flex items (i.e. the child elements of the container inner div) will be placed in the flex-container (i.e. the container-inner div). We have defined the direction in which the flex items will be placed as column; this aligns the child items of container-inner div (i.e. above-screen, screen and home-button) in a column format, one on top of the other. 

@include justify-content(center) → This adds the justify-content mixin we typed earlier. This includes the flexbox property justify-content and its vendor prefixes which allow this property to work in a number of browsers. By adding this property, this will center all the child items in the container-inner div horizontally. 

@include align-items(center) → This adds the align-items mixin we typed earlier. This includes the flexbox property align-items and its vendor prefixes which allow this property to work in a number of browsers. By adding this property, this will center all of the child items in the container-inner div vertically. 

position: relative and z-index: 1 → This positions container-inner relative to the container and gives the container-inner div a z-index of 1. By doing this, it places the container-inner div on top of the container div.

overflow: hidden → This hides any overflow that the container-inner div may have. 

Here's what we have so far.

**Please note
I know what you're thinking; why can't I see the container-inner div? Don't worry, there is nothing to be worried about here, this is to be expected. The reason why we are unable to see our container inner is due to the images that we inputted in our HTML code earlier, Due to the size of our images, they have covered our entire container-inner div so that all we can see is the images (the Apple logo image to be exact). The reason it looks like a black background has been applied in the container-inner div is due to our Apple logo image (which has a black background and is a pretty big image). We'll sort this out later on in the tutorial!

Above-screen, screen and home-button

.container {
  margin: 20px auto;
  width: 230px;
  height: 450px;
  border: 4px solid #C5AE87;
  border-radius: 25px;
  position: relative;
  z-index: -1;
  .container-inner {
    width: 100%;
    height: 99.8%;
    margin: 0.25% auto;
    border-radius: 20px;
    background-color: white;
    @include flexbox;
    @include flex-direction(column);
    @include justify-content(center);
    @include align-items(center);
    position: relative;
    z-index: 1;
    overflow: hidden;
    .above-screen {
      width: 50%;
      height: 9%;
      margin: 5px auto;
      @include flexbox;
      @include flex-direction(column);
      @include justify-content(center);
      @include align-items(center);
      position: relative;
      z-index: 2;
      }
    .screen {
      width: 90%;
      height: 77%;
      border: 1px solid white;
      background-color: black;
      position: relative;
      z-index: 2;
      overflow: hidden;
      }
     .home-button {
      width: 35px;
      height: 35px;
      margin-top: 5px;
      border: 3px solid #C5AE87;
      border-radius: 100%;
      position: relative;
      z-index: 2;
      cursor: pointer;
       }
    }
 }
Enter fullscreen mode Exit fullscreen mode

Next up are the three main child elements of the container-inner div; above-screen, screen and home button. 

Above-screen

We’ll start with the above-screen div. This will be placed at the top of the container-inner div and will contain the front-camera, speaker and light-sensor.

 

.above-screen {
      width: 50%;
      height: 9%;
      margin: 5px auto;
      @include flexbox;
      @include flex-direction(column);
      @include justify-content(center);
      @include align-items(center);
      position: relative;
      z-index: 2;
      }
Enter fullscreen mode Exit fullscreen mode

width: 50% and height: 9% → The above-screen div will have a width of 50% (50% of the width of the container-inner div, that is) and a height of 9%(9% of the height of the container-inner div). 

margin: 5px auto → Then we’ll add a margin top and margin bottom of 5px and a margin left and margin right of auto which will center the above-screen div horizontally within the container-inner div. 

@include flexbox → This defines the above-screen div as a flex container and adds the browser prefixes needed for the flex property to work in different browsers. 

@include flex-direction(column) → This defines the direction in which the flex-items (i.e. the child elements of the above-screen div) will be placed in the flex-container (i.e. the above-screen div). We defined the value of flex-direction as column; this lays out the child elements of above-screen div on top of each other so they stack vertically. Remember, the child elements of the above-screen div are the camera, light-sensor and speaker.

@include justify-content(center) → This defines how the flex-items (i.e the child elements of the above-screen div) align horizontally. By selecting the value of justify content to be center, this centers the child elements horizontally. So, when we add the child elements of the above-screen div (i.e the camera, light-sensor and speaker), they will be centered horizontally in the above-screen div.

@include align-items(center) → This defines how the flex-items (i.e. the child elements of the above-screen div) align vertically. By selecting the value of align-items to be center, this enters the child elements vertically. So, when we add the child elements of the above-screen div (i.e. the camera, light-sensor and speaker), they will be centered vertically in the above-screen div.

position: relative and z-index: 2→ This positions the above-screen div relative of the container-inner div. The z-index is set to 2 which then allows the above-screen-div to be stacked on top of the container-inner div (which had a z-index of 1). 

Screen

Next we have the screen, which will be in the middle of the container-inner div and will take up the majority of the container-inner div.

 

.screen {
      width: 90%;
      height: 77%;
      border: 1px solid white;
      background-color: black;
      position: relative;
      z-index: 2;
      overflow: hidden;
      }
Enter fullscreen mode Exit fullscreen mode

width: 90% & height: 77% → The screen div will take up 90% of the width of the container-inner div and will be 77% (a little over 3/4’s) of the height of the container-inner div.

border: 1px solid white → We’ll give the screen div a white border that’s 1 pixel. 

background-color: black → We will give the screen div a background-color of black; 

position: relative & z-index: 2 → This positions the screen div relative of the container-inner div. The z-index is set to 2 which then allows the screen-div to be stacked on top of the container-inner div (which had a z-index of 1).

overflow: hidden → We will apply an overflow of hidden. This will make sure to hide any overflow that may occur if, for example, the images go outside of the boundary the screen div. 

Home-button

Lastly, we have the last main section of the iPhone 6; the home button.

 

.home-button {
      width: 35px;
      height: 35px;
      margin-top: 5px;
      border: 3px solid #C5AE87;
      border-radius: 100%;
      position: relative;
      z-index: 2;
      cursor: pointer;
       }
Enter fullscreen mode Exit fullscreen mode

width: 35px & height 35px → Since our home button will be circular, in order to be perfectly round the height and width must be equal therefore, we’ll give our home button a width and height of 35px. 

margin-top: 5px → This will add a margin-top of 5px to the home button so that we create some space between the screen div (which is above the home button) and the home button. 

border: 3px solid #C5AE87 → To match the golden outer shell of our iPhone 6, we will add a border that is 3 pixels which is the same golden color as the outer shell of our iPhone. 

border-radius: 100% → A border-radius of 100% will make our home button perfectly circular. 

position: relative & z-index: 2 → This positions the home button div relative of the container-inner div. The z-index is set to 2 which then allows the home button div to be stacked on top of the container-inner div (which had a z-index of 1).

cursor: pointer → This will make it so that whenever we hover over the home button div, the cursor will change to a pointer cursor.

This is what our iPhone looks like so far:

Above-screen - camera, light-sensor and speaker

Now it's time to add our camera, light sensor and speaker to the above-screen div.

.above-screen {
      width: 50%;
      height: 9%;
      margin: 5px auto;
      @include flexbox;
      @include flex-direction(column);
      @include justify-content(center);
      @include align-items(center);
      position: relative;
      z-index: 2;
      .above-screen-top { 
        width: 100%;
        height: 50%; 
        @include flexbox;
        @include flex-direction(column);
        @include justify-content(center);
        @include align-items(center);       
          .light-sensor {
            width: 5px;
            height: 5px;
            background-color: black;
            border-radius: 100%;
      }
    }
      .above-screen-bottom { 
        width: 100%;
        height: 50%;    
        @include flexbox;
        @include flex-direction(row);
        @include justify-content(center);
        @include align-items(center);
          .front-camera {
            width: 7px;
            height: 7px;
            background-color: black;
            border-radius: 100%;
            position: relative;
            right: 10px;
      }
          .speaker {
            width: 37px;
            height: 5px;
            background-color: black;
            border-radius: 30px;
            margin-right: 5px;
      }
    }
  }
Enter fullscreen mode Exit fullscreen mode

Let's move on to the child elements of the above-screen div; the light-sensor, camera and speaker. The light sensor comes first at the top of an iPhone 6, then below are the camera and the speaker. In order to illustrate this, I broke the above-screen div into two sections; top and bottom. At the top will be the light-sensor and on the bottom will be the camera and speaker.

We'll start with the top section of the above-screen div.

Above-screen-top

.above-screen-top { 
        width: 100%;
        height: 50%; 
        @include flexbox;
        @include flex-direction(column);
        @include justify-content(center);
        @include align-items(center);       
          .light-sensor {
            width: 5px;
            height: 5px;
            background-color: black;
            border-radius: 100%;
      }
    }
Enter fullscreen mode Exit fullscreen mode

Here are the CSS properties that I applied to the above-screen-top div.

width: 100% & height: 50% → The top section of the above-screen div will span the full width of the above-screen div and will take up 50% of the height of above-screen div.

@include flexbox → This defines the above-screen-top div as a flex container and adds the browser prefixes needed for the flex property to work in different browsers. 

@include flex-direction(column) → This defines the direction in which the flex-items (i.e. the child elements of the above-screen-top div) will be placed in the flex-container (i.e. the above-screen-top div). We defined the value of flex-direction as column; this lays out the child elements of above-screen-top div on top of each other so they stack vertically. Here, the child element of the above-screen-top div is the light-sensor.

@include justify-content(center) → This defines how the flex-items (i.e the child elements of the above-screen-top div) align horizontally. By selecting the value of justify content to be center, this centers the child elements horizontally. Here, the child element of above-screen-top div which is the light-sensor, will be centered horizontally.

@include align-items(center) → This defines how the flex-items (i.e. the child elements of the above-screen-top div) align vertically. By selecting the value of align-items to be center, this enters the child elements vertically. Here the child element of above-screen-top div, which is the light-sensor, will be centered vertically.

Next, we define what our light-sensor will look like.

width: 5px & height: 5px → We'll give our light-sensor a width and height of 5px.

background-color: black → Our light-sensor will have a background-color of black.

border-radius: 100% → We'll give our light-sensor a border-radius of 100% which will change the shape of the light-sensor so that it is circular. Since the width and height are the same, the shape will be perfectly circular.

Above-screen-bottom

Now on to the bottom section of the above-screen div.

.above-screen-bottom { 
        width: 100%;
        height: 50%;    
        @include flexbox;
        @include flex-direction(row);
        @include justify-content(center);
        @include align-items(center);
      .front-camera {
        width: 7px;
        height: 7px;
        background-color: black;
        border-radius: 100%;
        position: relative;
        right: 10px;
      }
      .speaker {
        width: 37px;
        height: 5px;
        background-color: black;
        border-radius: 30px;
        margin-right: 5px;
      }
    }
Enter fullscreen mode Exit fullscreen mode

As you can see, the above-screen-bottom div has exactly the same properties as above-screen-top so I will explain the CSS properties that I have applied to the front-camera and speaker. We'll start with the front-camera.

      .front-camera {
        width: 7px;
        height: 7px;
        background-color: black;
        border-radius: 100%;
        position: relative;
        right: 10px;
      }
Enter fullscreen mode Exit fullscreen mode

width: 7px and height: 7px → The front-camera will have a width and height of 7 pixels.

background-color: black → It will have a background color of black.

border-radius: 100% → We'll give the front-camera a border-radius of 100% to make the shape circular.

position: relative → This position the front-camera relative to it's normal position.

right: 10px → This shifts the position of the front-camera 10 pixels to the right.

Now onto the speaker.

      .speaker {
        width: 37px;
        height: 5px;
        background-color: black;
        border-radius: 30px;
        margin-right: 5px;
      }
Enter fullscreen mode Exit fullscreen mode

width: 37px & height: 5px → To emulate the shape of the speaker on an iPhone 6, we will give the speaker a width of 37 pixels and a height of 5px.

background-color: black → This gives the speaker a background-color of black.

border-radius: 30px → This will give the corners of the speaker slightly rounded edges.

margin-right: 5px → This creates a margin on the right side of the speaker of 5 pixels

Screen - Apple logo and the home-screen images

   .screen {
      width: 90%;
      height: 77%;
      border: 1px solid white;
      background-color: black;
      position: relative;
      z-index: 2;
      overflow: hidden;
      img {
        position: absolute;
        left: 0;
        top: 0;
      }
      #apple-logo {
        width: 130%;
        height: auto;
        left: -30px;
        z-index: 5;
        animation: fade 15s ease-in-out 5 alternate;
      }
      #home-screen {
        width: 100%;
        height: auto;
        z-index: 4;
      }
    }
Enter fullscreen mode Exit fullscreen mode

Let's work on the images that will appear in our animation.

The easiest way of translating what happens when an iPhone 6 phone starts up into an animation would be to have the image of the Apple logo appear for a few seconds and then fade away to reveal the home-screen image below. This would require the two images to be on top of one another.

We can achieve this by making the positions of both images absolute so that they are taking out of the natural flow of the document and positioned relative to the closest positioned ancestor (the closest positioned ancestor in this case being the screen div). We then apply left: 0 and top: 0 to both images so they are positioned on the top-left hand corner of the screen div.

Now that both images are aligned at the top-left hand corner of the screen div, all that's left to do is to establish their stacking order. Since the Apple logo image will fade away to reveal the home-screen image in our animation, this means that the Apple logo will need to be stacked above the home-screen image. To do this, we give the home-screen image a z-index of 4 and the Apple logo will have a z-index of 5. As the number 4 comes before the number 5, the home-screen image will be below the Apple logo image.

Both images are quite large and are bigger than the screen div so we have to work out what the widths and heights of these two images will be. Through trial and error, I decided that a width of 130% and height of auto for the Apple logo works pretty well as it fits nicely in the screen div. I then gave the Apple logo a relative positioning so that I could then shift the position of the front-camera -30 pixels to the left to perfectly center the image within the screen div.

Similarly, I did the same to the home-screen image; I applied a width of 100% and a height of auto.

Phone start-up animation

Now for the final part of the tutorial: the animation!

First, we need to figure out what our animation will do so we need to think about what happens when an iPhone 6 starts up after being switched on. Now, I'm not an iPhone user (android all the way lol) so I figured that the start-up would be similar to how android phones start up. At first, the company logo appears on the screen and after a few seconds, the home screen comes into view.

Let's translate this into a CSS animation.We will be placing this piece of code at the top of our scss stylesheet.

@keyframes fade {
  0% {
  opacity:1;
  }
  20% {
  opacity: 1;
  }
  22% {
  opacity:0;
  }
  100% {
  opacity:0;
  }
}
Enter fullscreen mode Exit fullscreen mode

So for 20% of the duration of this animation, the opacity will be 1. This means that that for 20% of the duration of the animation, the image will be visible. For the rest of the animation, the opacity will be 0 which means for about 80% of the duration the image will no longer be visible.

Because we'll be applying this animation to our Apple logo image, this means that the logo will visible for 20% of the duration of the animation and for the rest of the animation, it will disappear as its opacity changes from 1 to 0. to reveal the image below which is the home-screen image,

All that is left to do now is to apply our animation to our Apple logo image. You can see how we do this by looking at the animation property we applied to our Apple logo. You can see it below too:

      #apple-logo {
        width: 130%;
        height: auto;
        left: -30px;
        z-index: 5;
        animation: fade 15s ease-in-out 5 alternate;
      }
Enter fullscreen mode Exit fullscreen mode

We start by stating our animation name, which is fade.

The 15 seconds(15s) refers to the animation duration.

Ease-in-out refers to the animation timing function which specifies the speed curve of an animation. The speed curve defines the TIME an animation uses to change from one set of CSS styles to another so that when we apply an animation timing function of ease-in-out, this means that the animation will have a slow beginning and slow end.

The number 5 refers to the animation iteration count, which refers to the number of times the animation will play so in this case, the animation will play 5 times.

The last animation property we will apply is the animation direction, which we have chosen to be alternate. This means that the animation is played forwards first, then backwards.

Here is how our iPhone 6 looks at the end:

That's it! We have managed to create an iPhone 6 UI with a smooth and simple animation.

If you made it this far, I really hope you enjoyed this tutorial, maybe even learned a couple things! Let me know what you think and if you enjoyed this post, like, comment & share! Till next time!

. . . . . . . . . . . . . . . .