Recreating the iOS7 Banner with HTML and CSS

by Donovan Hutchinson on June 17, 2013

The modern web is always changing, and this article is more than two years old.


By Donovan Hutchinson

In this post, we’ll make use of the amazing background gradients in CSS to create a rich, full-screen banner that loads in less than half a second and is only around 2KB in size.

WWDC and iOS 7

Apple have just revealed their latest iteration of the mobile operating system, iOS 7. In the run-up to the announcement at WWDC, they revealed an interesting banner that featured the number 7 against a dotted backdrop, seen below.


I liked this banner a lot. It’s a great combination of rich colors in the elegant, light typeface and an interesting, textured backdrop. It seemed like something that would make a great CSS project, so I gave it a go.

Turns out it is indeed possible to recreate this banner using nothing but HTML and CSS, making use of CSS’ background gradients and 3D transforms. Let’s see how.


Since this demo makes use of the -webkit-background-clip and -webkit-text-fill-color, it’ll work well on Chrome and Safari. Until support for text-clipping in improves, it might not work so well in other browsers.

Source and demo


You can see the finished demo here, and download the source on Github.

As you can see, it differs somewhat from the banner picture above. This is because, when watching the keynote, I noticed the 7 logo used inside a nice icon-shaped white box. I thought that looked cool so I added it to the layout. Hiding the white background in the container element will make it look more like the banner above.

Making the 7

Aside from the extreme thinness of the font (Helvetica Neue UltraLight), it’s most striking feature is the color gradients. To create this 7, we need to make use of CSS’s background gradient property, and then apply the gradient to the text.

Chris Coyier’s wonderful CSS-Tricks website has a great -webkit-background-clip snippet which works nicely for the purposes of this demo.

First, we need to set up some HTML to which we will apply the CSS:

<article class="container">
    <span class="text part1">7</span>
    <span class="text part2">7</span>

Here we have an article that contains two spans, each of which has a 7. The reason for including two 7’s will become apparent in a moment. Before applying gradients, we set up these two spans so that they sit in an iOS-like icon in the middle of the screen.

The containing article is positioned and styled:

