
Having designed some visual mocks to help guide us in building our little app for the browser, let’s get to the exciting part and start building!
File Structure
Let’s setup our file structure for the project. It’ll look something like this (with each respective asset living in its corresponding folder):
. ├── index.html └── assets ├── css ├── img ├── js └── sketch
We now have a folder for each of our assets, as well as the .sketch
file we created earlier which holds our page mocks.
Initial HTML
Based on our file structure, let’s setup our basic HTML document with links to our assets (which we will create in a moment).
<!doctype html> <html lang="en-US"> <head> <meta charset="utf-8"> <title>Gimmie Dat iCon</title> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <link href="https://fonts.googleapis.com/css?family=Pacifico" rel="stylesheet" type="text/css"> <link rel="stylesheet" href="assets/css/styles.css"> </head> <body> <header></header> <main></main> <footer></footer> <script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.3/jquery.min.js"></script> <script src="assets/js/main.js"></script> </body> </html>
Here’s what we have so far:
- Basic HTML page structure with header, main content, and footer areas.
- Link to our custom CSS (which we will create)
- Link to Pacifico on Google Fonts (as mentioned earlier, this is the font we will use to display our little app’s name)
- Links to our custom javascript (which we will create) as well as the jQuery library on Google’s Hosted Libraries CDN
Initial CSS
Because this little app is relatively small and simple, I’m going to favor using vanilla CSS in this project (no preprocessor), but you can obviously write your CSS in whatever form you like.
Let’s start by setting up some basic page styles and making comment references to the colors we will be using. In assets/css/styles.css
let’s do the following:
/* General Styles Colors @highlight: #196E76 @text: #4A4A4A; @text-light: #9A9A9A @body-background: #EEEEEE; */ *, *:before, *:after { box-sizing: inherit; margin: 0; padding: 0; } html { box-sizing: border-box; background: #EEEEEE; text-align: center; } body { font-size: 1em; line-height: 1.5; font-family: Lucida Grande, sans-serif; max-width: 43.75em; /* 880/16 */ margin: 0 auto; padding: 0; color: #4A4A4A; } img { max-width: 100%; height: auto; } a { color: inherit; }
Here we’ve setup a few basic page styles governing images, links, and the box model we’ll be using. As you may have noticed, we are using the body
tag as a wrapper by setting its max-width
. This will keep all of our content centered in the middle of the page without extending beyond a certain width.
Notice we also defined the color values we will be using in the top comments. Since we’re not using a preprocessor that allows us to set variables, these will come in handy as we continue writing our styles.
App Header
Let’s create the header of our app. Remember, in Sketch we designed this:

So, let’s create the HTML to match our mock. We will put this content in the header
element we created earlier.
<header> <h1><a href="./">Gimmie Dat iCon</a></h1> <p>Retrieve full-sized icon artwork for iOS & Mac apps.</p> </header>
Now we have our app’s name and description at the top of the page. But the styles are pretty basic.

Let’s write some styles for our page header that brings it more in line with our mock:
/* Header Styles */ header { margin: 1em 0 2em; color: #196E76; } header h1 { font-family: 'Pacifico', serif; font-size: 3em; text-shadow: 0 4px 2px rgba(0, 0, 0, .1); margin: 0; } header h1 a { text-decoration: none; } header p { margin-top: -.625em; text-indent: 7.75em; /* indent slightly */ text-shadow: 0 1px 0px rgba(0, 0, 0, .15); font-size: .875em; /* 14/16 */ }
Here’s a brief overview of what we did:
- Color and spacing for the header container
- App name
header h1
is set to use Pacicifo from Google Fonts (remember, we set a link to this resource in our header) - App description
header p
is slightly offset to avoid running into the descender of the “G” on the app name.
Now we have our header looking more like the design:

However, remember that our app is going to be responsive! So if we check these styles on a narrower width using Chrome’s dev tools, you’ll notice the text wrapping for the description is a little funky because of our text-indent
.

To alleviate this, at narrower widths, we’ll remove the text indentation and bump the description text down with a larger margin-top
so wrapping looks more natural. Let’s write a media query to help us:
@media screen and (max-width: 600px) { header p { text-indent: 0; margin-top: .5em; } }
There, now we have a responsive header!

App Input
The next stage is to move on to the input and output areas of our mock. Remember they looked something like this:

First, let’s add the input field to the main
HTML element we created earlier:
<main> <!-- input --> <form class="submit"> <input type="url" placeholder="iTunes Link..."> <button type="submit">Gimmie</button> </form> <!-- ./input --> </main>
Now we have a form with an input and a submit button. Good semantics thus far, but it’s not quite looking how we want it. We’ll need to add some styles.

Let’s add some styles to our form input and button elements.
/* Form Input Styles for the form input and button */ form { position: relative; } form input{ width: 100%; display: block; font-size: 1em; padding: .625em .85em; padding-right: 7em; line-height: 1.5; margin: 0; border: 1px solid #bbb; box-shadow: 0 1px 3px rgba(0, 0, 0, .1) inset, 0 2px 4px rgba(0, 0, 0, .1); border-radius: 3px; } form input:focus { border-color: #298cda; } form button { text-decoration: none; background: #196E76; height: 100%; position: absolute; right: 0; top: 0; line-height: 1.5; color: white; font-size: 1em; border-radius: 0 3px 3px 0; border: 0; outline: 0; text-align: center; -webkit-appearance: none; margin: 0; padding: 0 1em; font-family: 'Pacifico', serif; } form button:hover { cursor: pointer; } form button:disabled { opacity: .5; }
Here we added some styles to our form input and button as well as some different states like :hover
, :focus
, and :disabled
. This has given us an input styled just the way we designed it in our mock.

App Output
At this point we can create what we’ve been calling the “output” area. This is where we will dynamically render the icon returned by the iTunes API. However, on the initial page load, the user hasn’t yet requested anything. So we’re going to use our zero state design for now. Remember from our mocks, it looks like this:

We’ll continue to add to the main
HTML element we’ve been working in:
<main> <!-- input --> <form class="submit"> <input type="url" placeholder="iTunes Link..."> <button type="submit">Gimmie</button> </form> <!-- ./input --> <!-- output --> <div class="wrapper"> <div class="content"> <p><strong>Enter a valid iTunes app store link, i.e.</strong> <a href="https://itunes.apple.com/us/app/twitter/id333903271?mt=8">https://itunes.apple.com/us/app/twitter/id333903271?mt=8</a></p> <img src="assets/img/icon-placeholder.svg" alt="Icon placeholder" /> </div> </div> <!-- ./output --> </main>
Notice that we added the output HTML right after our input HTML. It consists of a wrapper, which acts as the big white box in our design, and the content, which is centered inside of that. We’ll use CSS to set the .content
element to have a max-width
of 512 pixels, as that’s the largest size at which we will display our icon. For now though, we have something that looks like this:

Notice our icon placeholder is missing. If we go back to our Sketch document, we can easily output that asset as an SVG for use in the browser.

Now we should have the image showing up in the browser.

Let’s add some styles to our output box.
/* Content Styles Main container for content, i.e. the icons, error messages, etc */ .wrapper { background: #fff; border: 1px solid #ccc; text-align: center; padding: 2em; margin: .5em 0 2em; box-shadow: 0 2px 4px rgba(0, 0, 0, .1); border-radius: 3px; position: relative; } .content { max-width: 512px; margin: 0 auto; position: relative; word-wrap: break-word; /* for long urls */ } .content * { /* do a simple reset on elements in .content */ margin: 0; padding: 0; } .content strong { font-weight: bold; display: block; }
Most of the CSS we added here has comments in the code to explain it. We added styles to our outside wrapper, then, because we didn’t do a full CSS reset on the page, we did a simple reset on HTML elements inside of our content area by applying .content *
.
Lastly, we added some styling for bolded elements in our zero state. Now we should have something resembling our mock!

Great Job!
Now that we have our HTML structure all setup, along with corresponding styles, we’re ready to jump in and handle the interactions of the page with JavaScript!
In the next (and final) tutorial of this series, we’ll figure out how to take user input, make an API request, and render the output in the browser. See you there!