body {
    background: black;

.container {
  width: 512px;
  height: 512px;
  position: absolute;
  left: 50%;
  margin-left: -256px;
  top: 50%;
  margin-top: -256px;
  background: whitesmoke;
  border-radius: 120px;

This creates the container as a 512 by 512 pixel box and positions it in the middle of the screen, both vertically and horizontally. The use of absolute positioning is not only a handy way of placing fixed-size elements in the centre of a screen, it’ll also help when we introduce a background pattern later. For now the black background will provide contrast.

Next, we’ll set some properties for the text.

.container span.text {
    font-family: "HelveticaNeue-UltraLight", "Helvetica Neue UltraLight", Roboto, Arial, Sans-serif;
    font-size: 512px;
    position: absolute;
    top: 0;
    left: 124px;

The font is “Helvetica Neue UltraLight”, and I’ve added a fallback of “Roboto”. This is a free Google font that should be somewhat similar, for those systems that might not have the font available. The text spans are positioned absolutely, so that both 7’s will sit directly on top of each other, and both are set to 512 pixels in size.

With the two 7’s placed on top of each other, and the icon in place, it should look a bit like this:


Adding some color

If you look closely at the photo above, you can make out two gradients in the number seven. The first is a red to blue going across the top bar of the seven. The second is a red, purple and blue gradient from the foot of the seven. Since there are two gradients, it’ll mean we need to make use of both the 7’s we added to the HTML.

I picked out several key points in the gradient across the top of the seven, and created some color stops for the first of the two 7’s. I’m using a WebKit version of the background gradient rather than creating all the prefixes:

span.text.part1 {
    background: -webkit-gradient(linear, left top, right top, color-stop(0%, #67e1c9), color-stop(10%, #67e1c9), color-stop(40%, #60b6cf), color-stop(60%, #1f7acb), color-stop(80%, #212f7f));

This gradient starts at the top-left and has 5 color-stop values along the way. The gradient looks a bit like this:


While this is nice, it doesn’t apply to the number in the HTML. To achieve this, we use the background-clip and text-fill-color properties:

span.text.part1 {
    background: -webkit-gradient(linear, left top, right top, color-stop(0%, #67e1c9), color-stop(10%, #67e1c9), color-stop(40%, #60b6cf), color-stop(60%, #1f7acb), color-stop(80%, #212f7f));
    -webkit-background-clip: text;
    -webkit-text-fill-color: transparent;

The result of these properties being added should look like this:


The next step is to apply another gradient to the second seven. Since this seven sits in front, it needs to have a gradient that starts red and ends transparent. Add some color stops to achieve this effect.

span.text.part2 {
    background: -webkit-gradient(linear, left bottom, right top, color-stop(0%, #c71f1f), color-stop(30%, #c71f1f), color-stop(40%, #a24b92), color-stop(50%, #3791ea), color-stop(60%, rgba(33, 47, 127, 0)));
    -webkit-background-clip: text;
    -webkit-text-fill-color: transparent;

In this case the gradient starts at the bottom with red and ends with a fade to a tranparent blue at around 60% transparency. Transparent blue may seem like a contradiction, but the color values in the R, G, and B of that RGBA have an impact on the gradient at it approaches transparent.

Now we’re getting somewhere:


Next step is to create the fancy polka-dot background.

Making the background

The background is a collection of dots that fade into white toward the top of the banner. There is also a subtle 3D effect, with the dots looking like they recede into the distance toward the top. To recreate this effect, we can make use of CSS’s 3D transforms along with background radial gradients.


The background will need some HTML. Place the following before the container article in the HTML source:

<div class="background-container">
    <section class="background"></section>

We’ll make use of a background-container to contain the background and add the pattern CSS to the section within. First, let’s place the background container in place with some CSS.

.background-container {
    width: 100%;
    height: 740px;
    top: 50%;
    margin: -370px auto 0;
    position: absolute;
    -webkit-perspective: 1200px;
    overflow: hidden;

The container is set to the full width of the screen, and 740 pixels high. It makes use of absolute positioning so that it sits in the vertical center of the screen, behind the icon.

Since this container will contain a 3D-transformed element, it’s necessary to specify the perspective property. In this case I’m using the -webkit prefixed version. The perspective property sets the distance for the vanishing point in a 3D scene, allowing elements within it to be placed in the 3D space.

The overflow property is set to hidden so that we can make the background larger than it’s container.

We then set up the styles for the background itself:

.background {
  width: 300%;
  height: 200%;
  position: absolute;
  left: -100%;
  -webkit-transform-style: preserve-3d;
  -webkit-transform: rotateX(45deg);

The main background element is positioned absolutely, set to 3 times the width of its container and twice the height. Then it is rotated 45 degrees on the X axis, which has the effect of tilting it back, so that the bottom of the element will seem closer than the top.

The width and height are set to be so much larger so that the rotated section won’t leave gaps in the top left and right corners. Since the container has the overflow property set to hidden, the extra background won’t be seen.

Making the dots

Let’s make use of a radial gradient to create the pattern.

When a CSS radial or linear gradient is generated, it is created as an image on the fly by the browser. This means that it can be tiled and sized just like a background image.

We generate the dot texture as follows:

div.example {
    background: -webkit-radial-gradient(#d0d1d3 40%, white 65%);
    background-size: 14px 14px;

The resulting dot pattern looks something like this:


Rotation problem

Rather than apply the dot pattern directly to the background element, we need to adjust it to match the banner. The dots in the banner are a diagonal pattern, rather than straight lines. This would mean rotating the pattern 45 degrees around the Z axis. Since the background element has been tilted back 45 degrees already, rotating it on the Z-axis would not create the desired effect:


To get around this we can create a pseudo-selector and apply the pattern to that. Pseudo-selectors can be added to an element to give us extra “elements” that we can style, referred to as before and after. Here’s the before pseudo-selector:

.background:before {
    content: "";
    position: absolute;
    width: 300%;
    height: 300%;
    bottom: 0;
    left: -100%;
    background: -webkit-radial-gradient(#d0d1d3 40%, white 65%);
    background-size: 14px 14px;
    -webkit-transform: rotateZ(45deg);

The before element contains the pattern and is itself rotated 45 degrees on the Z axis. At this point it’s almost there, it needs the white gradient from the top of the banner. We can use the second pseudo-selector to contain that gradient:

.background:after {
    content: "";
    position: absolute;
    left: 0;
    top: -60%;
    right: 0;
    bottom: 0;
    width: 300%;
    height: 200%;
    background: -webkit-gradient(linear, center top, center bottom, color-stop(0%, white), color-stop(60%, rgba(255, 255, 255, 0)));

The gradient on this pseudo-selector starts at white and fades to transparent. It’s positioned a little above the top to allow for the tiled effect of the background element.

Putting it all together, we get something like this:


Smaller screens

Before finishing up, we need to make sure it looks good on smaller devices. In this case, we’ll add a media query to target phones so that it fits onto the screen.

@media only screen and (max-width: 350px) {
    .container {
        width: 300px;
        height: 300px;
        margin-left: -150px;
        border-radius: 80px;
        margin-top: -150px;
    .container span.text {
        font-size: 300px;
        left: 70px;

This adjusts the container to be smaller on screens that display fewer than 350 pixels horizontally.

Demo and get in touch

Check out the online 7 demo or download the source from Github.

I love feedback. Reach me by email or on Twitter.

This post was originally published at

© 2017 Modern Web & our authors. All rights reserved.