0% found this document useful (0 votes)
7 views337 pages

Comprehensive Guide To Web Development

This comprehensive guide to web development covers essential topics including HTML, CSS, and JavaScript, providing a friendly introduction for beginners. It aims to equip readers with the skills to build professional-quality web pages from scratch, potentially replacing costly online courses. The tutorial emphasizes the importance of understanding the interaction between these languages to succeed in web development.
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PDF, TXT or read online on Scribd
0% found this document useful (0 votes)
7 views337 pages

Comprehensive Guide To Web Development

This comprehensive guide to web development covers essential topics including HTML, CSS, and JavaScript, providing a friendly introduction for beginners. It aims to equip readers with the skills to build professional-quality web pages from scratch, potentially replacing costly online courses. The tutorial emphasizes the importance of understanding the interaction between these languages to succeed in web development.
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PDF, TXT or read online on Scribd

COMPREHENSIVE GUIDE TO WEB

DEVELOPMENT

BY

Rima ComputeR tRaining institute sokoto

PREPARED BY: MAHMUD BAKALE & ALIJAFAR UMAR


TABLE OF CONTENTS
INTRODUCTION ........................................................................................................................ 13

HTML, CSS, & JAVASCRIPT ..................................................................................................... 14

LANGUAGES VERSUS “WEB DEVELOPMENT” .............................................................. 16

WEB PUBLISHING ..................................................................................................................... 17

FUNDAMENTALS, NOT FRAMEWORKS ........................................................................... 18

HANDS-ON LEARNING ............................................................................................................ 19

TOOLS OF THE TRADE ......................................................................................................... 19

ATOM TEXT EDITOR................................................................................................................. 20

CREATING A PROJECT ............................................................................................................. 21

CREATING FILES ................................................................................................................... 23

NAVIGATING THE FILE SYSTEM .................................................................................... 23

MULTIPLE PANES .............................................................................................................. 24

OUTSIDE OF ATOM ............................................................................................................ 25

SUMMARY .............................................................................................................................. 26

BASIC WEB PAGES .................................................................................................................... 27

SETUP....................................................................................................................................... 28

STRUCTURE OF A WEB PAGE ............................................................................................. 28

PAGE TITLES........................................................................................................................... 31

PARAGRAPHS ......................................................................................................................... 32

HEADINGS .............................................................................................................................. 34

UNORDERED LISTS............................................................................................................... 35

ORDERED LISTS .................................................................................................................... 37

EMPHASIS (ITALIC) ELEMENTS ......................................................................................... 39

STRONG (BOLD) ELEMENTS .............................................................................................. 40

STRUCTURE VERSUS PRESENTATION ............................................................................. 42

PREPARED BY: MAHMUD BAKALE & ALIJAFAR UMAR


EMPTY HTML ELEMENTS ................................................................................................... 43

LINE BREAKS ..................................................................................................................... 43

HORIZONTAL RULES ........................................................................................................ 45

OPTIONAL TRAILING SLASH .......................................................................................... 46

SUMMARY .............................................................................................................................. 47

LINKS AND IMAGES ................................................................................................................. 48

SETUP....................................................................................................................................... 49

LINKS PAGE ........................................................................................................................ 50

IMAGES PAGE ..................................................................................................................... 50

EXTRAS PAGE..................................................................................................................... 51

IMAGE DOWNLOADS ....................................................................................................... 51

ANCHORS ................................................................................................................................ 52

LINKS ....................................................................................................................................... 52

ABSOLUTE, RELATIVE, AND ROOT-RELATIVE LINKS .................................................. 54

ABSOLUTE LINKS.............................................................................................................. 55

RELATIVE LINKS ............................................................................................................... 56

ROOT-RELATIVE LINKS ................................................................................................... 59

LINK TARGETS ....................................................................................................................... 60

NAMING CONVENTIONS ..................................................................................................... 61

IMAGES.................................................................................................................................... 62

IMAGE FORMATS .................................................................................................................. 62

JPG IMAGES ........................................................................................................................ 63

GIF IMAGES ........................................................................................................................ 63

PNG IMAGES ....................................................................................................................... 64

SVG IMAGES ....................................................................................................................... 64

PREPARED BY: MAHMUD BAKALE & ALIJAFAR UMAR


IMAGE DIMENSIONS ............................................................................................................ 65

TEXT ALTERNATIVES ........................................................................................................... 67

MORE HTML ATTRIBUTES .................................................................................................. 68

DOCUMENT LANGUAGE ................................................................................................. 68

CHARACTER SETS............................................................................................................. 69

HTML ENTITIES ..................................................................................................................... 70

RESERVED CHARACTERS ............................................................................................... 70

QUOTES ............................................................................................................................... 71

UTF-8 AND HTML ENTITIES ............................................................................................ 71

SUMMARY .............................................................................................................................. 72

HELLO, CSS ................................................................................................................................ 73

SETUP....................................................................................................................................... 74

CSS STYLESHEETS ................................................................................................................... 76

LINKING A CSS STYLESHEET ............................................................................................. 77

CSS COMMENTS .................................................................................................................... 79

SETTING MULTIPLE PROPERTIES ..................................................................................... 80

SELECTING DIFFERENT ELEMENTS ................................................................................. 80

UNITS OF MEASUREMENT.................................................................................................. 81

SELECTING MULTIPLE ELEMENTS ................................................................................... 82

DEFINING FONTS ............................................................................................................... 83

LIST STYLES ........................................................................................................................... 84

REUSABLE STYLESHEETS .................................................................................................. 85

MORE TEXT STYLES............................................................................................................. 86

UNDERLINES ...................................................................................................................... 86

TEXT ALIGNMENT ............................................................................................................ 87

PREPARED BY: MAHMUD BAKALE & ALIJAFAR UMAR


FONT WEIGHT AND STYLES ........................................................................................... 87

THE CASCADE ....................................................................................................................... 88

PAGE-SPECIFIC STYLES ................................................................................................... 90

INLINE STYLES .................................................................................................................. 92

MULTIPLE STYLESHEETS ................................................................................................ 93

SUMMARY .............................................................................................................................. 94

CSS BOX MODEL ....................................................................................................................... 95

SETUP....................................................................................................................................... 97

BLOCK ELEMENTS AND INLINE ELEMENTS .................................................................. 98

CHANGING BOX BEHAVIOR ............................................................................................... 99

CONTENT, PADDING, BORDER, AND MARGIN ............................................................. 100

PADDING ............................................................................................................................... 101

SHORTHAND FORMATS ................................................................................................. 102

BORDERS .............................................................................................................................. 104

MARGINS .............................................................................................................................. 106

MARGINS ON INLINE ELEMENTS ................................................................................ 107

VERTICAL MARGIN COLLAPSE ....................................................................................... 108

PREVENTING MARGIN COLLAPSE .............................................................................. 109

GENERIC BOXES ..................................................................................................................111

EXPLICIT DIMENSIONS ......................................................................................................113

CONTENT BOXES AND BORDER BOXES ........................................................................114

ALIGNING BOXES ................................................................................................................116

CENTERING WITH AUTO-MARGINS.............................................................................117

RESETTING STYLES ............................................................................................................118

SUMMARY .............................................................................................................................119

PREPARED BY: MAHMUD BAKALE & ALIJAFAR UMAR


CSS SELECTORS ...................................................................................................................... 120

SETUP..................................................................................................................................... 120

CLASS SELECTORS ............................................................................................................. 121

CLASS NAMING CONVENTIONS .................................................................................. 123

MORE USEFUL DIVS ........................................................................................................... 123

CONTAINER DIVS ................................................................................................................ 125

REUSING CLASS STYLES .................................................................................................. 126

MODIFYING CLASS STYLES ............................................................................................. 127

ORDER MATTERS ............................................................................................................ 128

DESCENDANT SELECTORS ............................................................................................... 129

DON’T OVERDO IT .......................................................................................................... 130

PSEUDO-CLASSES FOR LINKS ......................................................................................... 131

BASIC LINK STYLES ....................................................................................................... 132

VISITED HOVER STATE .................................................................................................. 133

VISITED ACTIVE STATE.................................................................................................. 133

PSEUDO-CLASSES FOR BUTTONS ................................................................................... 134

LINK ELEMENTS, NOT DIV ELEMENTS ...................................................................... 134

BUTTON STYLES ............................................................................................................. 135

THE OTHER BUTTON ...................................................................................................... 136

PSEUDO-CLASSES FOR STRUCTURE .............................................................................. 137

CAVEATS ............................................................................................................................ 138

ID SELECTORS ..................................................................................................................... 140

URL FRAGMENTS ............................................................................................................ 140

CSS SPECIFICITY ................................................................................................................. 142

SUMMARY ............................................................................................................................ 144

PREPARED BY: MAHMUD BAKALE & ALIJAFAR UMAR


FLOATS ...................................................................................................................................... 145

SETUP..................................................................................................................................... 146

DEFAULT HTML LAYOUT BEHAVIOR ............................................................................. 148

FLOATING AN ELEMENT ................................................................................................... 150

FLOATING INSIDE OF PARENTS ....................................................................................... 152

MULTIPLE FLOATS .............................................................................................................. 153

AFTER A FLOAT ................................................................................................................... 155

CLEARING FLOATS ......................................................................................................... 156

HIDING OVERFLOW ........................................................................................................ 158

FULL-BLEED LAYOUTS ..................................................................................................... 160

FLOATS FOR EQUAL-WIDTH COLUMNS ........................................................................ 162

FLOATS FOR GRIDS ............................................................................................................ 163

A BRIEF NOTE ON NAMING CONVENTIONS ............................................................. 165

FLOATS FOR CONTENT ...................................................................................................... 165

HIDING OVERFLOW (FOR CONTENT) ......................................................................... 167

SUMMARY ............................................................................................................................ 169

FLEXBOX .................................................................................................................................. 170

SETUP..................................................................................................................................... 171

FLEXBOX OVERVIEW ........................................................................................................ 174

FLEX CONTAINERS ............................................................................................................. 175

ALIGNING A FLEX ITEM .................................................................................................... 176

DISTRIBUTING MULTIPLE FLEX ITEMS ........................................................................ 177

GROUPING FLEX ITEMS .................................................................................................... 178

CROSS-AXIS (VERTICAL) ALIGNMENT .......................................................................... 180

WRAPPING FLEX ITEMS .................................................................................................... 183

PREPARED BY: MAHMUD BAKALE & ALIJAFAR UMAR


FLEX CONTAINER DIRECTION......................................................................................... 186

ALIGNMENT CONSIDERATIONS .................................................................................. 188

FLEX CONTAINER ORDER ................................................................................................ 188

FLEX ITEM ORDER.............................................................................................................. 190

FLEX ITEM ALIGNMENT.................................................................................................... 191

FLEXIBLE ITEMS ................................................................................................................. 192

STATIC ITEM WIDTHS ..................................................................................................... 194

FLEX ITEMS AND AUTO-MARGINS ................................................................................. 196

SUMMARY ............................................................................................................................ 197

ADVANCED POSITIONING .................................................................................................... 199

SETUP..................................................................................................................................... 200

POSITIONED ELEMENTS ................................................................................................... 203

RELATIVE POSITIONING ................................................................................................... 203

ABSOLUTE POSITIONING .................................................................................................. 205

(RELATIVELY) ABSOLUTE POSITIONING .................................................................. 208

FIXED POSITIONING ........................................................................................................... 209

POSITIONED ELEMENTS FOR ANIMATION ................................................................... 210

POSITIONED ELEMENTS FOR MENUS ............................................................................ 212

INLINE MENU ITEMS .......................................................................................................... 214

SUBMENUS ........................................................................................................................... 215

(RELATIVELY) ABSOLUTE SUBMENUS .......................................................................... 217

Z-INDEX ................................................................................................................................. 218

PSEUDO-CLASSES FOR DROPDOWN MENUS ............................................................... 220

SUMMARY ............................................................................................................................ 221

RESPONSIVE DESIGN ............................................................................................................. 223

PREPARED BY: MAHMUD BAKALE & ALIJAFAR UMAR


SETUP..................................................................................................................................... 225

CSS MEDIA QUERIES .......................................................................................................... 225

A FEW NOTES ON DESIGN ................................................................................................ 227

CHOOSING BREAKPOINTS ............................................................................................ 229

MOBILE-FIRST DEVELOPMENT ....................................................................................... 229

TABLET LAYOUT ................................................................................................................. 233

DESKTOP LAYOUT .............................................................................................................. 234

DISABLING VIEWPORT ZOOMING .................................................................................. 236

SUMMARY ............................................................................................................................ 237

RESPONSIVE IMAGES ............................................................................................................ 238

SETUP..................................................................................................................................... 239

RETINA SCREENS ................................................................................................................ 241

RESPONSIVE SVG IMAGES ............................................................................................... 243

RESPONSIVE PNG, GIF, AND JPG IMAGES ..................................................................... 245

RESPONSIVE IMAGE OPTIMIZATION ............................................................................. 247

RETINA OPTIMIZATION USING SRCSET ........................................................................ 247

SCREEN WIDTH OPTIMIZATION USING SRCSET ......................................................... 249

TESTING WITH CHROME ............................................................................................... 253

ART DIRECTION USING <PICTURE> ............................................................................... 253

SUMMARY ............................................................................................................................ 256

SEMANTIC HTML .................................................................................................................... 257

SETUP..................................................................................................................................... 258

THE DOCUMENT OUTLINE ............................................................................................... 259

ARTICLES .............................................................................................................................. 261

USING MULTIPLE ARTICLE ELEMENTS ..................................................................... 262

PREPARED BY: MAHMUD BAKALE & ALIJAFAR UMAR


SECTIONS .............................................................................................................................. 263

<SECTION> AND THE DOCUMENT OUTLINE ............................................................ 265

NAV ELEMENTS ................................................................................................................... 267

HEADERS .............................................................................................................................. 268

FOOTERS ............................................................................................................................... 270

ASIDES ................................................................................................................................... 271

DIVS FOR LAYOUT .............................................................................................................. 274

DATES AND TIMES .............................................................................................................. 275

ADDRESS............................................................................................................................... 276

FIGURES AND CAPTIONS .................................................................................................. 277

CSS/LEGACY CONSIDERATIONS ..................................................................................... 278

SUMMARY ............................................................................................................................ 278

HTML FORMS ........................................................................................................................... 280

SETUP..................................................................................................................................... 281

HTML FORMS ....................................................................................................................... 284

STYLING FORMS.............................................................................................................. 285

TEXT INPUT FIELDS ........................................................................................................... 286

STYLING TEXT INPUT FIELDS ...................................................................................... 287

EMAIL INPUT FIELDS ......................................................................................................... 289

STYLING EMAIL INPUT FIELDS ................................................................................... 290

RADIO BUTTONS ................................................................................................................. 292

STYLING RADIO BUTTONS ........................................................................................... 293

SELECT ELEMENTS (DROPDOWN MENUS)................................................................... 296

STYLING SELECT ELEMENTS ....................................................................................... 296

TEXTAREAS .......................................................................................................................... 298

PREPARED BY: MAHMUD BAKALE & ALIJAFAR UMAR


STYLING TEXTAREAS .................................................................................................... 298

CHECKBOXES ...................................................................................................................... 299

STYLING CHECKBOXES ................................................................................................ 300

SUBMIT BUTTONS .............................................................................................................. 301

STYLING BUTTONS ......................................................................................................... 302

SUMMARY ............................................................................................................................ 304

WEB TYPOGRAPHY ................................................................................................................ 305

A BRIEF HISTORY OF WEB FONTS .................................................................................. 307

WEB SAFE FONTS ............................................................................................................ 307

CUSTOM WEB FONTS ..................................................................................................... 308

WOFF FONTS .................................................................................................................... 309

WHERE TO FIND WEB FONTS ........................................................................................... 310

SETUP......................................................................................................................................311

LOCALLY HOSTED WEB FONTS ...................................................................................... 312

HOSTING A WOFF FILE ................................................................................................... 313

EMBEDDING A WEB FONT ............................................................................................ 314

USING A WEB FONT ........................................................................................................ 314

FONT FAMILIES AND FONT FACES ................................................................................. 316

FAKIN’ IT ........................................................................................................................... 317

MULTIPLE FONT FACES (THE WRONG WAY) ............................................................ 318

MULTIPLE FONT FACES (THE RIGHT WAY) ............................................................... 320

EXTERNALLY HOSTED WEB FONTS ............................................................................... 322

TOO MANY FONT FILES ................................................................................................. 324

PARAGRAPH INDENTS ....................................................................................................... 326

TEXT ALIGNMENT .............................................................................................................. 328

PREPARED BY: MAHMUD BAKALE & ALIJAFAR UMAR


LEFT ALIGNMENT ........................................................................................................... 329

CENTER ALIGNMENT ..................................................................................................... 329

RIGHT ALIGNMENT ........................................................................................................ 330

JUSTIFIED TEXT ............................................................................................................... 332

VERTICAL TEXT SPACING ................................................................................................. 332

LINE LENGTH ....................................................................................................................... 335

OTHER BASIC TYPOGRAPHY GUIDELINES .................................................................. 336

SUMMARY ............................................................................................................................ 336

PREPARED BY: MAHMUD BAKALE & ALIJAFAR UMAR


INTRODUCTION
HTML & CSS IS HARD

The friendliest first encounter you’ll ever have with web development

Learning HTML and CSS is hard, but it doesn’t have to be. This 14-chapter tutorial is one
of the friendliest HTML and CSS guides. We’ll walk you through everything from selecting
a good text editor (which is surprisingly important) to building full-fledged, professional-
quality web pages from scratch.

We designed HTML & CSS Is Hard to be the only introduction to HTML and CSS that
you’ll ever need. If you put in the effort to read every section and write every code snippet,
this tutorial has the potential to replace hundreds or even thousands of dollars’ worth of
online courses and live training.

Our goal is to make it as easy as possible for complete beginners to become professional
web developers, so if you’ve never written a line of HTML or CSS, but you’re
contemplating a career shift, grab a cup of coffee, take a seat, and let’s get to work.

PREPARED BY: MAHMUD BAKALE & ALIJAFAR UMAR


HTML, CSS, & JAVASCRIPT
Hypertext Markup Language (HTML), Cascading Style Sheets (CSS), and JavaScript are
the languages that run the web. They’re very closely related, but they’re also designed for
very specific tasks. Understanding how they interact will go a long way towards becoming
a web developer. We’ll be expanding on this throughout the tutorial, but the gist of it is:

• HTML is for adding meaning to raw content by marking it up.


• CSS is for formatting that marked up content.
• JavaScript is for making that content and formatting interactive.

Think of HTML as the abstract text and images behind a web page, CSS as the page that
actually gets displayed, and JavaScript as the behaviors that can manipulate both HTML
and CSS.

For example, you might mark some particular run of text as a paragraph with this HTML:

<p id='some-paragraph'>This is a paragraph.</p>

Then, you can set the size and color of that paragraph with some CSS:
p{
font-size: 20px;

PREPARED BY: MAHMUD BAKALE & ALIJAFAR UMAR


color: blue;
}

And, if you want to get fancy, you can re-write that paragraph when the user clicks it with
some JavaScript (we’ll save the fancy stuff for a future tutorial):

var p = [Link]('some-paragraph');
[Link]('click', function(event) {
[Link] = 'You clicked it!';
});

As you can see, HTML, CSS, and JavaScript are totally different languages, but they all refer
to one another in some way. Most websites rely on all three, but the appearance
of every website is determined by HTML and CSS. That makes this tutorial a great starting
point for your web development journey.

PREPARED BY: MAHMUD BAKALE & ALIJAFAR UMAR


LANGUAGES VERSUS “WEB DEVELOPMENT”
Unfortunately, mastering HTML, CSS, and JavaScript is only a prerequisite for becoming
a professional web developer. There are a bunch of other practical skills that you need to
run a website:

• Organizing HTML into reusable templates


• Standing up a web server
• Moving files from your local computer to your web server
• Reverting to a previous version when you screw something up
• Pointing a domain name at your server

Dealing with these complexities involves setting up various “environments” to organize


your files and handle the building/deploying of your website. All of this is orthogonal to
the actual HTML, CSS, and JavaScript code that make up a website. This tutorial focuses
entirely on the languages of HTML and CSS—not setting up those underlying
environments.

PREPARED BY: MAHMUD BAKALE & ALIJAFAR UMAR


But, don’t be overwhelmed. Gaining fluency in HTML and CSS is a significant first step
towards becoming a real web developer. We just don’t want you to walk away from this
tutorial thinking that you’ll be able to launch a full website on your own. You will,
however, have the skills to recreate the vast majority of web pages on the Internet.

WEB PUBLISHING
So, what is it to “learn” HTML and CSS? We like to look at it through a historical lens into
the printing industry. Back in the days of the original printing press, printers created
documents by arranging metal characters, dipping them in ink, and pressing them onto a
piece of paper.

In a lot of ways, that’s exactly what web developers do, except instead of arranging
moveable type, they write HTML and CSS. We’re concerned with the same task as they
were: conveying content in meaningful ways. We even deal with the same presentational
issues they did, like selecting the font to use, setting the size of headings, and determining
the space between lines of text.

PREPARED BY: MAHMUD BAKALE & ALIJAFAR UMAR


Printers used to print a bunch of pages and bind them into a book. Nowadays, we create a
bunch of HTML files and link them together into a website. Learning HTML and CSS is a
matter of understanding the available HTML markup and CSS rules to make a browser render
those files exactly how they’re supposed to.

FUNDAMENTALS, NOT FRAMEWORKS


There’s all sorts of front-end web development frameworks out there (Bootstrap, ZURB
foundation, and Pure CSS, just to name a few). The goal of every single one of them is to
abstract away some of the redundant aspects of creating web pages from scratch. These kinds
of frameworks are an important part of real-world web development, and they’re definitely
worth exploring—but only after mastering the basics with HTML & CSS Is Hard.

This tutorial is about HTML and CSS fundamentals. You’ll walk away with the ability
build pretty much anything you’ll ever need as a web developer with raw HTML and CSS.

PREPARED BY: MAHMUD BAKALE & ALIJAFAR UMAR


This is stuff that stays with you forever, in spite of shiny new additions to the HTML and
CSS standards or trendy new frameworks that help you do things faster.

HANDS-ON LEARNING
Interneting Is Hard is all about hands-on education. With the exception of what you’ve
already read, the entirety of this tutorial revolves around concrete examples, explaining the
conceptual aspects of HTML and CSS along the way.

To get the most of out this tutorial, you should be actively creating web pages and following
along with every single step of each chapter. If you’re serious about becoming a web
developer, you should be typing each code snippet character-by-character instead of copy-
and-pasting them into your text editor.

Why? Because this is what you’ll actually be doing as a real web developer. Typing out
code examples ingrains the muscle memory that will serve you well once you’re out in the
wild and marking up content for real websites.

TOOLS OF THE TRADE


For this tutorial, a decent text editor and web browser is all you need. Your basic workflow
is to write code in your text editor, then open it up in a web browser to see how it looks. As
you start creating your own websites, you’ll eventually add more tools to your toolbox, but
it’s important to start out minimal and thoroughly learn the fundamentals of HTML and CSS.

PREPARED BY: MAHMUD BAKALE & ALIJAFAR UMAR


That said, take the time to get really good at using your text editor. Decent ones come with
features that let you write code faster than you normally could, like auto-completing tags,
jumping around your text, and navigating your file system. Fully leveraging your text editor
is the craftsmanship part of learning HTML and CSS.

The only real prerequisite for a good web browser is that it’s up to date and in mainstream
usage. Chrome and Firefox are favorites amongst web developers. Safari is alright if
you’re running OS X, too. We strongly suggest not creating websites with Internet
Explorer. Professional web development often requires an efficient way to test code on all
of these browsers, but that’s a little more complicated than what we need right now.

ATOM TEXT EDITOR


We recommend the Atom text editor. It’s user friendly even for beginners, provides all the
useful features we mentioned above, and is available for all major operating systems. It’s

PREPARED BY: MAHMUD BAKALE & ALIJAFAR UMAR


also infinitely configurable, which will become important as you identify repetitive tasks
that you can automate.

If you don’t already have Atom, go ahead and download it now, since you’ll be needing it
for the next chapter. Once you’ve downloaded it, open it up so we can take a brief tour of
its major features. You should see two panes with different welcome screens:

We don’t need either of these welcome screens, so close both of them by clicking the x icon
in their corresponding tabs. You can also use the Cmd+W (Mac)
or Ctrl+W (Windows/Linux) shortcut to close them (shortcuts are great, use them whenever
you can). You should be left with a single untitled tab.

CREATING A PROJECT

PREPARED BY: MAHMUD BAKALE & ALIJAFAR UMAR


Each website you work on in Atom is a “project,” which is essentially just a folder on your
file system that contains a bunch of HTML and CSS files. Let’s explore Atom by creating
a fake project and adding a few text files to it. Click File > Open in the menu bar to open
a file dialog window, then select New Folder to create a new folder. Call it hello-atom,
and click Open.

You should now see a sidebar on the left of the interface that says hello-atom at the top
next to a little folder icon. This is our file browser. Of course, it won’t show anything until
we add some files, so let’s do that next.

PREPARED BY: MAHMUD BAKALE & ALIJAFAR UMAR


CREATING FILES
Add some arbitrary text to that untitled tab, then hit Cmd+S (Mac) or Ctrl+S (Windows,
Linux) to save the file. Call it [Link]. After saving it, you should see it appear in
Atom’s file browser.

Let’s make one more file by hitting Cmd+N (Mac) or Ctrl+N (Windows, Linux). This
will create another untitled tab. As with our last file, add whatever text you want, then
save it as [Link].

NAVIGATING THE FILE SYSTEM


Again, one of the most important aspects of a proper text editor is to let you efficiently
navigate all the files in your project. In Atom, you can select the tab of the file you want to
work on or find it in the file browser on the left side of the interface. You can also
use Ctrl+Tab to switch between open tabs.

That’s all fine and dandy for browsing files, but there are a lot of times when
you’re searching for a specific file. For instance, imagine discovering a broken link on
your website while you’re doing some quality assurance. You want to be able to jump into
that file with Atom to fix the link as quickly as possible.

PREPARED BY: MAHMUD BAKALE & ALIJAFAR UMAR


For that, you need Atom’s fuzzy finder, which is accessible via Cmd+T (Mac)
or Ctrl+T (Windows, Linux). When you press this, Atom will open up a search bar and let
you type any part of the filename you’re looking for. Try closing both tabs,
hitting Cmd+T or Ctrl+T, and entering “one”. The [Link] file should pop up, and
you can hit Enter to edit it. This functionality is indispensable once your project grows to
a few dozen files spread across several folders.

MULTIPLE PANES
Atom not only lets you have multiple tabs, but multiple panes as well. To see what we’re
talking about, try right-clicking one of the files in the file browser and selecting Split
Right. This will open that file in a new pane, allowing you to see multiple files at the same
time.

Multiple panes are really useful for examining a CSS file and its related HTML file at the
same time.

PREPARED BY: MAHMUD BAKALE & ALIJAFAR UMAR


OUTSIDE OF ATOM
Finally, we’ll occasionally need to work with files outside of the Atom interface (e.g., when
we want to copy image files into our website). We can use the operating system’s built-in
file browser for this. Right-click a file in Atom’s file browser, then select Show in
Finder/Explorer/Some Other File Browser to open it up in your system’s default file
browser.

From here, you can add new files, create folders, or open up HTML files in a web browser.
That last one is going to become a common task for the rest of this tutorial, so let’s give it
a shot with our [Link] file. Right-click it in your system’s default file browser and
select Open With > Chrome/Firefox/Safari. You should see whatever text you added to
the file rendered as a web page in your default web browser.

Now, you can edit the contents of [Link] in Atom, save it, and reload it in your web
browser by pressing Cmd+R (Mac) or Ctrl+R (Windows, Linux). This is the basic editing
workflow for all web developers, and you’ll become very, very accustomed to it by the
time you’re done working through the next 13 chapters.

PREPARED BY: MAHMUD BAKALE & ALIJAFAR UMAR


SUMMARY
Congratulations! You’ve completed your first step towards becoming a professional web
developer. Hopefully, this chapter has given you a basic understanding of how HTML and
CSS fit into the broader industry of web development and the general philosophy
behind HTML and CSS Is Hard.

The Atom stuff we just covered is going to become part of our daily routine, so make sure
you’re comfortable with everything before moving on. We encourage you to play with the
example project a bit, adding more files and practicing navigating from one to the other.
Mastering the craft of writing HTML and CSS is what distinguishes amazingly productive
developers from average ones.

Now that we’ve got a proper text editor, we’re ready to start coding up some real web
pages. We’ll start by exploring the most common HTML elements over the next two
chapters, then we’ll add some CSS to the mix.

PREPARED BY: MAHMUD BAKALE & ALIJAFAR UMAR


BASIC WEB PAGES
HTML & CSS IS HARD

A friendly tutorial for making (really) simple web pages

HTML defines the content of every web page on the Internet. By “marking up” your
raw content with HTML tags, you’re able to tell web browsers how you want different
parts of your content to be displayed. Creating an HTML document with properly
marked up content is the first step of developing a web page.

In this chapter, we’ll build our first web page. It’ll look like crap because it won’t have
any CSS attached to it, but it will serve as a thorough introduction to the HTML
elements that web developers work with on a daily basis.

As you work your way through the examples, try to approach them as a more hands-on
version of a WYSIWYG editor like Google Docs or Microsoft Word. We’ll be working

PREPARED BY: MAHMUD BAKALE & ALIJAFAR UMAR


with all the same types of content (headings, paragraphs, lists, etc), we’ll just be
defining them a little bit more explicitly with HTML.

SETUP
Let’s get started by creating a new project with Atom called basic-web-pages. Then,
make a new file called [Link] in that folder. This HTML file represents a single
web page, and it’s where we’ll put all our code for this chapter. If you’re not already
set up with Atom, be sure to read the Introduction for this tutorial series.

Remember that the basic workflow for web developers is to edit HTML in their text editor
and view those changes in a web browser, so this is exactly what you should be doing for
each section of this chapter.

STRUCTURE OF A WEB PAGE


Add the following HTML markup to our [Link] file. This is what you’ll start with for
every single web page you’ll ever produce. Typically, you would use a templating engine
of some sort to avoid re-typing the redundant parts, but for this tutorial, we’ll be focusing
on the raw HTML.

<!DOCTYPE html>

PREPARED BY: MAHMUD BAKALE & ALIJAFAR UMAR


<html>
<head>
<!-- Metadata goes here -->
</head>
<body>
<!-- Content goes here -->
</body>
</html>

First, we need to tell browsers that this is an HTML5 web page with the <!DOCTYPE
html> line. This is just a special string that browsers look for when they try to display our
web page, and it always needs to look exactly like it does above.

Then, our entire web page needs to be wrapped in <html> tags. The actual <html> text is
called an “opening tag”, while </html> is called a “closing tag”. Everything inside of these
tags are considered part of the <html> “element”, which is this ethereal thing that gets
created when a web browser parses your HTML tags.

PREPARED BY: MAHMUD BAKALE & ALIJAFAR UMAR


Inside of the <html> element, we have two more elements called <head> and <body>. A
web page’s head contains all of its metadata, like the page title, any CSS stylesheets, and
other things that are required to render the page but you don’t necessarily want the user to
see. The bulk of our HTML markup will live in the <body> element, which represents the
visible content of the page. Note that opening up our page in a web browser won’t display
anything, since it has an empty <body>.

The purpose of this <head>/<body> split will become clearer in a few chapters after we
start working with CSS.

PREPARED BY: MAHMUD BAKALE & ALIJAFAR UMAR


Also notice the HTML comment syntax in the above snippet. Anything that starts with <!-
- and ends with --> will be completely ignored by the browser. This is useful for
documenting your code and making notes to yourself.

PAGE TITLES
One of the most important pieces of metadata is the title of your web page, defined by the
aptly named <title> element. Browsers display this in the tab for your page, and Google
displays it in search engine results.

Try updating our [Link] file’s <head> to match the following:

<!DOCTYPE html>

<html>

<head>

<title>Interneting Is Easy!</title>

</head>

<body>

<!-- Content goes here -->

</body>

</html>

PREPARED BY: MAHMUD BAKALE & ALIJAFAR UMAR


When you reload the page in your browser, you should still see an empty page, but you’ll
also see Interneting Is Easy! in the browser tab:

Notice how all the HTML tags in our web page are neatly nested. It’s very important to
ensure that there are no overlapping elements. For instance, the <title> element is supposed
to be inside of the <head>, so you’d never want to add the closing </head> tag before the
closing </title> tag:

<!-- (Don't ever do this) -->


<head>
<title>Interneting Is Easy!</head>
</title>

PARAGRAPHS
Titles are all well and good, but let’s do something we can actually see. The <p> element
marks all the text inside it as a distinct paragraph. Try adding the following <p> element
to the body of our web page:

<!DOCTYPE html>
<html>
<head>

PREPARED BY: MAHMUD BAKALE & ALIJAFAR UMAR


<title>Interneting Is Easy!</title>
</head>
<body>
<p>First, we need to learn some basic HTML.</p>
</body>
</html>

You should now be able to see some content on the page. Again, since this is content we
want to display, it needs to go in the <body> element, not <head>.

Also note how the <p> and <title> elements are indented twice,
while <body> and <head> are indented once. Indenting nested elements like this is an
important best practice that makes your HTML easier to read for other developers (or for
yourself if you come back 5 months from now and want to change some stuff).

It’s up to you and your development team to decide if you want to use spaces or tab
characters for indents. You can set this preference in your text editor under Atom >
Preferences > Editor and scrolling down to the Tab Type setting.

PREPARED BY: MAHMUD BAKALE & ALIJAFAR UMAR


HEADINGS
Headings are like titles, but they’re actually displayed on the page. HTML provides six levels of
headings, and the corresponding elements are: <h1>, <h2>, <h3>, … , <h6>. The higher the
number, the less prominent the heading.

The first heading on a page should typically be an <h1>, so let’s insert one above our
existing <p> element. It’s very common for the first <h1> element to match the <title> of the
document, as it does here:

<body>
<h1>Interneting Is Easy!</h1>
<p>First, we need to learn some basic HTML.</p>
</body>

By default, browsers render less important headings in smaller fonts. For example, let’s
include a second-level heading and see what happens:

<!DOCTYPE html>
<html>
<head>
<title>Interneting Is Easy!</title>
</head>
<body>

PREPARED BY: MAHMUD BAKALE & ALIJAFAR UMAR


<h1>Interneting Is Easy!</h1>
<p>First, we need to learn some basic HTML.</p>
<h2>Headings</h2>
<p>Headings define the outline of your site. There are six levels of
headings.</p>
</body>
</html>

This should result in a web page that looks something like this:

Headings are the primary way you mark up different sections of your content. They define
the outline of your web page as both humans and search engines see it, which makes
selecting relevant headings essential for a high-quality web page.

UNORDERED LISTS
Whenever you surround a piece of text with HTML tags, you’re adding new meaning to
that text. Wrapping content in <ul> tags tells a browser that whatever is inside should be
rendered as an “unordered list”. To denote individual items in that list, you wrap them
in <li> tags, like so:

PREPARED BY: MAHMUD BAKALE & ALIJAFAR UMAR


<h2>Lists</h2>

<p>This is how you make an unordered list:</p>

<ul>
<li>Add a "ul" element (it stands for unordered list)</li>
<li>Add each item in its own "li" element</li>
<li>They don't need to be in any particular order</li>
</ul>

After adding this markup to the <body> element (underneath the existing content), you
should see a bulleted list with a dedicated bullet for each <li> element:

The HTML specification defines strict rules about what elements can go inside other
elements. In this case, <ul> elements should only contain <li> elements, which means you
should never ever write something like this:
<!-- (This is bad!) -->
<ul>
<p>Add a "ul" element (it stands for unordered list)</p>
</ul>

Instead, you should wrap that paragraph with <li> tags:


<!-- (Do this instead) -->

PREPARED BY: MAHMUD BAKALE & ALIJAFAR UMAR


<ul>
<li><p>Add a "ul" element (it stands for unordered list)</p></li>
</ul>

How do we know that <ul> only accepts <li> elements and that <li> allows nested
paragraphs? Because the Mozilla Developer Network (MDN) says so. MDN is a superb
HTML element reference. We’ll try to cover as much as we can about how to use basic
HTML elements in this tutorial, but whenever you’re not sure about a particular element, do
a quick Google search for “MDN <some-element>”.

ORDERED LISTS
With an unordered list, rearranging the <li> elements shouldn’t change the meaning of the
list. If the sequence of list items does matter, you should use an “ordered list” instead. To
create an ordered list, simply change the parent <ul> element to <ol>. Append the
following content to the Lists section of [Link]:

<p>This is what an ordered list looks like:</p>


<ol>
<li>Notice the new "ol" element wrapping everything</li>
<li>But, the list item elements are the same</li>
<li>Also note how the numbers increment on their own</li>
<li>You should be noticing things is this precise order, because this is
an ordered list</li>
</ol>
When you reload the page in your browser, you’ll notice that the browser automatically
incremented the count for each <li> element. In Hello, CSS, we’ll learn how to change
what type of numbers get displayed.

PREPARED BY: MAHMUD BAKALE & ALIJAFAR UMAR


The difference between an unordered list and an ordered list might seem silly, but it really
does have significance to web browsers, search engines, and, of course, human readers. It’s
also easier than manually numbering each list item.

Step-by-step procedures like recipes, instructions, and even tables of contents are good
candidates for ordered lists, while <ul> lists are better for representing item inventories,
product features, pro/con comparisons, and navigational menus.

PREPARED BY: MAHMUD BAKALE & ALIJAFAR UMAR


EMPHASIS (ITALIC) ELEMENTS
So far, we’ve only been working with “block-level elements” (also called “flow content”).
The other major type of content is “inline elements” or “phrasing content”, which are
treated a little bit differently. Block-level elements are always drawn on a new line, while
inline elements can affect sections of text anywhere within a line.

For instance, <p> is a block-level element, while <em> is an inline element that affects a
span of text inside of a paragraph. It stands for “emphasis”, and it’s typically displayed as
italicized text. Try adding a new section demonstrating emphasized text to our example
web page:

PREPARED BY: MAHMUD BAKALE & ALIJAFAR UMAR


<h2>Inline Elements</h2>

<p><em>Sometimes</em>, you need to draw attention to a particular word or


phrase.</p>

The part wrapped in <em> tags should render as italics, as shown below. Notice how only
part of a line has been affected, which is characteristic of inline elements. In the CSS Box
Model chapter, we’ll discover how inline and block elements can have a dramatic impact on
the layout of a page.

Just in case it hasn’t sunk in yet, it’s really important that you properly nest your HTML
elements. It’s easier to mess up the order of tags when you’re using multiple inline
elements, so make sure to double-check that your markup never looks like this:

<!-- (Again, don't ever do this) -->


<p>This is some <em>emphasized text</p></em>

STRONG (BOLD) ELEMENTS


If you want to be more emphatic than an <em> tag, you can use <strong>. It’s an inline
element just like <em>, and looks like this:

PREPARED BY: MAHMUD BAKALE & ALIJAFAR UMAR


<p>Other times you need to <strong>strong</strong>ly emphasize the importance
of a word or phrase.</p>

It should be rendered in bold text, like so:

To draw even more attention your a span of text, you can nest a <strong> element in
an <em> element (or vice versa). This will give you text that is both strong and
emphasized:

<p><em><strong>And sometimes you need to shout!</strong></em></p>

As the example text suggests, this is effectively the typographic equivalent of shouting.
Have a read through the Web Typography chapter before going too crazy with the bold and
italic fonts.

PREPARED BY: MAHMUD BAKALE & ALIJAFAR UMAR


STRUCTURE VERSUS PRESENTATION
You might be wondering why we’re using the terms “emphasis” and “strong” instead of
“italic” and “bold”. That brings us to an important distinction between HTML and CSS.
HTML markup should provide semantic information about your content—
not presentational information. In other words, HTML should define the structure of your
document, leaving its appearance to CSS.

The pseudo-obsolete <b> and <i> elements are classic examples of this. They used to stand
for “bold” and “italic”, respectively, but HTML5 attempted to create a clear separation

PREPARED BY: MAHMUD BAKALE & ALIJAFAR UMAR


between a document’s structure and its presentation. Thus, <i> was replaced with <em>,
since emphasized text can be displayed in all sorts of ways aside from being italicized (e.g.,
in a different font, a different color, or a bigger size). Same for <b> and <strong>.

As we’ll discover in Hello, CSS, we can alter the browser’s default rendering of
the <strong> and <em> elements. This furthers the point that we shouldn’t call it out as
italicized or bold text in the HTML—that’s something for CSS to decide.

EMPTY HTML ELEMENTS


The HTML tags we’ve encountered so far either wrap text content (e.g., <p>) or other
HTML elements (e.g., <ol>). That’s not the case for all HTML elements. Some of them
can be “empty“ or “self-closing”. Line breaks and horizontal rules are the most common
empty elements you’ll find.

LINE BREAKS
HTML condenses consecutive spaces, tabs, or newlines (together known as “whitespace”)
into a single space. To see what we’re talking about, add the following section to
our [Link] file:

<h2>Empty Elements</h2>

<p>Thanks for reading! Interneting should be getting easier now.</p>

<p>Regards,
The Authors</p>

PREPARED BY: MAHMUD BAKALE & ALIJAFAR UMAR


The newline after Regards in the above snippet will be transformed into a space instead of
displaying as a line break:

This behavior may seem counter intuitive, but web developers often set their text editor to
limit line length to around 80 characters. As a programmer, it’s easier to manage code this
way, but having each of the newlines show up in the rendered page would severely mess
up the intended page layout.

To tell the browser that we want a hard line break, we need to use an explicit <br/> element,
like this:

<p>Regards,<br/>
The Authors</p>

The <br/> element is useful anywhere text formatting matters. Haiku, music lyrics, and
signatures are just a few examples where it might come in handy.

PREPARED BY: MAHMUD BAKALE & ALIJAFAR UMAR


However, be very careful not to abuse the <br/> tag. Each one you use should still
convey meaning—you shouldn’t use it to, say, add a bunch of space between paragraphs:

<!-- (You will be shunned for this) -->


<p>This paragraph needs some space below it...</p>
<br/><br/><br/><br/><br/><br/><br/><br/>
<p>So, I added some hard line breaks.</p>

As discussed in the previous section, this kind of presentational information should be


defined in your CSS instead of your HTML.

HORIZONTAL RULES
The <hr/> element is a “horizontal rule”, which represents a thematic break. The transition
from one scene of a story into the next or between the end of a letter and a postscript are
good examples of when a horizontal rule may be appropriate. For instance:

<h2>Empty Elements</h2>

<p>Thanks for reading! Interneting should be getting easier now.</p>

<p>Regards,<br/>
The Authors</p>

<hr/>

PREPARED BY: MAHMUD BAKALE & ALIJAFAR UMAR


<p>P.S. This page might look like crap, but we'll fix that with some CSS
soon.</p>

One of the themes for this chapter has been the separation of content (HTML) from
presentation (CSS), and <hr/> is no different. Like <em> and <strong>, it has a default
appearance (a horizontal line), but once we start working with CSS, we’ll be able to render
it as more space between sections, a decorative accent character, or pretty much anything
else we want.

Like <br/>, <hr/> should carry meaning—don’t use it when you just want to display a line
for the sake of aesthetics. For that, you’ll want to use the CSS border property, which we’ll
discuss in a few chapters.

Another way to think about the <hr/> element is that it carries less significance than the
separation created by a new heading element, but more significance than a new paragraph.

OPTIONAL TRAILING SLASH


The trailing slash (/) in all empty HTML elements is entirely optional. The above snippet
could also be marked up like this (note the lack of / in the <br> and <hr> tags):

PREPARED BY: MAHMUD BAKALE & ALIJAFAR UMAR


<p>Regards,<br>
The Authors</p>
<hr>

It doesn’t really make a difference which convention you choose, but pick one and stick
to it for the sake of consistency. In this tutorial, we’ll be including the trailing / character
because it clearly shows that it’s a self-closing element. This will help prevent your eyes
from searching for the closing tag elsewhere in the document.

SUMMARY
This chapter may have seemed like an endless list of HTML elements, and, well, it basically
was. HTML is pretty simple when it comes right down to it. Web pages are made up of
HTML elements, each element adds a different meaning to the text it contains, and
elements can be nested inside of each other.

What we did in this chapter is always the first step in the web development process—you
need to define what you want to say (HTML) before defining how you want to say it (CSS).
Hopefully, the [Link] file we created in this chapter will serve as a useful quick-
reference of core HTML elements.

PREPARED BY: MAHMUD BAKALE & ALIJAFAR UMAR


We talked about how writing HTML is sort of like manipulating content in a
WYSIWYG document editor. HTML is obviously a much more manual process, but
the trade off is its incredible flexibility. You can display it in a web page, a mobile
device, a tablet, or a printed piece of paper, each with different layouts. You can even
re-style multiple documents just by changing a single line of CSS. Microsoft Word
doesn’t come close to the potential of HTML and CSS as a content medium.

LINKS AND IMAGES


Nº 3. of HTML & CSS Is Hard
A friendly HTML tutorial about connecting web pages to each other
The previous chapter covered some very important HTML elements, but we were only
dealing with a single web page. Links and images are fundamentally different from
those elements in that they deal with external resources. Links point the user to a
different HTML document, and images pull another resource into the page.

PREPARED BY: MAHMUD BAKALE & ALIJAFAR UMAR


To use links and images, we’ll also need to learn about another component of the HTML
syntax: attributes. Attributes will open up a whole new world of possibilities for our
web pages.

In this chapter, we’ll create a simple website composed of several HTML documents
and image files. It may be entitled Links and Images, but the central theme of this
chapter is actually around file and folder organization. As we start working with
multiple files, we’ll discover the importance of being an organized web developer.

SETUP
This chapter is all about linking web pages together, so we’ll need to create some new
HTML files before we code anything up. We’ll be working with three separate web
pages this chapter, along with a few image files of various formats:

PREPARED BY: MAHMUD BAKALE & ALIJAFAR UMAR


To get started, create a new folder called links-and-images to store all our files. You
should be able to do this in Atom using the same process we followed in
the Introduction chapter.

LINKS PAGE
Next, add a new file to that folder called [Link] and insert the following HTML
template. This should be familiar to you from the previous chapter.
<!DOCTYPE html>
<html>
<head>
<title>Links</title>
</head>
<body>
<h1>Links</h1>
</body>
</html>

IMAGES PAGE
In the same folder, create another file called [Link]:
<!DOCTYPE html>
<html>
<head>

PREPARED BY: MAHMUD BAKALE & ALIJAFAR UMAR


<title>Images</title>
</head>
<body>
<h1>Images</h1>
</body>
</html>

EXTRAS PAGE
Our last page will help us demonstrate relative links. Create a new folder in links-and-
images called misc, then add a new file called [Link]:
<!DOCTYPE html>
<html>
<head>
<title>Extras</title>
</head>
<body>
<h1>Extras</h1>
</body>
</html>
Note that you can create a new folder in Atom by right-clicking the file browser pane
and selecting New Folder in the contextual menu. Life is better when you never need
to leave your text editor.

IMAGE DOWNLOADS
We’ll be embedding images in our [Link] file, so be sure to download
these example mochi images, too. Unzip them in your links-and-images folder, keeping
the parent images folder from the ZIP file. Your project should now look like this:

PREPARED BY: MAHMUD BAKALE & ALIJAFAR UMAR


ANCHORS
Links are created with the <a> element, which stands for “anchor”. It works just like all
the elements in the previous chapter: when you wrap some text in <a> tags, it alters the
meaning of that content. Let’s take a look by adding the following paragraph to
the <body> element of [Link]:

<p>This example is about links and <a>images</a>.</p>

If you load the page in a web browser, you’ll notice that the <a> element doesn’t look
like a link at all. Yes, unfortunately, the <a> element on its own doesn’t do much of
anything.

LINKS
In the same way that an element adds meaning to the content it contains, an HTML
“attribute” adds meaning to the element it’s attached to.

PREPARED BY: MAHMUD BAKALE & ALIJAFAR UMAR


Different elements allow different attributes, and you can refer to MDN for details
about which elements accept which attributes. Right now, we’re concerned with
the href attribute because it determines where the user goes when they click
an <a> element. Update your link to match the following:

<p>This example is about links and <a href='[Link]'>images</a>.</p>

Notice how attributes live inside the opening tag. The attribute name comes first, then
an equal sign, then the “value” of the attribute in either single or double quotation
marks. This syntax distinguishes attributes from content (which goes between the tags).

The extra bit of information provided by the href attribute tells the browser that
this <a> element is in fact a link, and it should render the content in its default blue text:

PREPARED BY: MAHMUD BAKALE & ALIJAFAR UMAR


ABSOLUTE, RELATIVE, AND ROOT-RELATIVE LINKS
Now that we’re working with links, we need to understand how a website is structured. For our
purposes, a website is just a collection of HTML files organized into folders. To refer to those files
from inside of another file, the Internet uses “uniform resource locators” (URLs). Depending on
what you’re referring to, URLs can take different forms. The three types of URLs we’ll be dealing
with are highlighted below:

Absolute, relative, and root-relative links refer to the value of the href attribute. The
next few sections will explain how and when to use each of them. But first, let’s add
the following content to our [Link] file:

<p>This particular page is about links! There are three kinds of links:</p>

<ul>
<!-- Add <li> elements here -->
</ul>

PREPARED BY: MAHMUD BAKALE & ALIJAFAR UMAR


ABSOLUTE LINKS
“Absolute” links are the most detailed way you can refer to a web resource. They start with the
“scheme” (typically http:// or [Link] followed by the domain name of the website, then the path
of the target web page.

For example, try creating a link to the Mozilla Developer Network’s HTML element reference:

<li>Absolute links, like to


<a href='[Link]
Developer Network</a>, which is a very good resource for web
developers.</li>

It’s possible to use absolute links to refer to pages in your own website, but hard-coding your
domain name everywhere can make for some tricky situations. It’s usually a better idea to reserve
absolute links only for directing users to a different website.

PREPARED BY: MAHMUD BAKALE & ALIJAFAR UMAR


RELATIVE LINKS
“Relative” links point to another file in your website from the vantage point of the file
you’re editing. It’s implied that the scheme and domain name are the same as the current
page, so the only thing you need to supply is the path.

Here’s how we can link to our [Link] file from inside of [Link]:
<li>Relative links, like to our <a href='misc/[Link]'>extras
page</a>.</li>

In this case, the href attribute represents the file path to [Link] from
the [Link] file. Since [Link] isn’t in the same folder as [Link], we need to
include the misc folder in the URL.

Each folder and file in a path is separated by a forward slash ( /). So, if we were trying
to get to a file that was two folders deep, we’d need a URL like this:

misc/other-folder/[Link]

PREPARED BY: MAHMUD BAKALE & ALIJAFAR UMAR


PARENT FOLDERS
That works for referring to files that are in the same folder or a deeper folder. What
about linking to pages that are in a directory above the current file? Let’s try creating
relative links to [Link] and [Link] from within our [Link] file. Add this
to [Link]:

<p>This page is about miscellaneous HTML things, but you may


also be interested in <a href='[Link]'>links</a> or
<a href='[Link]'>images</a>.</p>

When you click either of those links in a web browser, it will complain that the page
doesn’t exist. Examining the address bar, you’ll discover that the browser is trying to
load misc/[Link] and misc/[Link]—it’s looking in the wrong folder! That’s
because our links are relative to the location of [Link], which lives in
the misc folder.

PREPARED BY: MAHMUD BAKALE & ALIJAFAR UMAR


To fix this, we need the .. syntax. Two consecutive dots in a file path represent a pointer
to the parent directory:
<p>This page is about miscellaneous HTML things, but you may also be
interested in <a href='../[Link]'>links</a> or <a
href='../[Link]'>images</a>.</p>

This is like saying, “I know [Link] is in the misc folder. Go up a folder and look
for [Link] and [Link] in there.”

To navigate up through multiple directories, use multiple .. references, like so:


../../[Link]
Relative links are nice because they let you move around entire folders without having
to update all the href’s on your <a> elements, but they can get a little confusing when
all your links start with a bunch of dots. They’re best for referring to resources in the
same folder or in a standalone section of your website.

PREPARED BY: MAHMUD BAKALE & ALIJAFAR UMAR


For example, all the images in HTML & CSS Is Hard are loaded with relative URLs
(we’ll learn how to do images a moment). This allows us to rename any of our chapter
slugs without having to update all our image paths.

ROOT-RELATIVE LINKS
“Root-relative” links are similar to the previous section, but instead of being relative to
the current page, they’re relative to the “root” of the entire website. For instance, if your
website is hosted on [Link], all root-relative URLs will be relative to [Link].

Unfortunately, there is one caveat to our discussion of root-relative links: this entire
tutorial uses local HTML files instead of a website hosted on a web server. This means
we won’t be able to experiment with root-relative links. But, if we did have a real server,
the link to our home page would look like this:

<!-- This won't work for our local HTML files -->
<li>Root-relative links, like to the <a href='/'>home page</a> of our website,
but those aren't useful to us right now.</li>

The only difference between a root-relative link and a relative one is that the
former starts with a forward slash. That initial forward slash represents the root of your
site. You can add more folders and files to the path after that initial slash, just like
relative links. The following path will work correctly no matter where the current page
is located (even in misc/[Link]):
/[Link]

PREPARED BY: MAHMUD BAKALE & ALIJAFAR UMAR


Root-relative links are some of the most useful kinds of links. They’re explicit enough
to avoid the potential confusion of relative links, but they’re not overly explicit like
absolute links. You’ll see a lot of them throughout your web development career,
especially in larger websites where it’s hard to keep track of relative references.

LINK TARGETS
Attributes alter the meaning of HTML elements, and sometimes you need to modify
more than one aspect of an element. For example, <a> elements also accept
a target attribute that defines where to display the page when the user clicks the link. By
default, most browsers replace the current page with the new one. We can use
the target attribute to ask the browser to open a link in a new window/tab.

Try changing our absolute link in [Link] to match the following. Notice how the
second attribute looks just like the first, but they’re separated from each other by a space
(or a newline):

<li>Absolute links, like to


<a href='[Link]
target='_blank'>Mozilla Developer Network</a>, which is a very good
resource for web developers.</li>

The target attribute has a few pre-defined values that carry special meaning for web
browsers, but the most common one is _blank, which specifies a new tab or window.
You can read about the rest on MDN.

PREPARED BY: MAHMUD BAKALE & ALIJAFAR UMAR


NAMING CONVENTIONS
You’ll notice that none of our files or folders have spaces in their names. That’s on
purpose. Spaces in URLs require special handling and should be avoided at all costs.
To see what we’re talking about, try creating a new file in our links-and-images project
called spaces are [Link]. Add a little bit of text to it, then open it in Google Chrome
or Safari (Firefox cheats and preserves the spaces).

links-and-images/spaces%20are%[Link]

In the address bar, you’ll see that all our spaces have been replaced with %20, as shown
above. Spaces aren’t allowed in URLs, and that’s the special encoding used to represent
them. Instead of a space, you should always use a hyphen, as we’ve been doing
throughout this tutorial. It’s also a good idea to use all lowercase characters for
consistency.

Notice how there’s a direct connection between our file/folder names and the URL for
the web page they represent. The names of our folders and files determine the slugs for
our web pages. They’re visible to the user, which means you should put in as much
effort into naming your files as you put into creating the content they contain.

These naming conventions apply to all of the files in your site—not just HTML files.
CSS files, JavaScript files, and images should avoid spaces and have consistent
capitalization, too.

PREPARED BY: MAHMUD BAKALE & ALIJAFAR UMAR


IMAGES
Unlike all the HTML elements we’ve encountered so far, image content is
defined outside of the web page that renders it. Fortunately for us, we already have a
way to refer to external resources from within an HTML document: absolute, relative,
and root-relative URLs.

Images are included in web pages with the <img/> tag and its src attribute, which points
to the image file you want to display. Notice how it’s an empty
element like <br/> and <hr/> from the previous chapter. (Don’t add this to our project
just yet. We’ll deal with concrete examples in the next section.)

<img src='[Link]'/>

Retina displays and mobile devices make image handling a little bit more complicated
than a plain old <img/> tag. We’ll leave these complexities for the Responsive
Images chapter of this tutorial. Also be sure to check out
the <figure> and <figcaption> element in the Semantic HTML chapter.
For now, let’s focus on the many image formats floating around the Internet.

IMAGE FORMATS
There’s four main image formats in use on the web, and they were all designed to do
different things. Understanding their intended purpose goes a long way towards
improving the quality of your web pages.

PREPARED BY: MAHMUD BAKALE & ALIJAFAR UMAR


The next few sections will walk through ideal use cases for each of these image formats.
Make sure you’ve unzipped these mochi images into your links-and-images project
before moving on.

JPG IMAGES
JPG images are designed for handling large color palettes without exorbitantly
increasing file size. This makes them great for photos and images with lots of gradients
in them. On the other hand, JPGs don’t allow for transparent pixels, which you can see
in the white edges of the image below if you look real close:

Embed this [Link] image in our [Link] page with the following snippet (this
also includes a bit of navigation to our other pages):
<p>This page covers common image formats, but you may also be looking for <a
href='[Link]'>links</a> and <a href='misc/[Link]'>useful
extras</a>.</p>
<h2>JPGs</h2>
<p>JPG images are good for photos.</p>
<img src='images/[Link]'/>

GIF IMAGES
GIFs are the go-to option for simple animations, but the trade off is that they’re
somewhat limited in terms of color palette—never use them for photos. Transparent
pixels are a binary option for GIFs, meaning you can’t have semi-opaque pixels. This
can make it difficult to get high levels of detail on a transparent background. For this
reason, it’s usually better to use PNG images if you don’t need animation.

PREPARED BY: MAHMUD BAKALE & ALIJAFAR UMAR


You can add this little guy to our [Link] file with the following:
<h2>GIFs</h2>
<p>GIFs are good for animations.</p>
<img src='images/[Link]'/>

PNG IMAGES
PNGs are great for anything that’s not a photo or animated. For photos, a PNG file of
the same quality (as perceived the human eye) would generally be bigger than an
equivalent JPG file. However, they do deal with opacity just fine, and they don’t have
color palette limitations. This makes them an excellent fit for icons, technical diagrams,
logos, etc.

Let’s add this PNG image to our example project as well:

<h2>PNGs</h2>
<p>PNGs are good for diagrams and icons.</p>
<img src='images/[Link]'/>

SVG IMAGES
Unlike the pixel-based image formats above, SVG is a vector-based graphics format,
meaning it can scale up or down to any dimension without loss of quality. This property
makes SVG images a wonderful tool for responsive design. They’re good for pretty
much all the same use cases as PNGs, and you should use them whenever you can.

PREPARED BY: MAHMUD BAKALE & ALIJAFAR UMAR


These 300×300 pixel images were originally 100×100 pixels, but scaling them up
clearly shows the difference between them. Notice the crisp, clean lines on the left SVG
image, while the PNG image on the right is now very pixelated.

Despite being a vector format, SVGs can be used exactly like their raster counterparts.
Go ahead and add the [Link] to our [Link] page:
<h2>SVGs</h2>
<p>SVGs are <em>amazing</em>. Use them wherever you can.</p>
<img src='images/[Link]'/>
There is one potential issue with SVGs: for them to display consistently across
browsers, you need to convert any text fields to outlines using your image editor (e.g.,
Abode Illustrator or Sketch). If your images contain a lot of text (like the fancy
screenshots in this tutorial), this can have a big impact on file size. For this
reason, [Link] uses PNGs instead of SVGs, even though SVGs are so
awesome.

IMAGE DIMENSIONS
By default, the <img/> element uses the inherit dimensions of its image file. Our JPG,
GIF, and PNG images are actually 150×150 pixels, while our SVG mochi is only
75×75 pixels.

PREPARED BY: MAHMUD BAKALE & ALIJAFAR UMAR


PREPARED BY: MAHMUD BAKALE & ALIJAFAR UMAR
As we’ll discuss further in Responsive Images, pixel-based image formats need to be
twice as big as you want them to appear on retina displays. To get our pixel-based
images down to the intended size (75×75), we can use
the <img/> element’s width attribute. In [Link], update all of our pixel-based
images to match the following:

<!-- In JPGs section -->


<img src='images/[Link]' width='75'/>

<!-- In GIFs section -->


<img src='images/[Link]' width='75'/>

<!-- In PNGs section -->


<img src='images/[Link]' width='75'/>

The width attribute sets an explicit dimension for the image. There’s a
corresponding height attribute, as well. Setting only one of them will cause the image
to scale proportionally, while defining both will stretch the image. Dimension values
are specified in pixels, and you should never include a unit (e.g., width='75px' would be
incorrect).

The width and height attributes can be useful, but it’s usually better to set image
dimensions with CSS so you can alter them with media queries. We’ll discuss this in
more detail once we get to responsive design.

TEXT ALTERNATIVES
Adding alt attributes to your <img/> elements is a best practice. It defines a “text
alternative” to the image being displayed. This has an impact on both search engines
and users with text-only browsers (e.g., people that use text-to-speech software due to
a vision impairment).

PREPARED BY: MAHMUD BAKALE & ALIJAFAR UMAR


Update all our images to include descriptive alt attributes:
<!-- In JPGs section -->
<img src='images/[Link]' width='75' alt='A mochi ball in a bubble'/>

<!-- In GIFs section -->


<img src='images/[Link]' width='75' alt='A dancing mochi ball'/>

<!-- In PNGs section -->


<img src='images/[Link]' width='75' alt='A mochi ball'/>

<!-- In SVGs section -->


<img src='images/[Link]' alt='A mochi ball with Bézier handles'/>
For more examples of how to use the alt attribute, please refer to the ridiculously
detailed official specification.

MORE HTML ATTRIBUTES


Now that we’re (hopefully) more than comfortable with the HTML attribute syntax, we
can add a couple of finishing touches to our HTML boilerplate code. Every web page
you create should define the language it’s written in and its character set.

DOCUMENT LANGUAGE
A web page’s default language is defined by the lang attribute on the top-
level <html> element. Our document is in English, so we’ll use the en country code as
the attribute value (do this for all of the pages we created):
<html lang='en'>
If you’re not sure what the country code for your language is, you can look it
up here under the Subtag field.

PREPARED BY: MAHMUD BAKALE & ALIJAFAR UMAR


CHARACTER SETS
A “character set” is kind of like a digital alphabet for your browser. It’s different from
the language of your document in that it only affects how the letters themselves are
rendered, not the language of the content. Let’s copy and paste some international
characters into our misc/[Link] web page and see what happens.
<h2>Character Sets</h2>

<p>You can use UTF-8 to count in Turkish:</p>

<ol>
<li>bir</li>
<li>iki</li>
<li>üç</li>
<li>dört</li>
<li>beş</li>
</ol>

When you view this in a browser, you’ll see some weird stuff where the ü, ç, ö,
and ş characters should be:

PREPARED BY: MAHMUD BAKALE & ALIJAFAR UMAR


That’s because the default character set for most browsers doesn’t accommodate these
“special” characters. To fix this, specify a UTF-8 character encoding by adding
a <meta> element with a charset attribute to the <head> of our misc/[Link] file:
<meta charset='UTF-8'/>
The special characters should now render correctly. These days, UTF-8 is sort of like
a universal alphabet for the Internet. Every web page you create should have this line
in its <head>.

HTML ENTITIES
Ok, so this last section doesn’t actually have anything to do with links or images, but
we do need to discuss one more thing before switching gears into CSS. An “HTML
entity” is a special character that can’t be represented as plain text in an HTML
document. This typically either means it’s a reserved character in HTML or you don’t
have a key on your keyboard for it.

RESERVED CHARACTERS
The <, >, and & characters are called “reserved characters” because they aren’t allowed
to be inserted into an HTML document without being encoded. This is because they
mean something in the HTML syntax: < begins a new tag, > ends a tag, and, as we’re
about to learn, & sets off an HTML entity.

In misc/[Link], add the following:


<h2>HTML Entities</h2>
<p>There are three reserved characters in HTML: &lt; &gt; and &amp;. You
should always use HTML entities for these three characters.</p>

Entities always begin with an ampersand (&) and end with a semicolon (;). In between,
you put a special code that your browser will interpret as a symbol. In this case, it

PREPARED BY: MAHMUD BAKALE & ALIJAFAR UMAR


interprets lt, gt, and amp as less-than, greater-than, and ampersand symbols,
respectively.

There’s a crap-ton of HTML entities. We’ll leave you to explore most of them on your
own.

QUOTES
Curly quotes are by no means necessary, but if you care about typography they’ll be
some of the most common HTML entities you’ll use. There’s four different kinds of
curly quotes (opening and closing single and double quotes):
• &ldquo;
• &rdquo;
• &lsquo;
• &rsquo;
You can use them in place of ' and " straight quotes, like so:
<p>If you&rsquo;re into &ldquo;web typography,&rdquo; you&rsquo;ll also find
yourself using curly quotes quite a bit.</p>

Unlike straight quotes, these curly quote entities should hug the text.

UTF-8 AND HTML ENTITIES


In the olden days of the web, HTML files weren’t allowed to have special characters in
them, making entities much more useful. But, since we’re now using a UTF-8 character
set, we should be able to insert any character directly into the HTML document. This
makes entities primarily useful as reserved characters or for convenience when
authoring straight HTML.

PREPARED BY: MAHMUD BAKALE & ALIJAFAR UMAR


SUMMARY
A website is basically just a bunch of HTML, image, and (as we’ll learn about
shortly) CSS files linked together. You should start thinking of a website as a
beautiful way for users to navigate the folders and files we create as part of the web
development process. With that perspective, it should be clear than maintaining a
well-organized file system is a critical aspect of creating a website.

We also learned about a few important attributes (lang and charset) that give us the basic
template you should use as the beginning of every web page you ever create:

<!DOCTYPE html>
<html lang='en'>
<head>
<meta charset='UTF-8'/>
<title>Some Web Page</title>
</head>
<body>
<h1>Some Web Page</h1>
<!-- Rest of the page content -->
</body>
</html>

However, we’re still missing one really big piece: CSS. In the next chapter, we’ll
discover more HTML elements and attributes that will let us attach CSS styles to our
entire website. The ability to work with multiple files and link them to each other in
intelligent ways will become even more important than it was in this chapter.

PREPARED BY: MAHMUD BAKALE & ALIJAFAR UMAR


HELLO, CSS
Nº 4. of HTML & CSS Is Hard
A friendly tutorial for crafting slightly prettier websites

The first few chapters of this tutorial focused exclusively on HTML. Now, it’s time to
make things pretty (sort of) with Cascading Style Sheets (CSS). You can think of CSS
as defining the “design” of a web page. It determines things like font size, margins, and
colors using a language entirely separate from HTML.

Why is it a separate language? Well, it serves a completely different purpose. HTML


represents the content of your web page, while CSS defines how that content is
presented to the user. This is a fundamental distinction central to modern web
development.

PREPARED BY: MAHMUD BAKALE & ALIJAFAR UMAR


CSS provides the vocabulary to tell a web browser things like, “I want my headings to
be really big and my sidebar to appear on the left of the main article.” HTML doesn’t
have the terminology to make those kinds of layout decisions—all it can say is, “that’s
a heading and that’s a sidebar.”

In this chapter, we’ll explore the basic syntax of CSS, as well as how to connect it to
our HTML documents. The goal isn’t so much to become a CSS expert or memorize
all the available styles, but rather to understand how CSS and HTML interact. CSS
typically lives in its own file, so as in the previous chapter, good file organization will
be paramount.

SETUP
To keep things simple, we’ll store the example for each chapter of this tutorial in a
separate folder. Using Atom, create a new project called hello-css. We’re going to be
styling an existing page called [Link], so go ahead and create that, then add the
following markup:
<!DOCTYPE html>
<html lang='en'>

PREPARED BY: MAHMUD BAKALE & ALIJAFAR UMAR


<head>
<meta charset='UTF-8'/>
<title>Hello, CSS</title>
</head>
<body>
<h1>Hello, CSS</h1>

<p>CSS lets us style HTML elements. There’s also


<a href='[Link]'>another page</a> associated with this example.</p>

<h2>List Styles</h2>

<p>You can style unordered lists with the following bullets:</p>

<ul>
<li>disc</li>
<li>circle</li>
<li>square</li>
</ul>

<p>And you can number ordered lists with the following:</p>

<ol>
<li>decimal</li>
<li>lower-roman</li>
<li>upper-roman</li>
<li>lower-alpha</li>
<li>upper-alpha</li>
<li>(and many more!)</li>
</ol>
</body>
</html>

In addition, we’ll need a small dummy page to learn how CSS styles can be applied to
multiple web pages. Create [Link] and add the following:

PREPARED BY: MAHMUD BAKALE & ALIJAFAR UMAR


<!DOCTYPE html>
<html lang='en'>
<head>
<meta charset='UTF-8'/>
<title>Dummy</title>
</head>
<body>
<h1>Dummy</h1>

<p>This is a dummy page that helps us demonstrate reusable CSS


stylesheets. <a href='[Link]'>Go back</a>.</p>

<p>Want to try crossing out an <a href='[Link]'>obsolete link</a>? This


is your chance!</p>
</body>
</html>

CSS STYLESHEETS
CSS stylesheets reside in plaintext files with a .css extension. Create a new file
called [Link] in our hello-css folder. This will house all our example snippets for this
chapter. Let’s add one CSS rule so that we can tell if our stylesheet is hooked up to our
HTML pages properly.
body {
color: #FF0000;
}
A CSS “rule” always start with a “selector” that defines which HTML elements it
applies to. In this case, we’re trying to style the <body> element. After the selector, we
have the “declarations block” inside of some curly braces. Any “properties” we set in
here will affect the <body> element.

PREPARED BY: MAHMUD BAKALE & ALIJAFAR UMAR


Color is a built-in property defined by the CSS specification that determines the text
color of whatever HTML elements have been selected. It accepts a hexadecimal value
representing a color. #FF0000 means bright red.

CSS properties are kind of like HTML attributes in that they both deal with key-value
pairs. Except, here we’re defining presentational information instead of contributing to
the semantic meaning of the underlying content.

LINKING A CSS STYLESHEET


If you try loading either of the HTML pages in a browser, you won’t see our stylesheet
in action. That’s because we didn’t link them together yet. This is what the
HTML <link/> element is for. In [Link], change <head> to the following:

<head>
<meta charset='UTF-8'/>
<title>Hello, CSS</title>
<link rel='stylesheet' href='[Link]'/>
</head>

This <link/> element is how browsers know they need to load [Link] when they try
to render our [Link] page. We should now see blindingly red text everywhere:

PREPARED BY: MAHMUD BAKALE & ALIJAFAR UMAR


The <link/> element is just like the <a> element, but it’s only meant to be used inside
of <head>. Since it’s in the head of the document, <link/> connects to metadata that’s
defined outside of the current document. Also notice that it’s an empty element, so it
doesn’t need a closing tag.

The rel attribute defines the relationship between the resource and the HTML
document. By far the most common value is stylesheet, but there are a few other options.
The href attribute works the same as in the previous chapter, only it should point to
a .css file instead of another web page. The value for href can be an absolute, relative,
or root-relative link.

PREPARED BY: MAHMUD BAKALE & ALIJAFAR UMAR


Note that there’s no direct connection between the browser and our stylesheet. It’s only
through the HTML markup that the browser can find it. CSS, images, and even
JavaScript all rely on an HTML page to glue everything together, making HTML the
heart of most websites.

CSS COMMENTS
Now that our stylesheet is hooked up, let’s play with it a little bit. That red is horrible.
Let’s tone it down to a nice gray:
body {
color: #414141; /* Dark gray */
}
Notice that comments in CSS are a little different than their HTML counterparts.
Instead of the <!-- --> syntax, CSS ignores everything between /* and */ characters.

PREPARED BY: MAHMUD BAKALE & ALIJAFAR UMAR


SETTING MULTIPLE PROPERTIES
You can stick as many properties as you want in the declarations block of a CSS rule. Try
setting the background color of the entire web page by changing our rule to the following:
body {
color: #414141; /* Dark gray */
background-color: #EEEEEE; /* Light gray */
}
The background-color property is very similar to the color property, but it defines the
background color of whatever element you selected. Take a second to admire those
semicolons at the end of each declaration. Removing them will break the CSS rule,
so always mind your semicolons!
Why did we pick shades of grays instead of black and white? Using
a #000000 background with a #FFFFFF text color is too high of a contrast. It makes it
look like the page is vibrating, which can be very distracting for readers.

SELECTING DIFFERENT ELEMENTS


Of course, you’ll want to apply styles to elements other than <body>. For that, simply
add more CSS rules with different selectors. We can change the font size of
our <h1> headings like so:
body {
color: #414141; /* Dark gray */
background-color: #EEEEEE; /* Light gray */
}

h1 {
font-size: 36px;
}
And, if you want to alter h2 headings, add another rule:
h2 {
font-size: 28px;

PREPARED BY: MAHMUD BAKALE & ALIJAFAR UMAR


}

UNITS OF MEASUREMENT
Many CSS properties require a unit of measurement. There’s a lot of units available,
but the most common ones you’ll encounter are px (pixel) and em (pronounced like the
letter m). The former is what you would intuitively call a pixel, regardless of whether
the user has a retina display or not, and the latter is the current font size of the element
in question.

The em unit is very useful for defining sizes relative to some base font. In the above
diagram, you can see em units scaling to match a base font size of 12px, 16px, and 20px.
For a concrete example, consider the following alternative to the previous code snippet:
body {
color: #414141; /* Dark gray */
background-color: #EEEEEE; /* Light gray */
font-size: 18px;
}

h1 {
font-size: 2em;
}

h2 {

PREPARED BY: MAHMUD BAKALE & ALIJAFAR UMAR


font-size: 1.6em;
}
This sets our base font size for the document to 18px, then says that our <h1> elements
should be twice that size and our <h2>’s should be 1.6 times bigger. If we (or the user)
ever wanted to make the base font bigger or smaller, em units would allow our entire
page to scale accordingly.

SELECTING MULTIPLE ELEMENTS


What if we want to add some styles to all our headings? We don’t want to have
redundant rules, since that would eventually become a nightmare to maintain:
/* (You'll regret creating redundant styles like this) */
h1 {
font-family: "Helvetica", "Arial", sans-serif;
}

h2 {
font-family: "Helvetica", "Arial", sans-serif;
}

h3 {
font-family: "Helvetica", "Arial", sans-serif;
}
/* (etc) */
Instead, we can select multiple HTML elements in the same CSS rule by separating
them with commas. Add this to our [Link] file:
h1, h2, h3, h4, h5, h6 {
font-family: "Helvetica", "Arial", sans-serif;
}
This defines the font to use for all of our headings with a single rule. That’s great, ’cause
if we ever want to change it, we only have to do so in one place. Copying and pasting
code is usually a bad idea for web developers, and multiple selectors can help reduce
that kind of behavior quite a bit.

PREPARED BY: MAHMUD BAKALE & ALIJAFAR UMAR


DEFINING FONTS
Font-family is another built-in CSS property that defines the typeface for whatever
element you selected. It accepts multiple values because not all users will have the same
fonts installed. With the above snippet, the browser tries to load the left-most one first
(Helvetica), falls back to Arial if the user doesn’t have it, and finally chooses the
system’s default sans serif font.

Relying on the user’s built-in fonts has historically been incredibly limiting for web
designers. Nowadays, system fonts have been largely superseded by web fonts. You
can read more about this in the Web Typography chapter of this tutorial.

PREPARED BY: MAHMUD BAKALE & ALIJAFAR UMAR


LIST STYLES
The list-style-type property lets you alter the bullet icon used for <li> elements. You’ll
typically want to define it on the parent <ul> or <ol> element:

ul {
list-style-type: circle;
}

ol {
list-style-type: lower-roman;
}

You can find other common values in the [Link] example page. Of particular
interest is none, which is commonly used when marking up menu navigation with
a <ul> list. The none value allows the menu’s list items to be styled more like buttons.
In the Advanced Positioning chapter, we’ll actually use this technique to create the
navigation menu shown below.

This is good example of the separation of content from presentation. A navigation


menu is an unordered list, but it also makes sense to display them as buttons instead of
a typical bulleted list. Intelligently designed HTML allows search engines to infer the
structure of our content, while CSS lets us display it to humans in beautiful ways.

PREPARED BY: MAHMUD BAKALE & ALIJAFAR UMAR


You can even create custom bullets for <li> elements with the list-style-image property
(see MDN for details).

Defining the color of your text and the appearance of your bullets might seem trivial,
and it kind of is. But, look at the bigger picture: this is about gaining complete control
over the appearance of an HTML document. Alone, a single CSS property is silly. Put
them all together, and you’re able to create a totally customized web page.

REUSABLE STYLESHEETS
So, we just defined some basic styles for one of our web pages. It would be really
convenient if we could reuse them on our other page, too. For this, all we need to do is
add the same <link/> element to any other pages we want to style. Try adding the
following line to the <head> of [Link]:

<link rel='stylesheet' href='[Link]'/>

Now, our [Link] pages should match our [Link] styles. Whenever we
change a style in [Link], those changes will automatically be reflected in both of our
web pages. This is how you get a consistent look and feel across an entire website.

PREPARED BY: MAHMUD BAKALE & ALIJAFAR UMAR


You’ll almost always have at least one stylesheet that’s applied to the entire site. It’s
usually a good idea to use root-relative paths when linking global stylesheets to avoid
problems in nested pages. For example, some-folder/[Link] would need to
use ../[Link] to reference our [Link] file, and this can get real confusing real quick.

MORE TEXT STYLES


There’s a whole bunch of different CSS properties that we’ll be introducing over the
course of this tutorial, but for now, let’s finish up with some of the most common ways
to format text.

UNDERLINES
The text-decoration property determines whether text is underlined or not. By setting it
to none, we can remove the default underline from all of our links. We’ll discuss link
styles in-depth later on.
a{
text-decoration: none;
}

PREPARED BY: MAHMUD BAKALE & ALIJAFAR UMAR


The other common value for text-decoration is line-through to strike out “deleted” text.
But, remember that meaning should always be conveyed through HTML—not CSS.
It’s better to use the <ins> and <del> elements instead of adding a line-through style to,
say, an ordinary <p> element.

TEXT ALIGNMENT
The aptly named text-align property defines the alignment of the text in an HTML
element.
p{
text-align: left;
}
Other accepted values are right, center, or justify, but notice how it always aligns to the
entire page:

This isn’t what you want for most websites. We’ll learn why this is the case in the next
chapter when we start talking about CSS boxes.

FONT WEIGHT AND STYLES


The font-weight property defines the “boldness” of the text in an element, and the font-
style property indicates whether it’s italicized or not.
Let’s say we don’t want our headings to be bold. Update our heading font rule
in [Link] to match the following:

h1, h2, h3, h4, h5, h6 {

PREPARED BY: MAHMUD BAKALE & ALIJAFAR UMAR


font-family: "Helvetica", "Arial", sans-serif;
font-weight: normal; /* Add this */
}
These properties clearly demonstrate the separation of content (HTML) from
presentation (CSS). The following rules swap the appearance of
the <em> and <strong> elements:
/* (You probably shouldn't do this) */
em {
font-weight: bold;
font-style: normal;
}

strong {
font-weight: normal;
font-style: italic;
}
We don’t suggest doing this for real websites though. Font weights and styles will,
however, become a lot more important once we start playing with custom fonts in
the Web Typography chapter.

THE CASCADE
The “cascading” part of CSS is due to the fact that rules cascade down from multiple
sources. So far, we’ve only seen one place where CSS can be defined: external .css files.
However, external stylesheets are just one of many places you can put your CSS code.
The CSS hierarchy for every web page looks like this:

• The browser’s default stylesheet


• User-defined stylesheets
• External stylesheets (that’s us)
• Page-specific styles (that’s also us)

PREPARED BY: MAHMUD BAKALE & ALIJAFAR UMAR


• Inline styles (that could be us, but it never should be)

This is ordered from least to most precedence, which means styles defined in each
subsequent step override previous ones. For example, inline styles will always make
the browser ignore its default styles. The next few sections focus on the last two options
because that’s what we have control over as web developers (in addition to the external
styles we’ve already been working with).

We made an effort to get you started down the right path with external stylesheets. It’s
important to understand page-specific and inline styles because you’ll most definitely
encounter them in the wild, but external stylesheets are by far the best place to define
the appearance of your website.

PREPARED BY: MAHMUD BAKALE & ALIJAFAR UMAR


PAGE-SPECIFIC STYLES
The <style> element is used to add page-specific CSS rules to individual HTML
documents. The <style> element always lives in the <head> of a web page, which
makes sense because it’s metadata, not actual content.

As an example, let’s apply some styles to our [Link] page by updating


its <head> element to this:

<head>
<meta charset='UTF-8'/>
<title>Dummy</title>
<link rel='stylesheet' href='[Link]'/>
<style>
body {
color: #0000FF; /* Blue */
}
</style>
</head>
These apply only to [Link]. Our [Link] page won’t be affected. If you did
it right, you should see bright blue text when you load [Link] in a browser.

Anything you would put in our [Link] file can live in this <style> element. It uses the
exact same CSS syntax as an external stylesheet, but everything here will override rules
in our [Link] file. In this case, we’re telling the browser to ignore the color property
we defined for <body> in our external stylesheet and use #0000FF instead.

PREPARED BY: MAHMUD BAKALE & ALIJAFAR UMAR


The problem with page-specific styles is that they’re incredibly difficult to maintain.
As shown in the above diagram, when you want to apply these styles to another page,
you have to copy-and-paste them into that document’s <head>. Trying to track down
redundant CSS rules in multiple .html files is much harder than editing a single .css file.

Page-specific styles occasionally come in handy when you’re in a rush, but it’s almost
always better to store all your CSS in external stylesheets opposed to <style> elements.

PREPARED BY: MAHMUD BAKALE & ALIJAFAR UMAR


INLINE STYLES
You can also stick CSS rules in the style attribute of an HTML element. In [Link],
we have a link that doesn’t actually go anywhere. Let’s make it red via an inline style
so we remember it’s a dead link:

<p>Want to try crossing out an <a href='[Link]'


style='color: #990000; text-decoration: line-through;'>obsolete link</a>?
This is your chance!</p>

Like page-specific styles, this is the same CSS syntax we’ve been working with.
However, since it’s in an attribute, it needs to be condensed to a single line. Inline styles
are the most specific way to define CSS. The color and text-decoration properties we
defined here trump everything. Even if we went back and added a text-decoration:
none to our <style> element, it wouldn’t have any effect.

Inline styles should be avoided at all costs because they make it impossible to alter
styles from an external stylesheet. If you ever wanted to re-style your website down the
road, you can’t just change a few rules in your global [Link] file—you’d have to go
through every single page and update every single HTML element that has
a style attribute. It’s horrifying.

PREPARED BY: MAHMUD BAKALE & ALIJAFAR UMAR


That said, there will be many times when you need to apply styles to only a specific
HTML element. For this, you should always use CSS classes instead of inline styles.
We’ll explore classes in the CSS Selectors chapter.

MULTIPLE STYLESHEETS
CSS rules can be spread across several external stylesheets by adding
multiple <link/> elements to the same page. A common use case is to separate out styles
for different sections of your site. This lets you selectively apply consistent styles to
distinct categories of web pages.

For instance, if we had a bunch of product pages that looked entirely different than our
blog, we could use the following. (We don’t actually have these stylesheets defined, so
don’t bother adding them to our example project).

<!-- All product pages have this -->


<head>
<link rel='stylesheet' href='[Link]'/>
<link rel='stylesheet' href='[Link]'/>
</head>
<!-- While all blog posts have this -->
<head>
<link rel='stylesheet' href='[Link]'/>
<link rel='stylesheet' href='[Link]'/>
</head>

The order of the <link/> elements matters. Stylesheets that come later will override
styles in earlier ones. Typically, you’ll put your “base” or “default” styles in a global
stylesheet ([Link]) and supplement them with section-specific stylesheets
([Link] and [Link]). This allows you to organize CSS rules into manageable files
while avoiding the perils of page-specific and inline styles.

PREPARED BY: MAHMUD BAKALE & ALIJAFAR UMAR


SUMMARY
We talked a lot about separating content from presentation in this chapter. This not only
allows us to reuse the same CSS stylesheet in multiple HTML documents, but also lets
us conditionally apply different CSS rules to the same HTML content, depending on
whether the user is on a mobile phone, tablet, or desktop computer. This latter part is
called Responsive Design.

As a web developer, you’ll (hopefully) be given a polished design to work off of. Your
job is to turn that mockup into a real web page leveraging your knowledge of CSS. As
we mentioned earlier, setting individual CSS properties is actually quite simple. The
hard part is combining the overwhelming number of built-in properties to create exactly
what your web designer asked for—and do it quickly.

This chapter focused mostly on text formatting, but the Cascading Style Sheet language
can do a whole lot more. In the next chapter, we’ll start exploring how CSS defines the
layout of our web pages. On a final note, remember that you can always refer to MDN’s
CSS Reference when you’re not sure how a particular property works.

PREPARED BY: MAHMUD BAKALE & ALIJAFAR UMAR


CSS BOX MODEL
Nº 5. of HTML & CSS Is Hard
A friendly introduction to padding, borders, and margins

The previous chapter introduced the basic text formatting properties of CSS, but that
was only one aspect of styling pages. Defining the layout of a web page is an entirely
different beast. That’s what this chapter is about.

The “CSS box model“ is a set of rules that define how every web page on the Internet
is rendered. CSS treats each element in your HTML document as a “box” with a bunch

PREPARED BY: MAHMUD BAKALE & ALIJAFAR UMAR


of different properties that determine where it appears on the page. So far, all of our
web pages have just been a bunch of elements rendered one after another. The box
model is our toolkit for customizing this default layout scheme.

A big part of your job as a web developer will be to apply rules from the CSS box model
to turn a design mockup into a web page. As you work through this chapter, you might
find yourself wondering why we have to learn all these rules instead of just uploading
a giant static image of a web page (i.e., a mockup) to a web server and calling it a day.

Indeed, this would make life a lot easier; however, if we didn’t separate out our content
into HTML, search engines would have no way to infer the structure of our web pages,
we couldn’t make our site responsive, and there would be no way to add fancy
animations or interactivity with JavaScript. That’s a big enough trade-off to make CSS
a worthwhile cause.

This chapter covers the core components of the CSS box model: padding, borders,
margins, block boxes, and inline boxes. You can think of this as the “micro” view of
CSS layouts, as it defines the individual behavior of boxes. In future chapters, we’ll

PREPARED BY: MAHMUD BAKALE & ALIJAFAR UMAR


learn more about how HTML structure and the CSS box model combine to form all
sorts of complex page layouts.

SETUP
To get started, let’s create a new folder called css-box-model and stick a new web page
in it called [Link]. Add the following code:

<!DOCTYPE html>
<html lang='en'>
<head>
<meta charset='UTF-8'/>
<title>Boxes Are Easy!</title>
<link rel='stylesheet' href='[Link]'/>
</head>
<body>
<h1>Headings Are Block Elements</h1>

<p>Paragraphs are blocks, too. <em>However</em>, &lt;em&gt; and &lt;strong&gt;


elements are not. They are <strong>inline</strong> elements.</p>

<p>Block elements define the flow of the HTML document, while inline elements
do not.</p>
</body>
</html>
As you should remember from Hello, CSS, this HTML file links to a CSS stylesheet
stored in a file called [Link]. Go ahead and create this file, too (you can leave it
empty for now).

Hopefully, you should be very familiar using Atom for these kinds of file and folder
creation tasks. If not, be sure to review the Atom walkthrough in the introductory
chapter of this tutorial.

PREPARED BY: MAHMUD BAKALE & ALIJAFAR UMAR


BLOCK ELEMENTS AND INLINE ELEMENTS
Back in Basic Web Pages, we briefly touched on how CSS uses “boxes” to define the
layout of a web page. Each HTML element rendered on the screen is a box, and they
come in two flavors: “block” boxes and “inline“ boxes.

All the HTML elements that we’ve been working with have a default type of box. For
instance, <h1> and <p> are block-level elements, while <em> and <strong> are inline
elements. Let’s get a better look at our boxes by adding the following to [Link]:
h1, p {
background-color: #DDE0E3; /* Light gray */
}

em, strong {
background-color: #B2D6FF; /* Light blue */
}
The background-color property only fills in the background of the selected box, so this
will give us a clear view into the structure of the current sample page. Our headings and
paragraphs should have gray backgrounds, while our emphasis and strong elements
should be light blue.

PREPARED BY: MAHMUD BAKALE & ALIJAFAR UMAR


This shows us a couple of very important behaviors associated with block and inline
boxes:
• Block boxes always appear below the previous block element. This is the
“natural” or “static” flow of an HTML document when it gets rendered by a
web browser.
• The width of block boxes is set automatically based on the width of its parent
container. In this case, our blocks are always the width of the browser
window.
• The default height of block boxes is based on the content it contains. When
you narrow the browser window, the <h1> gets split over two lines, and its
height adjusts accordingly.
• Inline boxes don’t affect vertical spacing. They’re not for determining
layout—they’re for styling stuff inside of a block.
• The width of inline boxes is based on the content it contains, not the width of
the parent element.

CHANGING BOX BEHAVIOR


We can override the default box type of HTML elements with the CSS display property.
For example, if we wanted to make our <em> and <strong> elements blocks instead of
inline elements, we could update our rule in [Link] like so:

PREPARED BY: MAHMUD BAKALE & ALIJAFAR UMAR


em, strong {
background-color: #B2D6FF;
display: block;
}
Now, these elements act like our headings and paragraphs: they start on their own line,
and they fill the entire width of the browser. This comes in handy when you’re trying
to turn <a> elements into buttons or format <img/> elements (both of these are inline
boxes by default).

However, it’s almost never a good idea to turn <em> and <strong> into block elements,
so let’s turn them back into inline boxes by changing their display property to inline,
like so:
em, strong {
background-color: #B2D6FF;
display: inline; /* This is the default for em and strong */
}

CONTENT, PADDING, BORDER, AND MARGIN


The “CSS box model” is a set of rules that determine the dimensions of every element
in a web page. It gives each box (both inline and block) four properties:

• Content – The text, image, or other media content in the element.


• Padding – The space between the box’s content and its border.

PREPARED BY: MAHMUD BAKALE & ALIJAFAR UMAR


• Border – The line between the box’s padding and margin.
• Margin – The space between the box and surrounding boxes.

Together, this is everything a browser needs to render an element’s box. The content is
what you author in an HTML document, and it’s the only one that has any semantic
value (which is why it’s in the HTML). The rest of them are purely presentational, so
they’re defined by CSS rules.

PADDING
Let’s start from the inside out. We’ve already been working with content, so on to
padding. The padding property…you guessed it…defines the padding for the selected
element:
h1 {
padding: 50px;
}

PREPARED BY: MAHMUD BAKALE & ALIJAFAR UMAR


This adds 50 pixels to each side of the <h1> heading. Notice how the background color
expands to fill this space. That’s always the case for padding because it’s inside the
border, and everything inside the border gets a background.

Sometimes you’ll only want to style one side of an element. For that, CSS provides the
following properties:
p{
padding-top: 20px;
padding-bottom: 20px;
padding-left: 10px;
padding-right: 10px;
}
You can use any unit for the padding of an element, not just pixels. Again, em units are
particularly useful for making your margins scale with the base font size.

SHORTHAND FORMATS
Typing out all of these properties out can be tiresome, so CSS provides an alternative
“shorthand” form of the padding property that lets you set the top/bottom and left/right
padding with only one line of CSS. When you provide two values to
the padding property, it’s interpreted as the vertical and horizontal padding values,
respectively.

PREPARED BY: MAHMUD BAKALE & ALIJAFAR UMAR


This means that our previous rule can be rewritten as:
p{
padding: 20px 10px; /* Vertical Horizontal */
}
Alternatively, if you provide four values, you can set the padding for each side of an
element individually. The values are interpreted clockwise, starting at the top:

PREPARED BY: MAHMUD BAKALE & ALIJAFAR UMAR


Let’s try this out by removing the 10px right padding from the previous rule. This
should give us 20 pixels on the top and bottom of each paragraph, 10 pixels on the left,
but none on the right:
p{
padding: 20px 0 20px 10px; /* Top Right Bottom Left */
}
Whether or not you want to use shorthand forms or not is largely a matter of personal
preference and team conventions. Some developers like the fact that the shorthand form
is more condensed, while others think the long form is easier to understand at a glance
(and thus easier to maintain). Regardless, you’ll likely encounter all of them at some
point in your web development career.

BORDERS
Continuing our journey outward from the center of the CSS box model, we have the
border: a line drawn around the content and padding of an element. The border property
requires a new syntax that we’ve never seen before. First, we define the stroke width of
the border, then its style, followed by its color.

PREPARED BY: MAHMUD BAKALE & ALIJAFAR UMAR


Try adding a border around our <h1> heading by updating the rule in [Link]:
h1 {
padding: 50px;
border: 1px solid #5D6063;
}
This tells the browser to draw a thin gray line around our heading. Notice how the
border bumps right up next to the padding with no space in between. And, if you shrink
your browser enough for the heading to be split over two lines, both the padding and
the border will still be there.

Drawing a border around our entire heading makes it look a little 1990s, so how about
we limit it to the bottom of the heading? Like padding, there are -top, -bottom, -left,
and -right variants for the border property:
border-bottom: 1px solid #5D6063;

PREPARED BY: MAHMUD BAKALE & ALIJAFAR UMAR


Borders are common design elements, but they’re also invaluable for debugging. When
you’re not sure how a box is being rendered, add a border: 1px solid red; declaration to
it. This will clearly show the box’s padding, margin, and overall dimensions with just
a single line of CSS. After you figured out why your stuff is broken, simply delete the
rule.

Please refer to the Mozilla Developer Network for more information about border
styles.

MARGINS
Margins define the space outside of an element’s border. Or, rather, the space between
a box and its surrounding boxes. Let’s add some space to the bottom of
each <p> element:
p{
padding: 20px 0 20px 10px;
margin-bottom: 50px; /* Add this */
}
This demonstrates a side-specific variant of the margin property, but it also accepts the
same shorthand formats as padding.

Margins and padding can accomplish the same thing in a lot of situations, making it
difficult to determine which one is the “right” choice. The most common reasons why
you would pick one over the other are:

• The padding of a box has a background, while margins are always transparent.
• Padding is included in the click area of an element, while margins aren’t.
• Margins collapse vertically, while padding doesn’t (we’ll discuss this more in
the next section).

PREPARED BY: MAHMUD BAKALE & ALIJAFAR UMAR


If none of these help you decide whether to use padding over margin, then don’t fret
about it—just pick one. In CSS, there’s often more than one way to solve your problem.

MARGINS ON INLINE ELEMENTS


One of the starkest contrasts between block-level elements and inline ones is their
handling of margins. Inline boxes completely ignore the top and bottom margins of an
element. For example, watch what happens when we add a big margin to
our <strong> element:
strong {
margin: 50px;
}
The horizontal margins display just like we’d expect, but this doesn’t alter the vertical
space around our <strong> element one bit.

If we change margin to padding, we’ll discover that this isn’t exactly the case for a box’s
padding. It’ll display the blue background; however, it won’t affect the vertical layout
of the surrounding boxes.

PREPARED BY: MAHMUD BAKALE & ALIJAFAR UMAR


The rationale behind this goes back to the fact that inline boxes format runs of text
inside of a block, and thus have limited impact on the overall layout of a page. If you
want to play with the vertical space of a page, you must be working with block-level
elements (luckily, we already know how to change an element’s box type).

So, before you start banging your head against the wall trying to figure out why your
top or bottom margin isn’t working, remember to check your display property. Trust us,
this will happen to you eventually.

VERTICAL MARGIN COLLAPSE


Another quirk of the CSS box model is the “vertical margin collapse”. When you have
two boxes with vertical margins sitting right next to each other, they will collapse.
Instead of adding the margins together like you might expect, only the biggest one is
displayed.

For example, let’s add a top margin of 25 pixels to our <p> element:
p{
padding: 20px 0 20px 10px;

margin-top: 25px;

PREPARED BY: MAHMUD BAKALE & ALIJAFAR UMAR


margin-bottom: 50px;
}
Each paragraph should have 50 pixels on the bottom, and 25 pixels on the top. That’s
75 pixels between our <p> elements, right? Wrong! There’s still only going to
be 50px between them because the smaller top margin collapses into the bigger bottom
one.

This behavior can be very useful when you’re working with a lot of different kinds of
elements, and you want to define their layout as the minimum space between other
elements.

PREVENTING MARGIN COLLAPSE


It can also be really annoying. Sometimes you do want to prevent the margins from
collapsing. All you need to do is put another invisible element in between them:

<p>Paragraphs are blocks, too. <em>However</em>, &lt;em&gt; and &lt;strong&gt;


elements are not. They are <strong>inline</strong> elements.</p>

<div style='padding-top: 1px'></div> <!-- Add this -->

<p>Block elements define the flow of the HTML document, while inline elements

PREPARED BY: MAHMUD BAKALE & ALIJAFAR UMAR


do not.</p>

We’ll talk more about the <div> element in the next section. The important part here is
that only consecutive elements can collapse into each other. Putting an element with
non-zero height (hence the padding-top) between our paragraphs forces them to display
both the 25px top margin and the 50px bottom margin.

Remember that padding doesn’t ever collapse, so an alternative solution would be to


use padding to space out our paragraphs instead of the margin property. However, this
only works if you’re not using the padding for anything else (at the moment, we are, so
let’s stick to the <div> option).

A third option to avoid margin collapse is to stick to a bottom-only or top-only margin


convention. For instance, if all your elements only define a bottom margin, there’s no
potential for them to collapse.

Finally, the flexbox layout scheme doesn’t have collapsing margins, so this isn’t really
even an issue for modern websites.

PREPARED BY: MAHMUD BAKALE & ALIJAFAR UMAR


GENERIC BOXES
So far, every HTML element we’ve seen lends additional meaning to the content it
contains. Indeed, this is the whole point of HTML, but there are many times when we
need a generic box purely for the sake of styling a web page. This is
what <div> and <span> are for.

Both <div> and <span> are “container” elements that don’t have any affect on the
semantic structure of an HTML document. They do, however, provide a hook for
adding CSS styles to arbitrary sections of a web page. For example, sometimes you
need to add an invisible box to prevent a margin collapse, or maybe you want to group
the first few paragraphs of an article into a synopsis with slightly different text
formatting.

We’ll use a lot of <div>’s throughout the rest of this tutorial. For now, let’s create a
simple button by adding the following to the bottom of our [Link] file:

<div>Button</div>

And here are the associated styles that need to go into [Link]. Most of these
should be familiar from the last chapter, although we did throw in a new border-
radius property:

div {
color: #FFF;
background-color: #5995DA;
font-weight: bold;
padding: 20px;
text-align: center;
border: 2px solid #5D6063;

PREPARED BY: MAHMUD BAKALE & ALIJAFAR UMAR


border-radius: 5px;
}

This will give us a big blue button that spans the entire width of the browser:

Of course, these styles also apply to the invisible <div> we used to break the margin
collapse in the previous section. Obviously, we need a way to select individual <div>’s
if they’re to be of any practical use to us. That’s what class selectors are for, which we’ll
introduce in the next chapter. In lieu of those, let’s just delete or comment out that
invisible <div>.

The only real difference between a <div> and a <span> is that the former is for block-
level content while the latter is meant for inline content.

PREPARED BY: MAHMUD BAKALE & ALIJAFAR UMAR


EXPLICIT DIMENSIONS
So far, we’ve let our HTML elements define their dimensions automatically. The
paddings, borders, and margins we’ve been playing with all wrap around whatever
content happens to be inside the element’s box. If you add more text to
our <em> element, everything will expand to accommodate it:

But, sometimes our desired layout calls for an explicit dimension, like a sidebar that’s
exactly 250 pixels wide. For this, CSS provides the width and height properties. These
take precedence over the default size of a box’s content.

Let’s give our button an explicit width by adding the following property to box-
[Link]:
div {
/* [Existing Declarations] */
width: 200px;
}

PREPARED BY: MAHMUD BAKALE & ALIJAFAR UMAR


Instead of being as wide as the browser window, our button is now 200 pixels, and it
hugs the left side of the page:

Also notice that if you make the button’s title longer, it will automatically wrap to the
next line, and the element will expand vertically to accommodate the new content. You
can change this default behavior with the white-space and overflow properties.

CONTENT BOXES AND BORDER BOXES


The width and height properties only define the size of a box’s content. Its padding and
border are both added on top of whatever explicit dimensions you set. This explains
why you’ll get an image that’s 244 pixels wide when you take a screenshot of our
button, despite the fact that it has a width: 200px declaration attached to it.

PREPARED BY: MAHMUD BAKALE & ALIJAFAR UMAR


Needless to say, this can be a little counterintuitive when you’re trying to lay out a page.
Imagine trying to fill a 600px container with three boxes that are all width: 200px, but
they don’t fit because they all have a 1px border (making their actual width 202px).

Fortunately, CSS lets you change how the width of a box is calculated via the box-
sizing property. By default, it has a value of content-box, which leads to the behavior
described above. Let’s see what happens when we change it to border-box:
div {
color: #FFF;
background-color: #5995DA;
font-weight: bold;
padding: 20px;
text-align: center;
border: 2px solid #5D6063;
border-radius: 5px;
width: 200px;
box-sizing: border-box; /* Add this */
}
This forces the actual width of the box to be 200px—including padding and borders. Of
course, this means that the content width is now determined automatically:

PREPARED BY: MAHMUD BAKALE & ALIJAFAR UMAR


This is much more intuitive, and as a result, using border-box for all your boxes is
considered a best practice among modern web developers.

ALIGNING BOXES
Aligning boxes horizontally is a common task for web developers, and the box model
offers a lot of ways to do it. We already saw the text-align property, which aligns the
content and inline boxes inside of a block-level element. Aligning block boxes is
another story.

Try adding the following rule to our stylesheet. It will only align the content inside of
our block boxes—not the blocks themselves. Our <div> button is still left-aligned
regardless of the <body>’s text alignment:
body {
text-align: center;

PREPARED BY: MAHMUD BAKALE & ALIJAFAR UMAR


}
There are three methods for horizontally aligning block-level elements: “auto-margins”
for center alignment, “floats” for left/right alignment, and “flexbox” for complete
control over alignment. Yes, unfortunately block-level alignment is totally unrelated to
the text-align property.

CENTERING WITH AUTO-MARGINS


Floats and flexbox are complicated topics that we’ve devoted entire chapters to, but we
do have the background to deal with auto-margins right now. When you set the left and
right margin of a block-level element to auto, it will center the block in its parent
element.

For example, we can center our button with the following:


div {
color: #FFF;
background-color: #4A90E2;
font-weight: bold;
padding: 20px;
text-align: center;
width: 200px;
box-sizing: border-box;
margin: 20px auto; /* Vertical Horizontal */
}
Note that this only works on blocks that have an explicit width defined on them.
Remove that width: 200px line, and our button will be the full width of the browser,
making “center alignment” meaningless.

PREPARED BY: MAHMUD BAKALE & ALIJAFAR UMAR


RESETTING STYLES
Notice that white band around our page? That’s a default margin/padding added by your
browser. Different browsers have different default styles for all of their HTML
elements, making it difficult to create consistent stylesheets.

It’s usually a good idea to override default styles to a predictable value using the
“universal” CSS selector (*). Try adding this to the top of our [Link] file:
*{
margin: 0;
padding: 0;
box-sizing: border-box;
}
This selector matches every HTML element, effectively resetting
the margin and padding properties for our web page. We also converted all our boxes
to border-box, which, again, is a best practice.

You’ll find a similar reset at the top of almost every global CSS stylesheet on the web.
They can get a whole lot more complicated, but the three simple declarations shown

PREPARED BY: MAHMUD BAKALE & ALIJAFAR UMAR


above allow us to confidently tweak the CSS box model for our own purposes without
worrying about unforeseen interactions with default browser styles.

SUMMARY
We’ll learn more about the practical uses of the CSS box model as we get deeper into
constructing complex web pages. For now, think of it as a new tool in your CSS toolbox.
With a few key concepts from this chapter, you should feel much more equipped to
convert a design mockup into a real-life web page:

• Everything is a box.
• Boxes can be inline or block-level.
• Boxes have content, padding, borders, and margins.
• They also have seemingly arbitrary rules about how they interact.
• Mastering the CSS box model means you can lay out most web pages.

Like the last chapter, the CSS properties we just covered might seem simple—and they
sort of are. But, start looking at the websites you visit through the lens of the CSS box
model, and you’ll see this stuff literally everywhere.

Our exploration of generic boxes (<div> and <span>) was a little bit limited because we
didn’t have a way to pluck out an individual HTML element from our web page. We’ll
fix that in the next chapter with a more in-depth discussion of CSS selectors.

PREPARED BY: MAHMUD BAKALE & ALIJAFAR UMAR


CSS SELECTORS

Nº 6. of HTML & CSS Is Hard


A friendly web development tutorial for plucking out HTML elements

Way back in the Links and Images chapter, we learned how to connect an HTML
document to other files in our project. “CSS selectors” are similar, except instead of
navigating between whole files, they let us map a single CSS rule to a specific HTML
element. This makes it possible to selectively style individual elements while ignoring
others.

Unless you want every section of your website to look exactly the same, this is a crucial
bit of functionality for us. It’s how we say things like “I want this paragraph to be blue
and that other paragraph to be yellow.” Until now, we’ve only been able to turn all our
paragraphs blue (or yellow).

The only CSS selector we’ve seen so far is called the “type selector”, which targets all
the matching elements on a page. In this chapter, we’ll explore more granular ways to
style a web page with class selectors, descendant selectors, pseudo-classes, and ID
selectors.

SETUP
We’ll only need one HTML file and a CSS stylesheet for our example this chapter.
Create a new folder called css-selectors and new web page called [Link] with the
following markup:
<!DOCTYPE html>

PREPARED BY: MAHMUD BAKALE & ALIJAFAR UMAR


<html lang='en'>
<head>
<meta charset='UTF-8'/>
<title>CSS Selectors</title>
<link rel='stylesheet' href='[Link]'/>
</head>
<body>
<h1>CSS Selectors</h1>
<p>CSS selectors let you <em>select</em> individual HTML elements in an HTML
document. This is <strong>super</strong> useful.</p>
<p>Classes are ridiculously important, since they allow you to select
arbitrary boxes in your web pages.</p>
<p>We’ll also be talking about links in this example, so here’s
<a href='[Link] Is Hard</a> for us to
style.</p>
<div>Button One</div>
</body>
</html>

Go ahead and create that [Link] stylesheet in the same folder, too. This gives us
everything we need to explore CSS selectors.

If you’re just diving into this tutorial series, be sure to have a quick read through
the Introduction to get set up with the Atom text editor.

CLASS SELECTORS
“Class selectors” let you apply CSS styles to a specific HTML element. They let you
differentiate between HTML elements of the same type, like when we had
two <div> elements in the previous chapter, but only wanted to style one of them. Class
selectors require two things:
• A class attribute on the HTML element in question.
• A matching CSS class selector in your stylesheet.

PREPARED BY: MAHMUD BAKALE & ALIJAFAR UMAR


We can use a class selector to style the first paragraph of our example page differently
than the rest of them. This could be, for instance, the synopsis of a newspaper article.
First, let’s add a class attribute to the desired paragraph:
<p class='synopsis'>CSS selectors let you <em>select</em> individual HTML
elements in an HTML document. This is <strong>super</strong> useful.</p>
Now, we can pluck out that <p class='synopsis'> element in our CSS with the following
(add this to [Link]):
.synopsis {
color: #7E8184; /* Light gray */
font-style: italic;
}
This rule is only applied to elements with the corresponding class attribute. Notice the
dot (.) prefixing the class name. This distinguishes class selectors from the type
selectors that we’ve been working with before this chapter.

PREPARED BY: MAHMUD BAKALE & ALIJAFAR UMAR


CLASS NAMING CONVENTIONS
The value of the HTML class attribute can be (almost) anything you want as long as it
matches the selector in your CSS. The standard naming convention for classes is to use
all lowercase and hyphens for spaces, just like file and folder names.

Adding a class attribute doesn’t alter the semantic meaning of your HTML document at
all—it’s purely for hooking into your CSS stylesheet. However, it’s still usually a good
idea to avoid naming classes based on their appearance. If we chose to name our
class .italic, we wouldn’t be able to do much besides make it italic in our CSS without
leading to a confusing situation. Using something semantic like .synopsis gives us more
freedom for our CSS to customize how that synopsis is displayed.

MORE USEFUL DIVS


The class attribute isn’t limited to <p> elements—it can be defined on any HTML
element. So, armed with CSS class selectors, our generic <div> and <span> boxes from
the previous chapter become much, much more useful. We can use them to style both
individual elements as well as arbitrary sections of our web page.

PREPARED BY: MAHMUD BAKALE & ALIJAFAR UMAR


Let’s start with individual elements by recreating our button from the previous chapter.
This time, we’ll use a class instead of a div selector. Add the following to [Link]:
.button {
color: #FFF;
background-color: #5995DA; /* Blue */
font-weight: bold;
padding: 20px;
text-align: center;
border: 2px solid #5D6063; /* Dark gray */
border-radius: 5px;
width: 200px;
margin: 20px auto;
}
Of course, we need a corresponding class attribute for this to work. Change
the <div> in [Link] to match the following:
<div class='button'>Button One</div>
Unlike the previous chapter that styled all the <div> elements, this lets us use it for
other things besides buttons.

PREPARED BY: MAHMUD BAKALE & ALIJAFAR UMAR


CONTAINER DIVS
Remember that <div> doesn’t alter the semantic structure of a page. This makes it a
great tool for defining the presentational structure of a web page. By wrapping other
HTML elements in <div> tags, we can organize our site into larger layout-oriented
chunks without messing up how search engines view our content.

For example, let’s try to create a fixed-width layout using the auto-margin
technique that we learned in the previous chapter. First, wrap our entire document in a
generic <div> and give it a unique class:
<body>
<div class='page'> <!-- Add this -->
<h1>CSS Selectors</h1>
<p class='synopsis'>CSS selectors let you <em>select</em> individual HTML
elements in an HTML document. This is <strong>super</strong> useful.</p>
<p>Classes are ridiculously important, since they allow you to select
arbitrary boxes in your web pages.</p>
<p>We’ll also be talking about links in this example, so here’s
<a href='[Link] Is Hard</a> for us to
style.</p>
<div class='button'>Button One</div>
</div> <!-- And this -->
</body>
Then, add the following to [Link]:
.page {

PREPARED BY: MAHMUD BAKALE & ALIJAFAR UMAR


width: 600px;
margin: 0 auto;
}
No matter how you resize the browser window, our web page will always be 600 pixels
wide and centered in the available space. Note that this was the exact same way we
centered our button, but now we’re doing it to multiple elements at the same time by
nesting them in a generic container.

This is how layouts are defined in more complex web pages. For instance, if our page
had a sidebar, we would nest all the sidebar elements in another <div> with
a .sidebar class. We’ll see this in action in the next chapter. For now, the key takeaway
is that without class selectors to differentiate our <div> elements, none of this would be
possible.

REUSING CLASS STYLES


The same class can be applied to multiple elements in a single HTML document. This
means that we can now reuse arbitrary CSS declarations wherever we want. To create
another button, all we have to do is add another HTML element with the same class:
<div class='button'>Button One</div>

PREPARED BY: MAHMUD BAKALE & ALIJAFAR UMAR


<div class='button'>Button Two</div>

This gives us a second button that looks just like the first one—without writing a
single line of CSS! Organizing similar graphical elements into reusable CSS rules
like this makes life much easier as a web developer. If we ever wanted to, say, change
the button color, we would only have to do it in one place and all our buttons would
automatically update.

MODIFYING CLASS STYLES


What if we want to alter our second button a little bit? Fortunately, we can apply
multiple classes to the same HTML element, too. The styles from each class will be
applied to the element, giving us the opportunity to both reuse styles from .button and
override some of them with a new class.

PREPARED BY: MAHMUD BAKALE & ALIJAFAR UMAR


Go ahead and add another class to our second button with the following markup. Notice
how multiple classes live in the same class attribute, separated by spaces:
<div class='button call-to-action'>Button Two</div>
This element now has two separate classes, and we can use either of them to style it.
This opens up some options. Styles shared by both buttons can live in the .button class
(as they already do), and styles specific to the second button reside in the .call-to-
action class (be sure to add this after the .button rule):

.call-to-action {
font-style: italic;
background-color: #EEB75A; /* Yellow */
}

ORDER MATTERS
There’s a couple of important things going on with our second button now:
• It’s adding a new font-style declaration to the original .button rule.
• It’s overriding an existing background-color style from .button.
Overriding occurs because of the order of .call-to-action and .button in our stylesheet.
When there’s two conflicting properties in a CSS file, the last one is always the one that
gets applied. So, if you moved .call-to-action to the top of [Link], .button would have
the final word on the value of background-color, and it would remain blue.

This means that the order of the class attribute in our HTML element has no effect on
override behavior. Multiple classes on a single element are applied “equally” (for lack
of a better term), so the precedence is determined solely by the order of the rules
in [Link]. In other words, the following elements are effectively equivalent:
<!-- These result in the same rendered page -->
<div class='button call-to-action'>Button Two</div>
<div class='call-to-action button'>Button Two</div>

PREPARED BY: MAHMUD BAKALE & ALIJAFAR UMAR


This does, however, get more complicated when CSS specificity is involved, which
we’ll discuss at the end of this chapter.

DESCENDANT SELECTORS
You may have noticed that the <em> in our first paragraph is no longer distinguishable
from its surround text, since our .synopsis rule made everything italic.

To alter that <em> element, we could add another class directly to it, but that won’t
result in very maintainable code. We want to treat .synopsis as its own independent
component that we can style entirely from CSS (i.e., without requiring alterations to our
HTML just for the sake of styling something.)

PREPARED BY: MAHMUD BAKALE & ALIJAFAR UMAR


This is what “descendant selectors” are for. They let you target only those elements that
are inside of another element. For example, we can pull out that <em> in
the .synopsis paragraph with the following:
.synopsis em {
font-style: normal;
}
Adding this rule to [Link] will make the <em> display as upright (roman) characters,
thus differentiating it from the italics we put on the entire <p> text. The rest of
the <em> elements on the page will be unaffected.

Descendant selectors aren’t limited to class selectors—you can combine any other
group of selectors this way. For instance, if we wanted to select only <em> elements
inside of headings, we might use something like this:
h1 em {
/* Some other styles */
}
Again, the goal of this chapter is to let you apply styles to exactly the element you want.
Descendant selectors are a great tool towards this end. You may also want to check out
the related “child selector” over at MDN if you’ve still got room in your toolbox.

DON’T OVERDO IT
You can nest descendant selectors as deep as you want, but don’t get carried away. Life
gets confusing and terrible when you start writing rules that look like this:

PREPARED BY: MAHMUD BAKALE & ALIJAFAR UMAR


/* Try to avoid this */
.article h2 .subheading em {
/* Special styles */
}
This isn’t the least bit reusable because it matches only the following HTML
structure:
<div class='article'>
<h2>
<span class='.subheading'>This is <em>really</em> special text</span>
</h2>
</div>
If you ever wanted to apply these styles to an <h2> heading that’s not wrapped in <div
class='article'> tags, you’re kind of screwed. Same deal if you want to apply them to
an <h3> heading anywhere on the page. This kind of CSS also leads to
a specificity nightmare.

PSEUDO-CLASSES FOR LINKS


So far, all the CSS selectors we’ve seen map directly to a piece of HTML markup that
we wrote. However, there’s more going on in a rendered web page than just our HTML
content. There’s “stateful” information about what the user is doing (opposed to the
content we’ve authored).

The classic example is a link. As a web developer, you create an <a href> element. After
the browser renders it, the user can interact with that link. They can hover over it, click
it, and visit the URL.

PREPARED BY: MAHMUD BAKALE & ALIJAFAR UMAR


CSS “pseudo-classes” provide a mechanism for hooking into this kind of temporary
user information. At any given time, an <a href> element can be in a number of different
states, and you can use pseudo-classes to style each one of them individually. Think of
them as class selectors that you don’t have to write on your own because they’re built
into the browser.

BASIC LINK STYLES


Pseudo-classes begin with a colon followed by the name of the desired class. The most
common link pseudo-classes are as follows:
• :link – A link the user has never visited.
• :visited – A link the user has visited before.
• :hover – A link with the user’s mouse over it.
• :active – A link that’s being pressed down by a mouse (or finger).
Let’s take a look at all of these by adding the following rules to our CSS stylesheet (also
note our use of keyword colors instead of our usual hex codes):

a:link {
color: blue;
text-decoration: none;
}
a:visited {
color: purple;
}
a:hover {

PREPARED BY: MAHMUD BAKALE & ALIJAFAR UMAR


color: aqua;
text-decoration: underline;
}
a:active {
color: red;
}
If you’ve never been to the [Link] home page, you should see a blue
link. Otherwise, you’ll see a purple link. When you hover over the link, it will turn aqua,
and when you push down on it, it’ll turn red.

VISITED HOVER STATE


The above snippet is just fine for most websites, but take a closer look at
the a:visited behavior by changing the href attribute to a URL that you’ve been to
before. Our a:hover style is applied to both visited and unvisited links. We can refine
our links even more by stringing pseudo-classes together. Add this below the previous
snippet:
a:visited:hover {
color: orange;
}
This creates a dedicated hover style for visited links. Hovering over an unvisited link
changes it to aqua, while hovering over a visited link will turn it orange. Fantastic!
Except for the fact that this breaks our a:active style due to some complicated CSS
internals that you’ll never want to read about. When you click down, our link won’t
turn red anymore.

VISITED ACTIVE STATE


We can fix that with a:visited:active. Add the following to the end of our stylesheet.
Note that, as with our .call-to-action class, the order in which these are defined
in [Link] matters:

PREPARED BY: MAHMUD BAKALE & ALIJAFAR UMAR


a:visited:active {
color: red;
}
These last two sections let you style visited links entirely separately from unvisited
ones. It’s a nice option to have, but again, you’re welcome to stop at basic link styles if
that’s all you need.

PSEUDO-CLASSES FOR BUTTONS


Pseudo-classes aren’t just for styling text links—they can be applied to any kind of
selector (not just type selectors). Instead of styling a:link and friends, we’ll be
modifying our .button class with pseudo-classes in this section. This will let us create
buttons that actually go somewhere.

LINK ELEMENTS, NOT DIV ELEMENTS


First, we need change our buttons to be <a href> elements instead of
generic <div> elements, as shown below:
<a class='button' href='[Link]'>Button One</a>
<a class='button call-to-action' href='[Link]'>Button Two</a>
If you reload this in your browser, you’ll see that we lost some of our styles even though
we’re using the same classes. This is because <a> is an inline element by default and
also has a default color value.

PREPARED BY: MAHMUD BAKALE & ALIJAFAR UMAR


We need to change it to a block element and remove some of the default link styling.

BUTTON STYLES
Let’s start with :link and :visited variants. We’re using a similar pattern as in the
previous section, but since these are buttons, we want to keep both the unvisited and
visited color the same. Change the existing .button rules to match the following:
.button:link, /* Change this */
.button:visited { /* Change this */
display: block; /* Add this */
text-decoration: none; /* Add this */
color: #FFF; /* The rest is the same */
background-color: #5995DA;
font-weight: bold;
padding: 20px;
text-align: center;
border: 2px solid #5D6063;
border-radius: 5px;
width: 200px;
margin: 20px auto;
}

PREPARED BY: MAHMUD BAKALE & ALIJAFAR UMAR


Notice the new :link and :visited pseudo-classes in the selector. Without it,
our color would not override the browser’s default a:link style. CSS specificity explains
why this is the case in greater detail. Next, let’s do the hover states:
.button:hover,
.button:visited:hover {
color: #FFF;
background-color: #76AEED; /* Light blue */
}
Both our buttons will be a lighter blue on hover. Finally, let’s make it a little darker
when the user presses the mouse down with the :active pseudo-class:
.button:active,
.button:visited:active {
color: #FFF;
background-color: #5995DA; /* Blue */
}
The great part about this is that all the styles we just defined are entirely reusable. Stick
a .button class on any HTML element, and you’ll turn it into an interactive button.

THE OTHER BUTTON


Now, what about that second button? It’s supposed to have a yellow background, but
we broke it with the code from the previous section. Our. button:link selector was more
“specific” than our current .call-to-action rule, so it took precedence. Again, we’ll
explore this further at the end of the chapter.
For now, let’s fix it by applying some pseudo-classes to our .call-to-action rule. Replace
the existing rule with the following (make sure this appears after the new .button styles
from the previous section):
.call-to-action:link,
.call-to-action:visited {
font-style: italic;
background-color: #EEB75A; /* Yellow */
}

PREPARED BY: MAHMUD BAKALE & ALIJAFAR UMAR


.call-to-action:hover,
.call-to-action:visited:hover {
background-color: #F5CF8E; /* Light yellow */
}

.call-to-action:active,
.call-to-action:visited:active {
background-color: #EEB75A; /* Yellow */
}
Since we only added the .call-to-action class to our second button, that’s the only one
that’ll turn yellow. Of course, we still need the .button class on both <a> elements
because it defines shared styles like the padding, border radius, and font weight.

PSEUDO-CLASSES FOR STRUCTURE


Link states are just one aspect of pseudo-classes. There’s also a bunch of other pseudo-
classes that provide extra information about an element’s surroundings. For example,
the :last-of-type pseudo-class selects the final element of a particular type in its parent
element. This gives us an alternative to class selectors for selecting specific elements.
For instance, we could use :last-of-type to add some space after the last paragraph of
our example page:
p:last-of-type {
margin-bottom: 50px;
}
This avoids selecting the first two <p> elements without requiring a new class attribute
on the last paragraph:

PREPARED BY: MAHMUD BAKALE & ALIJAFAR UMAR


We could even use a :first-of-type pseudo-class in place of our .synopsis class.
Replacing the existing .synopsis rule with the following snippet should result in the
exact same page.
p:first-of-type {
color: #7E8184;
font-style: italic;
}
There’s pros and cons to using this method over plain old classes. For instance,
this only works if our synopsis is a <p> element. If we ever wanted to create a multi-
paragraph synopsis by wrapping a bunch of <p> elements in a <div class='synopsis'>,
we’d have to rewrite our CSS accordingly. On the other hand, the pseudo-class method
lets us style specific elements without having to alter the HTML at all. This gives us a
very clean separation of content from presentation.

CAVEATS
Ok, so actually the pseudo-class method is a little more complicated. They’re still a
useful tool—as long as you know their ins-and-outs. The :first-of-type and :last-of-

PREPARED BY: MAHMUD BAKALE & ALIJAFAR UMAR


type selectors only operate inside their parent element. That is to say, p:first-of-
type selects the first <p> in every container element.

We have a single generic <div> wrapping our content (.page), so this isn’t a problem
for us. However, consider what happens when we add this to the bottom of
our .page element:

<div class='sidebar'>
<p>If this page had a sidebar...</p>
<p>We’d have some problems with pseudo-classes.</p>
</div>

We won’t be able to make a real sidebar until the next chapter, but this does highlight
the complications of pseudo-classes for structure. The first <p> element here will also
match p:first-of-type because the pseudo-class’s scope is limited to the parent element.
If you wanted to avoid the sidebar paragraphs and select only the first <p> in our <div
class='page'>, you would need to limit its scope using a child selector, like so:
.page > p:first-of-type {
color: #7E8184;
font-style: italic;
}

All of this is yet another example of how there are many ways to do the same thing in
the wonderful world of HTML and CSS. Different developers adhere to different
schools of thought. Some like the semantic nature of pseudo-classes, while others go to
the far extreme with explicit class attributes on every HTML element.

PREPARED BY: MAHMUD BAKALE & ALIJAFAR UMAR


ID SELECTORS
“ID selectors” are a more stringent alternative to class selectors. They work pretty much
the same way, except you can only have one element with the same ID per page, which
means you can’t reuse styles at all. Instead of a class attribute, they require
an id attribute on whatever HTML element you’re trying to select. Try adding one to
our second button:
<a id='button-2' class='button' href='[Link]'>Button Two</a>
The corresponding CSS selector must begin with a hash sign ( #) opposed to a dot.
Adding the following to [Link] will change the text color of our yellow button:
#button-2 {
color: #5D6063; /* Dark gray */
}
The problem is, if we wanted to share this style with another button, we’d have to give
it another unique id attribute. Pretty soon, our CSS would start to look pretty gnarly:
/* (This is painful to maintain) */
#button-2,
#button-3,
#checkout-button,
#menu-bar-call-to-action {
color: #5D6063;
}
For this reason, ID selectors are generally frowned upon. Use class selectors instead.

URL FRAGMENTS
id attributes need to be unique because they serve as the target for “URL fragments”,
which we sort of glossed over in our discussion of URLs. Fragments are how you point
the user to a specific part of a web page. They look like an ID selector stuck on the end
of a URL.

PREPARED BY: MAHMUD BAKALE & ALIJAFAR UMAR


For example, if we wanted to point the user to our second button, we could use the
following. Note that we can omit the URL entirely if we’re linking to a different section
on the same page:

<!-- From the same page -->


<a href='#button-2'>Go to Button Two</a>

<!-- From a different page -->


<a href='[Link]#button-2'>Go to Button Two</a>
If you add the first option to our [Link] page and click it, you’ll see the URL in
the browser change. To actually see it jump down to the second button, you’ll need to
add some more dummy content to the page or make the window height very short, as
the browser will limit scrolling to the visible page.

This overlapping functionality is more reason to avoid ID selectors. They create a


dependency between your website’s URLs and your CSS styles. Imagine using a bunch
of id attributes on your headings as both URL fragments and ID selectors. If you forgot
to update your stylesheet every time you edited the URL of a section, you would
actually break your website.

PREPARED BY: MAHMUD BAKALE & ALIJAFAR UMAR


CSS SPECIFICITY
Earlier in this chapter, we talked about how order matters when it comes to CSS rules
in an external stylesheet. All else being equal, rules are applied from top-to-bottom.
This allowed us to override rules in a predictable manner.

Unfortunately, not all CSS selectors are created equal. “CSS specificity” is the weight
given to different categories of selectors. This means that certain selectors
will always override other ones, regardless of where they appear in the stylesheet.

Let’s start by seeing where this doesn’t break. If you add the following after our
existing .call-to-action rules, it will override the previous background-color. If you stick
it at the top of the file, it’ll get overridden later on, so our button won’t turn red. This is
expected behavior.
.call-to-action:link,
.call-to-action:visited {
background-color: #D55C5F; /* Red */
}

PREPARED BY: MAHMUD BAKALE & ALIJAFAR UMAR


Now, watch what happens when we try to do the same thing with an ID selector. First,
be sure to delete the previous snippet, then try adding this before our existing .call-to-
action rules:
#button-2 {
background-color: #D55C5F; /* Red */
}
ID selectors have higher specificity than class selectors, so this will turn our second
button red even though we try to set the background-color with .call-to-action:link later
in our stylesheet. The whole “order matters” concept only works when all your rules
have the same specificity.

The specificity of selectors we’ve seen in this chapter are show below, from greatest to
least:
• #button-2
• .button:link
• a:link and .synopsis em (they’re equal)
• .button
• a
This can get very confusing. It’s such a big problem that an entire methodology called
“BEM” has evolved. BEM attempts to make CSS rules more reusable by

PREPARED BY: MAHMUD BAKALE & ALIJAFAR UMAR


making everything a class selector. This completely eliminates the potential for
specificity issues.

BEM is outside the scope of this tutorial. The takeaway here is that CSS rules are not
necessarily applied in sequential order, but you should try to make the browser do so
by writing CSS that uses the same specificity.

SUMMARY
In this chapter, we got some hands-on experience with class selectors, descendant
selectors, pseudo-classes, link styling, and ID selectors. The goal of all this was to be
able to target a specific HTML element from your CSS. Class selectors are by far the
most versatile and come with the least amount of drawbacks. As a result, they’ll become
part of your daily life as a web developer.

Like it or not, things got a lot more complicated this chapter. We’re now able to make
our CSS interact with an HTML document in half a dozen different ways. Furthermore,
over the next few chapters, we’ll begin to see a dependency between our HTML’s
structure and the layout of a web page. With all this interplay between CSS and HTML,
it can be hard to know where to start building a new web page.

The separation of content from presentation helps guide this process. You need content
before you can present it, so your first step is usually to mark up your raw content with
HTML tags. Once that’s prepared, you’re ready to add class attributes to your elements
and style them one-by-one. When you discover a need for some extra structure to create
a desired layout (e.g., turn a group of elements into a sidebar), that’s when you start
wrapping your content in container <div>’s.

PREPARED BY: MAHMUD BAKALE & ALIJAFAR UMAR


This chapter covered almost all the CSS selectors that power real websites. We’ve got
the tools we need to dive much deeper into complex CSS layouts. In the next installment
of HTML and CSS Is Hard, we’ll learn how to create columns and sidebars using CSS
floats.

FLOATS
Nº 7. of HTML & CSS Is Hard
An old-timey web dev tutorial (and a friendly intro to CSS layouts)

Over the last few chapters, we’ve learned how to manipulate the size of boxes and the
space around them, but for the most part, we were stuck with the default vertical flow
of the page. Block elements always appeared vertically one after another, effectively
limiting us to a single-column layout.

PREPARED BY: MAHMUD BAKALE & ALIJAFAR UMAR


“Floats” let you put block-level elements side-by-side instead of on top of each other.
This is a big deal. It lets us build all sorts of layouts, including sidebars, multi-column
pages, grids, and magazine-style articles with text flowing around an image. This is
where we finally start creating real web pages. Float-based layouts have mostly been
replaced with Flexbox in modern websites. But, that’s not to say this chapter isn’t worth
reading. For over a decade, floats served as the foundation for the majority of websites
on the Internet, which means you’ll definitely encounter them at some point in your
career.
Perhaps more importantly, the limited nature of floats makes them a gentler introduction
to CSS layouts than Flexbox. Instead of being overwhelmed with all the possibilities of
Flexbox, we’ll get a chance to focus more on the process of building up a sophisticated
web page layout.

SETUP
This chapter demonstrates CSS floats with a pretty simple sample project. Instead of
working with proper HTML content as we have been in previous chapters, we’ll be
styling a bunch of empty <div> elements. We’ll end up with something that looks like
the following, which is a pretty big divergence from the types of web pages we’ve been
creating thus far.

PREPARED BY: MAHMUD BAKALE & ALIJAFAR UMAR


First, create a new folder called floats, then add a new web page called [Link] with
the following markup:
<!DOCTYPE html>
<html lang='en'>
<head>
<meta charset='UTF-8' />
<title>Floats</title>
<link rel='stylesheet' href='[Link]'/>
</head>
<body>
<div class='page'>
<div class='menu'>Menu</div>
<div class='sidebar'>Sidebar</div>
<div class='content'>Content</div>
<div class='footer'>Footer</div>
</div>
</body>
</html>

PREPARED BY: MAHMUD BAKALE & ALIJAFAR UMAR


This gives us the basic structure for most websites on the Internet. We have a place to
put a navigation menu, a sidebar, the main content of the page, and a footer. Think of
all these as container divs that you can put your actual HTML content into.
You won’t see much when you open [Link] in a browser because empty elements
have zero height. We’ll fix this in the next section.
*{
margin: 0;
padding: 0;
box-sizing: border-box;
}
Also be sure to create a [Link] stylesheet that resets default box behavior, as shown
above.

DEFAULT HTML LAYOUT BEHAVIOR


Floats alter the default layout of a web page, so we should probably start by reviewing
what exactly that “default” behavior is. We introduced this in block elements versus
inline elements, but it’s about to become much more important.

We can get a better look at our example page by adding some background colors and
explicit heights to each of our <div> elements. Add this to [Link]:
.menu {
height: 100px;
background-color: #B2D6FF; /* Medium blue */
}

.sidebar {
height: 300px;
background-color: #F09A9D; /* Red */
}

.content {

PREPARED BY: MAHMUD BAKALE & ALIJAFAR UMAR


height: 500px;
background-color: #F5CF8E; /* Yellow */
}

.footer {
height: 200px;
background-color: #D6E9FE; /* Light blue */
}
This gives us a nice rainbow, which isn’t what we’re looking for, though it does
demonstrate some useful concepts.

The important part here is that each block-level element fills 100% of its parent
elements’s width (<div class='page'> in this case), and they appear vertically one after
another. Again, we’re essentially limited to a single-column layout.
Typically, you’d want to let the height of these boxes be determined automatically
based on the content they contain; however, we’re more concerned with controlling

PREPARED BY: MAHMUD BAKALE & ALIJAFAR UMAR


layouts this chapter, so we won’t be dealing with much real content. This is why we
need the explicit height properties.

It’s worth taking a look at what happens when we shrink an element’s width. Update
our .sidebar rule to match the following:
.sidebar {
width: 200px; /* Add this */
height: 300px;
background-color: #F09A9D;
}
The sidebar element gets narrower, but the rest of the boxes stay in the exact same
position. All the blocks are still rendered vertically one after another. This is the
behavior we’ll be changing with floats.

FLOATING AN ELEMENT
The CSS float property gives us control over the horizontal position of an element. By
“floating” the sidebar to the left, we’re telling the browser to align it to the left side of
the page. Go ahead and float our sidebar with the following line:
.sidebar {
float: left; /* Add this */
width: 200px;

PREPARED BY: MAHMUD BAKALE & ALIJAFAR UMAR


height: 300px;
background-color: #F09A9D;
}
However, this doesn’t just align the sidebar—it also tells surrounding elements that
they can flow around the sidebar instead of beginning underneath it. It’s as if the
sidebar is inside the .content block, so any HTML markup in .content would wrap
around the sidebar’s box. This gives us a magazine-style layout:

You can also float elements right, as shown below (let’s keep our sidebar floated left
though). Or, if you’re overriding a float declaration, you can cancel it with
the none value. These are the most common values for the float property.

float: right; /* Right-aligned */


float: none; /* Revert to default flow */

We now have all the tools necessary to align block-level elements: floats for left/right
alignment and auto-margins for center alignment. Remember that this only applies
to block boxes. Inline boxes are aligned with the text-align property, as discussed in
the previous chapter.

PREPARED BY: MAHMUD BAKALE & ALIJAFAR UMAR


FLOATING INSIDE OF PARENTS
Floated boxes always align to the left or right of their parent element. In our example,
the sidebar’s parent is <div class='page'>, which is as wide as the browser window. This
is why our sidebar floats to the far left of the page.

Let’s change this by giving our page a fixed-width layout. Once again, the auto-margin
centering technique comes in handy. Add this to [Link]:
.page {
width: 900px;
margin: 0 auto;
}
Now, we can see that .sidebar floats to the left of the .page container, opposed to the
edge of the browser window.

PREPARED BY: MAHMUD BAKALE & ALIJAFAR UMAR


Positioning nested container divs like this is how you build up sophisticated website
layouts. Here, we started with .page to center everything, then we left-aligned a
sidebar inside that centered page. Things can get way more complex, but our simple
example demonstrates the universal truth of CSS layouts: everything is a box inside of
a box inside of another box.

MULTIPLE FLOATS
Let’s examine our current magazine-style float a little bit more by adding an explicit
width to our .content block:
.content {
width: 650px; /* Add this */
height: 500px;
background-color: #F5CF8E;
}
This clearly demonstrates that our sidebar is in fact inside the .content block: if you take
a screenshot of them, you’ll have an image that’s 650 pixels wide opposed to 850 pixels
(our sidebar is 200 pixels wide).

PREPARED BY: MAHMUD BAKALE & ALIJAFAR UMAR


This kind of float behavior is nice for images (which we’ll see later on), but for page
layout, we actually want the content block to be next to the sidebar instead of flowing
around it. For this, we need to tell the content block to float left, too. Add one more line
to the .content rule:
.content {
float: left; /* Add this */
width: 650px;
height: 500px;
background-color: #F5CF8E;
}
When you float multiple elements in the same direction, they’ll stack horizontally,
much like the default vertical layout algorithm, except rotated 90 degrees. The above
code causes our entire content block to appear on the right of the sidebar instead of
wrapping around it.

PREPARED BY: MAHMUD BAKALE & ALIJAFAR UMAR


This gives us true control over the horizontal alignment of our block boxes. Try playing
with the float values for both .sidebar and .content, and you’ll find that we already have
a couple of distinct layouts at our disposal:

Make sure both of them are floating left before moving on. That takes care of the layout
for the sidebar and content blocks, but it unfortunately messed up our .footer element…

AFTER A FLOAT
You probably noticed that our footer shows up in the top right, directly below .menu.
That’s because floated boxes are removed from the normal flow of the page. The height

PREPARED BY: MAHMUD BAKALE & ALIJAFAR UMAR


of our floated elements don’t contribute to the vertical position of the footer, so it simply
sticks itself below the last element that wasn’t floated.

We can see this more clearly by adding a red border around our .page element:
.page {
width: 900px;
margin: 0 auto;
border: 1px solid red; /* Add this */
}
Notice how the border is only around the .menu and .footer elements. It’s as if the
floated elements weren’t even there. There are two ways to fix this: clearing a float and
hiding overflow.

CLEARING FLOATS
“Clearing” a float is when we tell a block to ignore any floats that appear before it.
Instead of flowing around the floated box, a cleared element always appears after any
floats. It’s like forcing a box back into the default vertical flow of the page.

We can use the clear property to make our .footer drop down to the bottom of the page:
.footer {

PREPARED BY: MAHMUD BAKALE & ALIJAFAR UMAR


clear: both; /* Add this */
height: 200px;
background-color: #D6E9FE;
}
Usually, you want to clear both left and right floats as we did here, but you can choose
to clear only one or the other with the left or right values. Note that the red border now
wraps all the way around the footer, indicating that the floated elements indeed count
towards the height of the .page container:

Depending on the type of layout you’re trying to create, this is a perfectly acceptable
solution. We could stop here, but we’re going to explore float behavior more by
transforming our page into a full-bleed layout that has background colors filling the
entire browser window.

Watch what happens when we take the menu and footer out of the .page element.
Change the <body> element to match the following:
<body>
<div class='menu'>Menu</div>
<div class='page'>
<div class='sidebar'>Sidebar</div>

PREPARED BY: MAHMUD BAKALE & ALIJAFAR UMAR


<div class='content'>Content</div>
</div>

<div class='footer'>Footer</div>
</body>
Since .menu and .footer are outside our fixed-width .page, they’re the full width of the
window, which is exactly what we want for a full-bleed layout. However, notice
how .page has zero height again despite the fact that the footer still clears the sidebar
and content blocks.

Once again, the only elements in .page are floated, so they don’t count towards its
height. In other words, moving the footer outside of the .page container broke
our clear fix.

HIDING OVERFLOW
Clearing floats only fixes the height issue when there’s an element inside the container
element that we can add a clear property to. Now that our footer is outside .page, we
need a new way to make floated elements contribute to the height of their container.

PREPARED BY: MAHMUD BAKALE & ALIJAFAR UMAR


The solution is the CSS overflow property. By adding an overflow: hidden declaration
to a container div, we’re telling it to recognize the height of any floated elements it
contains. This is how we can add a background color to our .page element and have it
actually render:
.page {
width: 900px;
margin: 0 auto;
overflow: hidden; /* Add this */
background-color: #EAEDF0; /* Add this */
}
You should now be able to see a light gray background in .page instead of the default
white. This isn’t full bleed yet (we’ll address that in the next section). The important
part here is the behavior of overflow: hidden. Without it, we wouldn’t be able to see
the .page container’s background because it would have zero height.

PREPARED BY: MAHMUD BAKALE & ALIJAFAR UMAR


To summarize, when you have an extra unfloated HTML element at the bottom of a
container div, use the clear solution. Otherwise, add an overflow: hidden declaration to
the container element. The underlying idea for both options is that you need a way to
tell the browser to incorporate floats into the height of their container element in order
for their backgrounds to show up.

FULL-BLEED LAYOUTS
Next, we want to make our .page background fill the entire browser window without
changing the alignment of our sidebar or content blocks. The problem is, our .page is
busy centering everything—we can’t use it for a full-bleed background because
centering requires an explicit width property.

PREPARED BY: MAHMUD BAKALE & ALIJAFAR UMAR


It’s time for another container div. Putting a box around .page lets it continue centering
stuff while giving us a place to define a background-color property. Change
our <body> element to match the following:
<body>
<div class='menu'>Menu</div>
<div class='container'> <!-- Add this -->
<div class='page'>
<div class='sidebar'>Sidebar</div>
<div class='content'>Content</div>
</div>
</div> <!-- Add this -->
<div class='footer'>Footer</div>
</body>
Remember that the default block-rendering behavior is for elements to fill the width of
their container. So, we should be able to move our background-color declaration to
a .container rule to get a full-bleed background:
.page {
width: 900px;
margin: 0 auto;
}

PREPARED BY: MAHMUD BAKALE & ALIJAFAR UMAR


.container {
overflow: hidden;
background-color: #EAEDF0;
}
As in the previous section, we still need the overflow: hidden line to force
the .container to pay attention to the height of the floated elements. Without it, we
wouldn’t see our background color because .container would have zero height.

This gives us three nested <div> elements just for laying out our page:
a .container wrapper for full-bleed background color, a fixed-width .page for centering
everything, and finally left-aligned .sidebar and .content blocks. This kind of nesting
and aligning is pretty typical of most website layouts.

FLOATS FOR EQUAL-WIDTH COLUMNS


So far, we’ve seen a sidebar layout, a fixed-width layout, and a full-bleed layout. Floats
can also be used to create multi-column layouts. This works just like
our .sidebar and .content floats—we just have more of them.

Next we’re going to add three equal-width columns to our footer. Update
the <footer> element, like so:
<div class='footer'>
<div class='column'></div>
<div class='column'></div>
<div class='column'></div>
</div>
We can style each of these columns just like we laid out the rest of our page. Add a
new rule to [Link]:
.column {
float: left;
width: 31%;

PREPARED BY: MAHMUD BAKALE & ALIJAFAR UMAR


margin: 20px 1.15%;
height: 160px;
background-color: #B2D6FF; /* Medium blue */
}
This is the first time we’ve used percentage values instead of explicit pixel values.
Percentages in CSS are relative to the width of the parent element. The result is three
columns that automatically resize to one-third of the browser window. Resize the
browser window, and you’ll see our columns grow and shrink accordingly. This is the
beginning of responsive design.

Anyhoo, let’s not lose sight of the central thesis of this chapter: floats let us stack things
horizontally instead of vertically. By changing the widths of the elements we’re
floating, we can get all kinds of different layouts, from sidebars to multiple columns to
grids.

FLOATS FOR GRIDS


Want a grid in the footer instead of 3 columns? No problem! When there isn’t enough
room to stack a floated element horizontally, it pops down to the next line. All we need
to do is add some more .column elements:
<div class='footer'>

PREPARED BY: MAHMUD BAKALE & ALIJAFAR UMAR


<div class='column'></div>
<div class='column'></div>
<div class='column'></div>
<div class='column'></div>
<div class='column'></div>
<div class='column'></div>
</div>
Voilà! A grid! Well, almost…

Our footer background is too short. Fortunately, we already know how to fix that. Let’s
replace the footer’s explicit height with another overflow: hidden so it can accommodate
any number of grid items:
.footer {
overflow: hidden;
background-color: #D6E9FE;
}
You can use this same technique to make grids of any size. For example, creating a
photo gallery with a bunch of thumbnails is simply a matter of putting the grid items
in .page instead of the footer and adding <img/> elements to them. But, again,
remember that flexbox is a more modern way to create these kinds of layouts.

PREPARED BY: MAHMUD BAKALE & ALIJAFAR UMAR


A BRIEF NOTE ON NAMING CONVENTIONS
The .column class name isn’t exactly accurate anymore. This scenario is a good
example of why we want to avoid class names that refer to appearance. “Column” isn’t
so great because the content it contains doesn’t necessarily need to be rendered in
multiple columns (e.g., for a mobile layout, there would likely only be one column). A
better name would be something like .footer-item, but we’ll leave that for you to fix.

FLOATS FOR CONTENT


There’s two aspects to defining a web page layout. You have your overall page
structure, which we’ve been working on throughout this entire chapter. This is stuff like
where you sidebar goes, how big your navigation menu is, etc. The other aspect of
layouts is styling the individual HTML components (your actual content) that go inside
this overarching page structure.

The process for the latter is the same, it’s just nested inside the former. Let’s add some
dummy content to our .content element so we have something to play with:
<div class='container'>
<div class='page'>
<div class='sidebar'></div>
<div class='content'>

<img src='?' class='article-image'/>

<p>Ad netus sagittis velit orci est non ut urna taciti metus donec magnis
hendrerit adipiscing mauris sit a proin ultrices nibh.</p>

<p>Enim suspendisse ac scelerisque nascetur vestibulum parturient sed mi a


dolor eu non adipiscing non neque scelerisque netus ullamcorper sed
parturient [Link] dui risus non sodales ullamcorper libero a dis

PREPARED BY: MAHMUD BAKALE & ALIJAFAR UMAR


cubilia a orci iaculis cursus.</p>

<p>Egestas at aliquam a egestas accumsan cum elementum consectetur conubia


tristique eu et vitae condimentum in ante consectetur suscipit a a duis
vestibulum gravida morbi [Link] scelerisque facilisis
ullamcorper a a pretium a nisl parturient semper senectus accumsan ipsum
mus scelerisque eget [Link] dolor a.</p>

<p>Ligula taciti vel primis sit a tincidunt habitant parturient parturient


in parturient ante nulla consectetur [Link] parturient litora.</p>

</div>
</div>
</div>

We’ve got an image and several paragraphs that we can style just like our structural
divs. For example, let’s create a magazine-style layout by floating the image and letting
the text flow around it. Add a couple more rules to our stylesheet:

.content {
padding: 20px;
}

.article-image {
float: left;
width: 300px;
height: 200px;
margin-right: 20px;
margin-bottom: 20px;
}

p{
margin-bottom: 20px;
}

PREPARED BY: MAHMUD BAKALE & ALIJAFAR UMAR


Notice how we have a float inside of a float, and everything works just fine. Laying out
a website is a recursive process: you build a high-level structure to work in, then you
fill it with your actual content. More complex layouts may need another layer or two of
nesting, but the idea is the same.

HIDING OVERFLOW (FOR CONTENT)


You’ll find examples of nested layouts all over the place. For our final example,
consider a basic user-comment thread. You have an image that’s floated left with a
heading and some text next to it:

Let’s try creating this in our footer. In your favorite .column element, add the following:
<div class='column'>
<div class='avatar'></div>
<h3 class='username'>Bob Smith</h3>

PREPARED BY: MAHMUD BAKALE & ALIJAFAR UMAR


<p class='comment'>Aptent vel egestas vestibulum aliquam ullamcorper volutpat
ullamcorper pharetra hac posuere a rhoncus purus molestie torquent. Scelerisque
purus cursus dictum ornare a phasellus. A augue venenatis adipiscing.</p>
</div>
And the corresponding CSS rules:

.avatar {
float: left;
width: 60px;
height: 60px;
margin: 25px;
border-radius: 40px;
background-color: #D6E9FE;
}

.username {
margin-top: 30px;
}

.comment {
margin: 10px;
overflow: hidden; /* This is important */
}
This highlights another use case for our overflow: hidden trick. Sticking it on
our .comment box made sure that the text “horizontally cleared” (that’s not a technical
term) the floated image. Without it, the last line of the .comment text would hang
underneath the image.

PREPARED BY: MAHMUD BAKALE & ALIJAFAR UMAR


In other words, overflow: hidden breaks the magazine-style layout from the previous
section, but in a very useful way.

SUMMARY
This chapter was our first encounter with realistic web page layouts. We learned how
to float divs to the left and right, how to deal with content after a float, and how to
combine floats with the auto-margin centering technique from the CSS Box
Model chapter. These are the tools we need to create sidebars, grids, an magazine-style
layouts.

It’s important not to lose sight of the developer’s role in the website creation process.
Your job as a web developer is to take a beautifully designed mockup and turn it into
the HTML and CSS that browsers can display to your end users. Floats are a big leap
forward towards that end, but they’re also becoming obsolete in favor of the flexbox
layout scheme.

In the next chapter, we’ll learn even more ways to lay out complex websites using
flexbox. The CSS properties will be new, but the process will be the same as it was in
this chapter: we’ll still be aligning boxes inside of other boxes, inside of other boxes,
and so on until we accomplish the desired layout.

PREPARED BY: MAHMUD BAKALE & ALIJAFAR UMAR


FLEXBOX
Nº 8. of HTML & CSS Is Hard
A friendly tutorial for modern CSS layouts

The “Flexible Box” or “Flexbox” layout mode offers an alternative to Floats for defining
the overall appearance of a web page. Whereas floats only let us horizontally position our
boxes, flexbox gives us complete control over the alignment, direction, order, and size of
our boxes.

The web is currently undergoing a major transition, so a little discussion around the state
of the industry is warranted. For the last decade or so, floats were the sole option for laying
out a complex web page. As a result, they’re well supported even in legacy browsers, and

PREPARED BY: MAHMUD BAKALE & ALIJAFAR UMAR


developers have used them to build millions of web pages. This means you’ll inevitably
run into floats during your web development career (so the previous chapter wasn’t a total
waste).

However, floats were originally intended for the magazine-style layouts that we covered
in Floats for Content. Despite what we saw last chapter, the kinds of layouts you can create
with floats are actually somewhat limited. Even a simple sidebar layout is, technically
speaking, a little bit of a hack. Flexbox was invented to break out of these limitations.

We’re finally at a point where browser support has hit critical mass and developers can
start building full websites with flexbox. Our recommendation is to use flexbox to lay out
your web pages as much as possible, reserving floats for when you need text to
flow around a box (i.e., a magazine-style layout) or when you need to support legacy web
browsers.

In this chapter, we’ll explore the entire flexbox layout model step by step. You should walk
away comfortable building virtually any layout a web designer could ever give you.

SETUP
The example for this chapter is relatively simple, but it clearly demonstrates all of the important
flexbox properties. We’ll wind up with something that looks like this:

PREPARED BY: MAHMUD BAKALE & ALIJAFAR UMAR


For starters, we need an empty HTML document that contains nothing but a menu bar.
Make a new Atom project called flexbox to house all the example files for this chapter.
Then, create [Link] and add the following markup:
<!DOCTYPE html>
<html lang='en'>
<head>
<meta charset='UTF-8'/>
<title>Some Web Page</title>
<link rel='stylesheet' href='[Link]'/>
</head>
<body>
<div class='menu-container'>
<div class='menu'>
<div class='date'>Aug 14, 2016</div>
<div class='signup'>Sign Up</div>
<div class='login'>Login</div>
</div>
</div>
</body>
</html>

PREPARED BY: MAHMUD BAKALE & ALIJAFAR UMAR


Next, we need to create the corresponding [Link] stylesheet. This won’t look like much: just a
full-width blue menu bar with a white-bordered box in it. Note that we’ll be using flexbox instead
of our traditional auto-margin technique to center the menu.
*{
margin: 0;
padding: 0;
box-sizing: border-box;
}

.menu-container {
color: #fff;
background-color: #5995DA; /* Blue */
padding: 20px 0;
}

.menu {
border: 1px solid #fff; /* For debugging */
width: 900px;
}
Finally, download some images for use by our example web page. Unzip them into
the flexbox project, keeping the parent images directory. Your project should look like this
before moving on:

PREPARED BY: MAHMUD BAKALE & ALIJAFAR UMAR


FLEXBOX OVERVIEW
Flexbox uses two types of boxes that we’ve never seen before: “flex containers” and “flex
items”. The job of a flex container is to group a bunch of flex items together and define
how they’re positioned.

Every HTML element that’s a direct child of a flex container is an “item”. Flex items can
be manipulated individually, but for the most part, it’s up to the container to determine
their layout. The main purpose of flex items are to let their container know how many
things it needs to position.

PREPARED BY: MAHMUD BAKALE & ALIJAFAR UMAR


As with float-based layouts, defining complex web pages with flexbox is all about nesting
boxes. You align a bunch of flex items inside a container, and, in turn, those items can
serve as flex containers for their own items. As you work through the examples in this
chapter, remember that the fundamental task of laying out a page hasn’t changed: we’re
still just moving a bunch of nested boxes around.

FLEX CONTAINERS
The first step in using flexbox is to turn one of our HTML elements into a flex container.
We do this with the display property, which should be familiar from the CSS Box
Model chapter. By giving it a value of flex, we’re telling the browser that everything in the
box should be rendered with flexbox instead of the default box model.

Add the following line to our .menu-container rule to turn it into a flex container:
.menu-container {
/* ... */
display: flex;
}
This enables the flexbox layout mode—without it, the browser would ignore all the flexbox
properties that we’re about to introduce. Explicitly defining flex containers means that you can
mix and match flexbox with other layout models (e.g., floats and everything we’re going to learn
in Advanced Positioning).

PREPARED BY: MAHMUD BAKALE & ALIJAFAR UMAR


Great! We have a flex container with one flex item in it. However, our page will look
exactly like it did before because we haven’t told the container how to display its item.

ALIGNING A FLEX ITEM


After you’ve got a flex container, your next job is to define the horizontal alignment of its
items. That’s what the justify-content property is for. We can use it to center our .menu,
like so:
.menu-container {
/* ... */
display: flex;
justify-content: center; /* Add this */
}
This has the same effect as adding a margin: 0 auto declaration to the .menu element. But,
notice how we did this by adding a property to the parent element (the flex container)
instead of directly to the element we wanted to center (the flex item). Manipulating items
through their containers like this is a common theme in flexbox, and it’s a bit of a
divergence from how we’ve been positioning boxes thus far.

PREPARED BY: MAHMUD BAKALE & ALIJAFAR UMAR


Other values for justify-content are shown below:
• center
• flex-start
• flex-end
• space-around
• space-between
Try changing justify-content to flex-start and flex-end. This should align the menu to the
left and right side of the browser window, respectively. Be sure to change it back
to center before moving on. The last two options are only useful when you have multiple
flex items in a container.

DISTRIBUTING MULTIPLE FLEX ITEMS


“Big deal,” you might be saying: we can do left/right alignment with floats and centering
with auto-margins. True. Flexbox doesn’t show its real strength until we have more than
one item in a container. The justify-content property also lets you distribute items equally
inside a container.

PREPARED BY: MAHMUD BAKALE & ALIJAFAR UMAR


Change our .menu rule to match the following:
.menu {
border: 1px solid #fff;
width: 900px;
display: flex;
justify-content: space-around;
}
This turns our .menu into a nested flex container, and the space-around value spreads its
items out across its entire width. You should see something like this:

The flex container automatically distributes extra horizontal space to either side of each
item. The space-between value is similar, but it only adds that extra space between items.
This is what we actually want for our example page, so go ahead and update the justify-
content line:
justify-content: space-between;
Of course, you can also use center, flex-start, flex-end here if you want to push all the items
to one side or another, but let’s leave it as space-between.

GROUPING FLEX ITEMS


Flex containers only know how to position elements that are one level deep (i.e., their child
elements). They don’t care one bit about what’s inside their flex items. This means that
grouping flex items is another weapon in your layout-creation arsenal. Wrapping a bunch
of items in an extra <div> results in a totally different web page.

PREPARED BY: MAHMUD BAKALE & ALIJAFAR UMAR


For example, let’s say you want both the Sign Up and Login links to be on the right side
of the page, as in the screenshot below. All we need to do is stick them in another <div>:
<div class='menu'>
<div class='date'>Aug 14, 2016</div>
<div class='links'>
<div class='signup'>Sign Up</div> <!-- This is nested now -->
<div class='login'>Login</div> <!-- This one too! -->
</div>
</div>
Instead of having three items, our .menu flex container now has only two (.date and .links).
Under the existing space-between behavior, they’ll snap to the left and right side of the
page.

But, now we need to lay out the .links element because it’s using the default block layout
mode. The solution: more nested flex containers! Add a new rule to our [Link] file that
turns the .links element into a flex container:
.links {
border: 1px solid #fff; /* For debugging */
display: flex;

PREPARED BY: MAHMUD BAKALE & ALIJAFAR UMAR


justify-content: flex-end;
}

.login {
margin-left: 20px;
}
This will put our links right where we want them. Notice that margins still work just like
they did in the CSS Box Model. And, as with the normal box model, auto margins have a
special meaning in flexbox (we’ll leave that for the end of the chapter though).

We won’t need those white borders anymore, so you can go ahead and delete them if you
like.

CROSS-AXIS (VERTICAL) ALIGNMENT


So far, we’ve been manipulating horizontal alignment, but flex containers can also define
the vertical alignment of their items. This is something that’s simply not possible with
floats.

PREPARED BY: MAHMUD BAKALE & ALIJAFAR UMAR


To explore this, we need to add a header underneath our menu. Add the following markup
to [Link] after the .menu-container element:
<div class='header-container'>
<div class='header'>
<div class='subscribe'>Subscribe &#9662;</div>
<div class='logo'><img src='images/[Link]'/></div>
<div class='social'><img src='images/[Link]'/></div>
</div>
</div>
Next, add some base styles to get it aligned with our .menu element:
.header-container {
color: #5995DA;
background-color: #D6E9FE;
display: flex;
justify-content: center;
}

.header {
width: 900px;
height: 300px;
display: flex;
justify-content: space-between;
}
This should all be familiar; however, the scenario is a little bit different than our menu.
Since .header has an explicit height, items can be positioned vertically inside of it. The
official specification calls this “cross-axis” alignment (we’ll see why in a moment), but for
our purposes it might as well be called “vertical” alignment.

PREPARED BY: MAHMUD BAKALE & ALIJAFAR UMAR


Vertical alignment is defined by adding an align-items property to a flex container. Make
our example page match the above screenshot with the following line:
.header {
/* ... */
align-items: center; /* Add this */
}
The available options for align-items is similar to justify-content:
• center
• flex-start (top)
• flex-end (bottom)

• stretch
• baseline

PREPARED BY: MAHMUD BAKALE & ALIJAFAR UMAR


Most of these are pretty straightforward. The stretch option is worth a taking a minute to
play with because it lets you display the background of each element. Let’s take a brief
look by adding the following to [Link]:
.header {
/* ... */
align-items: stretch; /* Change this */
}

.social,
.logo,
.subscribe {
border: 1px solid #5995DA;
}
The box for each item extends the full height of the flex container, regardless of how much
content it contains. A common use case for this behavior is creating equal-height columns
with a variable amount of content in each one—something very difficult to do with floats.

Be sure to delete the above changes and vertically center our content inside
of .header before moving on.

WRAPPING FLEX ITEMS


Flexbox is a more powerful alternative to float-based grids. Not only can it render items as
a grid—it can change their alignment, direction, order, and size, too. To create a grid, we
need the flex-wrap property.

PREPARED BY: MAHMUD BAKALE & ALIJAFAR UMAR


Add a row of photos to [Link] so that we have something to work with. This should
go inside of <body>, under the .header-container element:
<div class='photo-grid-container'>
<div class='photo-grid'>
<div class='photo-grid-item first-item'>
<img src='images/[Link]'/>
</div>
<div class='photo-grid-item'>
<img src='images/[Link]'/>
</div>
<div class='photo-grid-item'>
<img src='images/[Link]'/>
</div>
</div>
</div>
Again, the corresponding CSS should be familiar from previous sections:

.photo-grid-container {
display: flex;
justify-content: center;
}

.photo-grid {
width: 900px;
display: flex;

PREPARED BY: MAHMUD BAKALE & ALIJAFAR UMAR


justify-content: flex-start;
}

.photo-grid-item {
border: 1px solid #fff;
width: 300px;
height: 300px;
}

This should work as expected, but watch what happens when we add more items than can
fit into the flex container. Insert an extra two photos into the .photo-grid:
<div class='photo-grid-item'>
<img src='images/[Link]'/>
</div>
<div class='photo-grid-item last-item'>
<img src='images/[Link]'/>
</div>
By default, they flow off the edge of the page:

If you’re trying to build a hero banner that lets the user horizontally scroll through a bunch
of photos, this might be desired behavior, but that’s not what we want. Adding the
following flex-wrap property forces items that don’t fit to get bumped down to the next
row:
.photo-grid {
/* ... */

PREPARED BY: MAHMUD BAKALE & ALIJAFAR UMAR


flex-wrap: wrap;
}
Now, our flex items behave much like floated boxes, except flexbox gives us more control
over how “extra” items are aligned in the final row via the justify-content property. For
example, the last line is currently left-aligned. Try centering it by updating our .photo-
grid rule, like so:
.photo-grid {
width: 900px;
display: flex;
justify-content: center; /* Change this */
flex-wrap: wrap;
}
Achieving this with float-based layouts is ridiculously complicated.

FLEX CONTAINER DIRECTION


“Direction” refers to whether a container renders its items horizontally or vertically. So far,
all the containers we’ve seen use the default horizontal direction, which means items are
drawn one after another in the same row before popping down to the next column when
they run out of space.

PREPARED BY: MAHMUD BAKALE & ALIJAFAR UMAR


One of the most amazing things about flexbox is its ability to transform rows into columns
using only a single line of CSS. Try adding the following flex-direction declaration to
our .photo-grid rule:
.photo-grid {
/* ... */
flex-direction: column;
}
This changes the direction of the container from the default row value. Instead of a grid,
our page now has a single vertical column:

A key tenant of responsive design is presenting the same HTML markup to both mobile
and desktop users. This presents a bit of a problem, as most mobile layouts are a single

PREPARED BY: MAHMUD BAKALE & ALIJAFAR UMAR


column, while most desktop layouts stack elements horizontally. You can imagine how
useful flex-direction is going to become once we start building responsive layouts.

ALIGNMENT CONSIDERATIONS
Notice that the column is hugging the left side of its flex container despite our justify-
content: center; declaration. When you rotate the direction of a container, you also rotate
the direction of the justify-content property. It now refers to the container’s vertical
alignment—not its horizontal alignment.

To horizontally center our column, we need to define an align-items property on our .photo-
grid:
.photo-grid {
/* ... */
flex-direction: column;
align-items: center; /* Add this */
}

FLEX CONTAINER ORDER


Up until now, there’s been a tight correlation between the order of our HTML elements
and the way boxes are rendered in a web page. With either floats or the flexbox techniques
we’ve seen so far, the only way we could make a box appear before or after another one is
to move around the underlying HTML markup. That’s about to change.

PREPARED BY: MAHMUD BAKALE & ALIJAFAR UMAR


The flex-direction property also offers you control over the order in which items appear
via the row-reverse and column-reverse properties. To see this in action, let’s transform
our column back into a grid, but this time around we’ll reverse the order of everything:
.photo-grid {
width: 900px;
display: flex;
justify-content: center;
flex-wrap: wrap;
flex-direction: row-reverse; /* <--- Really freaking cool! */
align-items: center;
}
Both rows are now rendered right-to-left instead of left-to-right. But, notice how this only swaps
the order on a per-row basis: the first row doesn’t start at 5, it starts at 3. This is useful behavior
for a lot of common design patterns (column-reverse in particular opens up a lot of doors for
mobile layouts). We’ll learn how to get even more granular in the next section.

PREPARED BY: MAHMUD BAKALE & ALIJAFAR UMAR


Reordering elements from inside a stylesheet is a big deal. Before flexbox, web developers
had to resort to JavaScript hacks to accomplish this kind of thing. However, don’t abuse
your newfound abilities. As we discussed in the very first chapter of this tutorial, you
should always separate content from presentation. Changing the order like this is purely
presentational—your HTML should still make sense without these styles applied to it.

FLEX ITEM ORDER


This entire chapter has been about positioning flex items through their parent containers,
but it’s also possible to manipulate individual items. The rest of this chapter is going to
shift focus away from flex containers onto the items they contain.

PREPARED BY: MAHMUD BAKALE & ALIJAFAR UMAR


Adding an order property to a flex item defines its order in the container without affecting
surrounding items. Its default value is 0, and increasing or decreasing it from there moves
the item to the right or left, respectively.

This can be used, for example, to swap order of the .first-item and .last-item elements in
our grid. We should also change the row-reverse value from the previous section back
to row because it’ll make our edits a little easier to see:
.photo-grid {
/* ... */
flex-direction: row; /* Update this */
align-items: center;
}

.first-item {
order: 1;
}

.last-item {
order: -1;
}
Unlike setting row-reverse and column-reverse on a flex container, order works across
row/column boundaries. The above snippet will switch our first and last items, even though
they appear on different rows.

FLEX ITEM ALIGNMENT


We can do the same thing with vertical alignment. What if we want that Subscribe link
and those social icons to go at the bottom of the header instead of the center? Align them
individually! This is where the align-self property comes in. Adding this to a flex item
overrides the align-items value from its container:
.social,
.subscribe {
align-self: flex-end;
margin-bottom: 20px;

PREPARED BY: MAHMUD BAKALE & ALIJAFAR UMAR


}
This should send them to the bottom of the .header. Note that margins (padding, too) work just
like you’d expect.

You can align elements in other ways using the same values as the align-items property,
listed below for convenience.
• center
• flex-start (top)
• flex-end (bottom)
• stretch
• baseline

FLEXIBLE ITEMS
All our examples have revolved around items with fixed- or content-defined-widths. This
has let us focus on the positioning aspects of flexbox, but it also means we’ve been ignoring
its eponymous “flexible box” nature. Flex items are flexible: they can shrink and stretch to
match the width of their containers.

The flex property defines the width of individual items in a flex container. Or, more
accurately, it allows them to have flexible widths. It works as a weight that tells the flex

PREPARED BY: MAHMUD BAKALE & ALIJAFAR UMAR


container how to distribute extra space to each item. For example, an item with a flex value
of 2 will grow twice as fast as items with the default value of 1.

First, we need a footer to experiment with. Stick this after the .photo-grid-container element:
<div class='footer'>
<div class='footer-item footer-one'></div>
<div class='footer-item footer-two'></div>
<div class='footer-item footer-three'></div>
</div>
Then, some CSS:

.footer {
display: flex;
justify-content: space-between;
}

.footer-item {
border: 1px solid #fff;
background-color: #D6E9FE;
height: 200px;
flex: 1;
}
That flex: 1; line tells the items to stretch to match the width of .footer. Since they all have
the same weight, they’ll stretch equally:

PREPARED BY: MAHMUD BAKALE & ALIJAFAR UMAR


Increasing the weight of one of the items makes it grow faster than the others. For example,
we can make the third item grow twice as fast as the other two with the following rule:
.footer-three {
flex: 2;
}
Compare this to the justify-content property, which distributes extra space between items.
This is similar, but now we’re distributing that space into the items themselves. The result
is full control over how flex items fit into their containers.

STATIC ITEM WIDTHS


We can even mix-and-match flexible boxes with fixed-width ones. flex: initial falls back
to the item’s explicit width property. This lets us combine static and flexible boxes in
complex ways.

PREPARED BY: MAHMUD BAKALE & ALIJAFAR UMAR


We’re going to make our footer behave like the above diagram. The center item is flexible,
but the ones on either side are always the same size. All we need to do is add the following
rule to our stylesheet:

.footer-one,
.footer-three {
background-color: #5995DA;
flex: initial;
width: 300px;
}
Without that flex: initial; line, the flex: 1; declaration would be inherited from the .footer-
item rule, causing the width properties to be ignored. initial fixes this, and we get a flexible
layout that also contains fixed-width items. When you resize the browser window, you’ll
see that only the middle box in the footer gets resized.

PREPARED BY: MAHMUD BAKALE & ALIJAFAR UMAR


This is a pretty common layout, and not just in footers, either. For instance, many websites
have a fixed-width sidebar (or multiple sidebars) and a flexible content block containing
the main text of the page. This is basically a taller version of the footer we just created.

FLEX ITEMS AND AUTO-MARGINS


Auto-margins in flexbox are special. They can be used as an alternative to
an extra <div> when trying to align a group of items to the left/right of a container. Think
of auto-margins as a “divider” for flex items in the same container.

Let’s take a look by flattening our items in .menu so that it matches the following:
<div class='menu-container'>
<div class='menu'>
<div class='date'>Aug 14, 2016</div>
<div class='signup'>Sign Up</div>
<div class='login'>Login</div>
</div>
</div>

PREPARED BY: MAHMUD BAKALE & ALIJAFAR UMAR


Reloading the page should make the items spread out equally through our menu, just like
at the beginning of the chapter. We can replicate the desired layout by sticking an auto-
margin between the items we want to separate, like so:

.signup {
margin-left: auto;
}
Auto-margins eat up all the extra space in a flex container, so instead of distributing items
equally, this moves the .signup and any following items (.login) to the right side of the
container. This will give you the exact same layout we had before, but without that extra
nested <div> to group them. Sometimes, it’s nice to keep your HTML flatter.

SUMMARY
Flexbox gave us a ton of amazing new tools for laying out a web page. Compare these
techniques to what we were able to do with floats, and it should be pretty clear that
flexbox is a cleaner option for laying out modern websites:

• Use display: flex; to create a flex container.


• Use justify-content to define the horizontal alignment of items.
• Use align-items to define the vertical alignment of items.
• Use flex-direction if you need columns instead of rows.
• Use the row-reverse or column-reverse values to flip item order.
• Use order to customize the order of individual elements.
• Use align-self to vertically align individual items.
• Use flex to create flexible boxes that can stretch and shrink.

Remember that these flexbox properties are just a language that lets you tell browsers
how to arrange a bunch of HTML elements. The hard part isn’t actually writing the

PREPARED BY: MAHMUD BAKALE & ALIJAFAR UMAR


HTML and CSS code, it’s figuring out, conceptually (on a piece of paper), the behavior
of all the necessary boxes to create a given layout.

When a designer hands you a mockup to implement, your first task is to draw a bunch
of boxes on it and determine how they’re supposed to stack, stretch, and shrink to
achieve the desired design. Once you’ve got that done, it should be pretty easy to code
it up using these new flexbox techniques.

The flexbox layout mode should be used for most of your web pages, but there are some
things it’s not-so-good at, like gently tweaking element positions and preventing them
from interacting with the rest of the page. After covering these kinds of advanced
positioning techniques in the next chapter, you’ll be an HTML and CSS positioning
expert.

PREPARED BY: MAHMUD BAKALE & ALIJAFAR UMAR


ADVANCED POSITIONING
Nº 9. of HTML & CSS Is Hard
A friendly tutorial about static, relative, absolute, and fixed positioning

“Static positioning” refers to the normal flow of the page that we’ve been working with
up ’til this point. The CSS Box Model, floats, and flexbox layout schemes all operate
in this “static” flow, but that’s not the only positioning scheme available in CSS.

The other three types of positioning are “relative”, “absolute”, and “fixed”. Each of
them let you manually position elements using specific coordinates, opposed to the
more semantic options in flexbox and floats. Instead of saying “Stick this box in the
center of its container,” advanced positioning lets you say things like “Put that box 20
pixels above and 50 pixels to the right of its parent’s origin.”

The vast majority of elements on a web page should be laid out according to the static
flow of the page. These other positioning schemes come into play when you want to do

PREPARED BY: MAHMUD BAKALE & ALIJAFAR UMAR


more advanced things like tweak the position of a particular element or animate a UI
component without messing up the surrounding elements.

This chapter is split into two parts. We’ll start by examining relative, absolute, and fixed
positioning in isolation, then we’ll apply everything we learned to a fancy dropdown
menu.

SETUP
Start by creating a new Atom project called advanced-positioning and a new file
called [Link] with the following markup:
<!DOCTYPE html>
<html>
<head>
<meta charset='UTF-8'/>
<title>Positioning Is Easy!</title>
<link href='[Link]' rel='stylesheet'/>
</head>
<body>

<div class='container'>
<div class='example relative'>
<div class='item'><img src='images/[Link]' /></div>
<div class='item item-relative'><img src='images/[Link]' /></div>
<div class='item'><img src='images/[Link]' /></div>
</div>
</div>
<div class='container'>
<div class='example absolute'>
<div class='item'><img src='images/[Link]' /></div>
<div class='item item-absolute'><img src='images/[Link]' /></div>
<div class='item'><img src='images/[Link]' /></div>
</div>
</div>
<div class='container'>

PREPARED BY: MAHMUD BAKALE & ALIJAFAR UMAR


<div class='example fixed'>
<div class='item'><img src='images/[Link]' /></div>
<div class='item item-fixed'><img src='images/[Link]' /></div>
<div class='item'><img src='images/[Link]' /></div>
</div>
</div>
</body>
</html>
We’ve got three examples to work with, all with the exact same HTML structure. Changing
the positioning behavior inside each one will have dramatically different effects.

This page relies on some images to make our example a little bit clearer. Keep the
parent images folder when unzipping the files into your project, as show above. Be sure to
create [Link] and populate it with the necessary base styles, as well:
*{
margin: 0;
padding: 0;
box-sizing: border-box;
}

body {
height: 1200px;
}

PREPARED BY: MAHMUD BAKALE & ALIJAFAR UMAR


.container {
display: flex;
justify-content: center;
}

.example {
display: flex;
justify-content: space-around;

width: 800px;
margin: 50px 0;
background-color: #D6E9FE;
}

.item img {
display: block;
}
Nothing new here, just some familiar flexbox techniques to create a grid of items. The only
weird thing is the explicit height on the <body> element, which will let us scroll up and
down the page to demonstration different positioning behaviors.

PREPARED BY: MAHMUD BAKALE & ALIJAFAR UMAR


POSITIONED ELEMENTS
The CSS position property lets you alter the positioning scheme of a particular element. Its
default value, as you might imagine, is static. When an
element’s position property doesn’t have a value of static, it’s called a “positioned
element”. Positioned elements are what this entire chapter is about.

It’s possible to mix-and-match different positioning schemes. Again, most of your web
page should be statically positioned, but it’s common to find relatively and absolutely
positioned elements inside of other elements that are part of the normal flow of the page.

RELATIVE POSITIONING
“Relative positioning” moves elements around relative to where they would normally
appear in the static flow of the page. This is useful for nudging boxes around when the
default flow is just a little bit off.

PREPARED BY: MAHMUD BAKALE & ALIJAFAR UMAR


Let’s turn the .item-relative element in [Link] into a relatively positioned
element. Add the following rule to [Link]:
.item-relative {
position: relative;
top: 30px;
left: 30px;
}
The position: relative; line makes it a positioned element, and the top and left properties
let you define how far it’s offset from its static position. This is sort of like setting an
(x, y) coordinate for the element.

Relative positioning works similarly to margins, with one very important difference:
neither the surrounding elements or parent element are affected by the top and left values.
Everything else renders as if .item-relative was in its original position. Think of the offsets
as being applied after the browser finishes laying out the page.

The top and left properties measure from the original box’s top and left edges, respectively.
We can offset relative to the other edges with the bottom and right properties.

PREPARED BY: MAHMUD BAKALE & ALIJAFAR UMAR


For example, the following will nudge the box in the opposite direction:
.item-relative {
position: relative;
bottom: 30px;
right: 30px;
}
Note that these properties accept negative values, which means there’s two ways to specify
the same offset. We could just as easily used top: -30px; in place of the bottom:
30px; declaration above.

ABSOLUTE POSITIONING
“Absolute positioning” is just like relative positioning, but the offset is relative to the entire
browser window instead of the original position of the element. Since there’s no longer any
relationship with the static flow of the page, consider this the most manual way to lay out
an element.

PREPARED BY: MAHMUD BAKALE & ALIJAFAR UMAR


Let’s take a look by adding the following rule to our stylesheet:
.item-absolute {
position: absolute;
top: 10px;
left: 10px;
}
Our HTML structure is the exact same as the previous example, but this will stick the
purple image in the top-left corner of the browser window. You can also try setting
a bottom or right value to get a clearer idea of what’s going on.

PREPARED BY: MAHMUD BAKALE & ALIJAFAR UMAR


The other interesting effect of absolute is that it completely removes an element from
the normal flow of the page. This is easier to see with left-aligned elements, so let’s
temporarily change the justify-content property in our .example rule:
.example {
display: flex;
justify-content: flex-start; /* Update this */
/* ... */
}
In our relative positioning example (the first row), there’s still a space where the
positioned element used to be, but with absolute positioning, that space has vanished.
It’s as if .item-absolute doesn’t even exist to its parent and surrounding elements. Be
sure to change the justify-content back to space-around before moving on.

This behavior isn’t really all that useful most of the time because it would
mean everything on your page needs to be absolutely positioned—otherwise we’d get
unpredictable overlaps of static elements with absolute elements. So, why
does absolute even exist?

PREPARED BY: MAHMUD BAKALE & ALIJAFAR UMAR


(RELATIVELY) ABSOLUTE POSITIONING
Absolute positioning becomes much more practical when it’s relative to some other
element that is in the static flow of the page. Fortunately, there’s a way to change the
coordinate system of an absolutely positioned element.

Coordinates for absolute elements are always relative to the closest container that is a
positioned element. It only falls back to being relative to the browser when none of its
ancestors are positioned. So, if we change .item-absolute’s parent element to be relatively
positioned, it should appear in the top-left corner of that element instead of the browser
window.
.absolute {
position: relative;
}
The .absolute div is laid out with the normal flow of the page, and we can manually
move around our .item-absolute wherever we need to. This is great, because if we want
to alter the normal flow of the container, say, for a mobile layout, any absolutely
positioned elements will automatically move with it.

PREPARED BY: MAHMUD BAKALE & ALIJAFAR UMAR


Notice how we didn’t specify any offset coordinates for .absolute. We’re using relative
positioning for the sole purpose of letting our absolute element hook back into the
normal flow of the page. This is how we safely combine absolute positioning with static
positioning.

FIXED POSITIONING
“Fixed positioning” has a lot in common with absolute positioning: it’s very manual,
the element is removed from the normal flow of the page, and the coordinate system is
relative to the entire browser window. The key difference is that fixed elements don’t
scroll with the rest of the page.

PREPARED BY: MAHMUD BAKALE & ALIJAFAR UMAR


Go ahead and update our third example to use fixed positioning:
.item-fixed {
position: fixed;
bottom: 0;
right: 0;
}
This will place the red image in the bottom-right corner of the screen. Try scrolling the
page, and you’ll discover that it doesn’t move with the rest of the elements on the page,
while the absolutely positioned purple image does.

This lets you create navigation bars that always stay on the screen, as well as those
annoying pop-up banners that never go away.

POSITIONED ELEMENTS FOR ANIMATION


This is a little out of scope, since this tutorial is about HTML and CSS, not JavaScript.
However, animation is one of the primary use cases for relative and absolute
positioning, so let’s take a little peek into the future by animating one of our elements.

These advanced positioning schemes allow JavaScript to move elements around while
avoiding any kind of interaction with surrounding elements. For instance, try copying-
and-pasting the following into [Link] after the third .container element.
The <script> element should be the last thing inside of <body>.

PREPARED BY: MAHMUD BAKALE & ALIJAFAR UMAR


<script>
var left = 0;

function frame() {
var element = [Link]('.item-relative');
left += 2;
[Link] = left + 'px';
if (left >= 300) {
clearInterval(id)
}
}

var id = setInterval(frame, 10)


</script>
This JavaScript code creates a simple animation that continually updates the left property
of the .item-relative. When you reload the page, you should see the blue image float to the
right edge of its container.

This is a pretty rudimentary example, but you can hopefully see how it’s applicable to
fancy UI animations. If you were to try to achieve the same effect by manipulating
the margin or padding properties, you would inadvertently move the statically
positioned boxes and/or the containing .example element, too.

PREPARED BY: MAHMUD BAKALE & ALIJAFAR UMAR


POSITIONED ELEMENTS FOR MENUS
So, those are all the techniques. Let’s do something advanced with them! The rest of
this chapter applies our newfound skills towards a fancy navigation menu with an
interactive dropdown for one of its links. We’ll be building this page entirely from
scratch.

Fixed positioning will let us make the menu stick to the top of the page, and relative
positioning will give us an anchor for the absolutely positioned dropdown. We’ll also
get a chance to talk about navigation menu best practices and see some practical
applications of the pseudo-classes we talked about in CSS Selectors.
For starters, we need a new web page called [Link] that has a header and a simple
top-level menu:
<!DOCTYPE html>
<html lang='en'>
<head>
<meta charset='UTF-8'/>
<title>Awesome!</title>
<link href='[Link]' rel='stylesheet'/>
</head>
<body>
<div class='header'>
<div class='logo'><img src='images/[Link]'/></div>

PREPARED BY: MAHMUD BAKALE & ALIJAFAR UMAR


<ul class='menu'>
<li class='dropdown'><span>Features ▾</span></li>
<li><a href='#'>Blog</a></li>
<li><a href='#'>Subscribe</a></li>
<li><a href='#'>About</a></li>
</ul>
</div>
</body>
</html>
Navigation menus should almost always be marked up as a <ul> list instead of a bunch
of <div> elements. These semantics make your site’s navigation much more accessible
to search engines. Also notice how we’re preparing for our dropdown menu by adding
a class attribute to the first <li> in the list. That <span> will allow us to differentiate the
label from the submenu it reveals.
Next, we need a new stylesheet called [Link] that makes our .header look a little bit
more like a header, among other things:
*{
margin: 0;
padding: 0;
box-sizing: border-box;
}

body {
height: 1200px;
font-size: 18px;
font-family: sans-serif;
color: #5D6063;
}

a:link,
a:visited {
color: #5D6063;
text-decoration: none;
}

PREPARED BY: MAHMUD BAKALE & ALIJAFAR UMAR


a:hover {
text-decoration: underline;
}

.header {
position: fixed;
display: flex;
justify-content: space-between;

width: 100%;
padding: 50px;
background: #D6E9FE;
}
This should all be familiar, but note the fixed position of the .header, which keeps our
navigation menu on top of any content that would go into the page.

INLINE MENU ITEMS


Despite being marked up as unordered lists, the navigation menus for most websites
don’t actually look like a list. We can fix this by making the list items inline
boxes instead of block boxes via the display property. Add the following to [Link]:
.menu {
margin-top: 15px;
}

.menu > li {
display: inline;
margin-right: 50px;

PREPARED BY: MAHMUD BAKALE & ALIJAFAR UMAR


}

.menu > li:last-of-type {


margin-right: 0;
}
We have to use child selectors here instead of descendant selectors because we only
want to select <li> elements that are directly inside the .menu. This will become
important once we add our submenu, which has its own <li> elements that we don’t
want to style with this rule. This snippet also adds margins to all the list items, but
removes it from the final <li> using the :last-of-type pseudo-class. This is a pretty
common technique for creating margins between items.

SUBMENUS
Our submenu is going to look just like the top-level menu, except the whole thing will
be nested inside a list item. Change the .menu element to match the following, ensuring
that the entire .features-menu list is wrapped in the first <li> of the .menu element.
<ul class='menu'>
<li class='dropdown'><span>Features &#9662;</span>
<ul class='features-menu'> <!-- Start of submenu -->
<li><a href='#'>Harder</a></li>
<li><a href='#'>Better</a></li>
<li><a href='#'>Faster</a></li>
<li><a href='#'>Stronger</a></li>
</ul> <!-- End of submenu -->
</li>
<li><a href='#'>Blog</a></li> <!-- These are the same -->
<li><a href='#'>Subscribe</a></li>

PREPARED BY: MAHMUD BAKALE & ALIJAFAR UMAR


<li><a href='#'>About</a></li>
</ul>

This provides a lot of crucial information for search engines. It allows Google to see
that all these new items are associated with the Features label and that they form an
isolated section of our website. You should always mark up complex navigation menus
with this kind of structure.

As for the CSS, we’ll deal with the interactive dropdown part later. Right now, let’s just
get our submenu looking the way we want it to. Add some simple styles so we can see
the box we’re trying to position:

.features-menu {
display: flex;
flex-direction: column;
background: #B2D6FF;
border-radius: 5px;
padding-top: 60px;
}

.features-menu li {
list-style: none;
border-bottom: 1px solid #FFF;

padding: 0 40px 10px 20px;


margin: 10px;
}

.features-menu li:last-of-type {
border-bottom: none;
}
The submenu itself is styled correctly, but it’s showing up in the wrong place and
severely messing up the rest of our top-level menu items. This should be expected

PREPARED BY: MAHMUD BAKALE & ALIJAFAR UMAR


because it’s still statically positioned, which means it still interacts with its parent and
surrounding elements.

To create our desired layout, we need to call on our new CSS positioning skills.

(RELATIVELY) ABSOLUTE SUBMENUS


We want our other top-level menu items to display just like they did before we added
the submenu, as if the submenu wasn’t even there. Wait a second…that’s the exact
behavior of absolutely positioned elements. Let’s give it a shot. Add a few lines to
the .features-menu rule:
.features-menu {
display: flex;
flex-direction: column;
background: #B2D6FF;
border-radius: 5px;
padding-top: 60px;

position: absolute; /* Add these */


top: -25px;

PREPARED BY: MAHMUD BAKALE & ALIJAFAR UMAR


left: -30px;
}
Great! The submenu is no longer part of the static flow of the page, so our top-level
menu items are back to normal. However, the submenu should appear underneath
the Features label—not in the corner of the browser window. What a coincidence…we
just learned how do that!

The submenu resides in <li class='dropdown'>. Turning that into a positioned element
should change the coordinate system used by our absolutely positioned .features-menu:
.dropdown {
position: relative;
}
Ok, next problem. Our submenu is in the right spot, but now it’s covering up
the Features label.

Z-INDEX
We’ve never had to deal with “depth” issues before. Until now, all our HTML elements
rendered above or below one another in an intuitive way. But, since we’re doing advanced
stuff, relying on the browser to determine which elements appear on top of other ones isn’t
going to cut it.

PREPARED BY: MAHMUD BAKALE & ALIJAFAR UMAR


The z-index property lets you control the depth of elements on the page. If you think of
your screen as 3D space, negative z-index values go farther into the page, and positive ones
come out of the page.

In other words, the .features-menu element needs to have a lower z-index than
the Features label. The default z-index value is 0, so let’s make both of them higher than
that. We conveniently wrapped the Features label in a <span>, allowing us to style it via
a child selector, like so:
.dropdown > span {
z-index: 2;
position: relative; /* This is important! */
cursor: pointer;
}

.features-menu {
/* ... */
z-index: 1;
}
The Features label should now appear on top of the submenu. Take note of
that position: relative; line. It’s required because only positioned elements pay attention
to their z-index property. This is easy to forget, so make a mental note for the next time
you’re having depth issues and your CSS rules don’t seem to have any effect.

PREPARED BY: MAHMUD BAKALE & ALIJAFAR UMAR


We threw in an example of the cursor property to make it look like a link when the user
hovers over the label. You can read more about it at Mozilla Developer Network.

PSEUDO-CLASSES FOR DROPDOWN MENUS


Alright! Submenu done! Our final task is to hide it until the user hovers over it.
Remember that :hover pseudo-class from the CSS Selectors chapter? We can use that to
turn our submenu into an interactive dropdown.

First, we need to change our existing .features-menu rule to only show the submenu
when the user hovers over it by adding a :hover descendant selector. Update
the .features-menu selector to match the following:
.dropdown:hover .features-menu { /* This used to be `.features-menu` */
display: flex; /* Leave everything else alone */
flex-direction: column;
background: #B2D6FF;
/* ... */
}
Then, we need to initially hide the submenu using the display property. Add a new
rule to [Link]:
.features-menu { /* Add this as a new rule */

PREPARED BY: MAHMUD BAKALE & ALIJAFAR UMAR


display: none;
}
Setting display to none makes an element completely disappear. By overriding that
value with flex in the :hover rule, we’re effectively telling the browser to show
the .features-menu again. This clever combination of descendant selectors and pseudo-
classes enables us to conditionally hide or show an element.

SUMMARY
In this chapter, we took a look at four new CSS layout schemes:

• Relative
• Absolute
• Relatively absolute
• Fixed
Relative positioning was for tweaking the position of an element without affecting its
surrounding boxes. Absolute positioning took elements out of the static flow of the page
and placed them relative to the browser window, while relatively absolute positioning
allowed us to hook back into the static flow of the page. Finally, fixed positioning let
us make elements that didn't scroll with the rest of the page.

PREPARED BY: MAHMUD BAKALE & ALIJAFAR UMAR


We used these new positioning techniques to create a rather sophisticated navigation
menu. If it felt complicated, that’s cause it was. But don’t worry, you shouldn’t feel
pressure to memorize the HTML and CSS behind our menu. Your goal should be to
have the ability to reference this example three months from now and understand what
all those position: relative; and position: absolute; declarations are doing.

This menu was also a pretty good example of how starting with the HTML markup
makes life a lot easier. First, we created the semantic structure we wanted. Then, we
wrote some fancy CSS to position the boxes right where we wanted them. Whenever
you’re looking at a complicated mockup and not sure where to start, this is good way
to approach the problem.

There’s still one big issue with our menu: it’s not built for mobile devices. Smartphones
and tablets don’t have a way to hover, and our layout doesn’t display well when the
browser is narrower than 960 pixels. The former requires a little bit of JavaScript magic
(or some really advanced CSS), so we’ll leave that for another tutorial. But, we will be
able to tackle the latter problem with some responsive design in the next chapter.

PREPARED BY: MAHMUD BAKALE & ALIJAFAR UMAR


RESPONSIVE DESIGN
Nº 10. of HTML & CSS Is Hard
A beginner’s tutorial for crafting mobile-friendly websites

“Responsive design” refers to the idea that your website should display equally well in everything
from widescreen monitors to mobile phones. It’s an approach to web design and development that
eliminates the distinction between the mobile-friendly version of your website and its desktop
counterpart. With responsive design, they’re the same thing.

Responsive design is accomplished through CSS “media queries”. Think of media queries as a
way to conditionally apply CSS rules. They tell the browser that it should ignore or apply certain
rules depending on the user’s device.

PREPARED BY: MAHMUD BAKALE & ALIJAFAR UMAR


Media queries let us present the same HTML content as distinct CSS layouts. So, instead of
maintaining one website for smartphones and an entirely unrelated site for laptops/desktops, we
can use the same HTML markup (and web server) for both of them. This means that whenever we
add a new article or edit a typo in our HTML, those changes are automatically reflected in both
mobile and widescreen layouts. This is the reason why we separate content from presentation.

In this chapter, we’ll learn how media queries are really just a thin wrapper around the plain old
CSS that we’ve been working with up ’til this point. As we’ll soon discover, it’s actually pretty
easy to implement a responsive layout. (Responsive Images, on the other hand, are an entirely
different story).

PREPARED BY: MAHMUD BAKALE & ALIJAFAR UMAR


SETUP
Create a new project called responsive-design and a new file called [Link]. It’s
the emptiest web page that we’ve seen in a while, but it’ll help us demonstrate something
very important in the next section:
<!DOCTYPE html>
<html lang='en'>
<head>
<meta charset='UTF-8'/>
<title>Responsive Design</title>
<link rel='stylesheet' href='[Link]'/>
</head>
<body>
<!-- There's nothing here! -->
</body>
</html>
You’ll also need to download some images for later in the chapter. Unzip everything into the same
folder as [Link], keeping the parent images folder. Your project should look like this
before moving on:

CSS MEDIA QUERIES


We’ll start small by simply updating the background color on the <body> element based
on the device width. This is a good way to make sure our media queries are actually
working before getting into complicated layouts.

PREPARED BY: MAHMUD BAKALE & ALIJAFAR UMAR


Let’s differentiate between narrow, medium, and wide layouts by creating a
new [Link] stylesheet and adding the following:
*{
margin: 0;
padding: 0;
box-sizing: border-box;
}

/* Mobile Styles */
@media only screen and (max-width: 400px) {
body {
background-color: #F09A9D; /* Red */
}
}

/* Tablet Styles */
@media only screen and (min-width: 401px) and (max-width: 960px) {
body {
background-color: #F5CF8E; /* Yellow */
}
}

/* Desktop Styles */
@media only screen and (min-width: 961px) {
body {
background-color: #B2D6FF; /* Blue */

PREPARED BY: MAHMUD BAKALE & ALIJAFAR UMAR


}
}
When you resize your browser, you should see three different background colors: blue
when it’s greater than 960px wide, yellow when it’s between 401px and 960px, and red
when it’s less than 400px.

Media queries always begin with the @media “at-rule” followed by some kind of
conditional statement, and then some curly braces. Inside the curly braces, you put a bunch
of ordinary CSS rules. The browser only pays attention to those rules if the condition is
met.

The only screen “media type” means that the contained styles should only be applied to
devices with screens (opposed to printed documents, like when you hit Cmd+P in a
browser). The min-width and max-width parts are called “media features”, and they
specify the device dimensions you’re targeting.

The above media queries are by far the most common ones you’ll encounter, but there are
a lot of other conditions you can check for, including whether the device is in portrait or
landscape mode, the resolution of its screen, and whether it has a mouse or not.

A FEW NOTES ON DESIGN


Ok, so @media is how we define different layouts for specific device widths, but what
layouts are we actually trying to implement? The example web page for this chapter is
going to look something like this:

PREPARED BY: MAHMUD BAKALE & ALIJAFAR UMAR


In the real world, it’s up to your web designer to supply you with these kinds of mockups.
Your job as a developer is to implement the individual layouts using media queries to
separate out the various CSS rules that apply to each one.

There’s a few well defined patterns for how a desktop layout collapses into a mobile layout
(we’re using “layout shifter”). A lot of these decisions are in the realm of design, which is
outside the scope of this code-oriented tutorial; however, there are two concepts that you
must understand as a developer:
• A “fluid” layout is one that stretches and shrinks to fill the width of the screen,
just like the flexible boxes we covered a few chapters ago.
• A “fixed-width” layout is the opposite: it has the same width regardless of the
screen dimensions (we created one of these in the CSS Selectors chapter).

PREPARED BY: MAHMUD BAKALE & ALIJAFAR UMAR


In our example web page, the mobile and tablet versions are fluid, and the desktop version
is fixed-width.

CHOOSING BREAKPOINTS
Most of those responsive design patterns have similar behavior, using fluid layouts for
mobile/tablet devices and fixed-width layouts for wider screens. There’s a reason for this.
Fluid layouts let us target a range of screen widths instead of specific mobile devices. This
is very important for web designers. When they set out to create a mobile layout, they aren’t
trying to make something that looks good on an iPhone 6s, Galaxy S7, or iPad mini—
they’re designing a fluid layout that looks good anywhere between 300 pixels and 500
pixels (or whatever).

In other words, the exact pixel values for the min-width and max-width parameters in a
media query (collectively known as the “breakpoints” for a responsive website) don’t
actually matter. Our website doesn’t care about the specific device the user is on. All it
needs to know is that it should display a layout that looks pretty at 400 pixels wide (or
whatever).

MOBILE-FIRST DEVELOPMENT
Let’s dive right into implementing the above screenshots. It’s always a good idea to start
with the mobile layout and work your way up to the desktop version. Desktop layouts are

PREPARED BY: MAHMUD BAKALE & ALIJAFAR UMAR


typically more complex than their mobile counterparts, and this “mobile-first” approach
maximizes the amount of CSS that you can reuse across your layouts.

First, we need to fill in [Link]’s <body> element with some empty boxes. Each
box has an image in it so we can tell them apart a little bit easier.
<div class='page'>
<div class='section menu'></div>
<div class='section header'>
<img src='images/[Link]'/>
</div>
<div class='section content'>
<img src='images/[Link]'/>
</div>
<div class='section sign-up'>
<img src='images/[Link]'/>
</div>
<div class='section feature-1'>
<img src='images/[Link]'/>
</div>
<div class='section feature-2'>
<img src='images/[Link]'/>
</div>
<div class='section feature-3'>
<img src='images/[Link]'/>
</div>
</div>
And here’s our base styles, which should apply to all layouts (mobile, tablet, and desktop).
Make sure to add these above the @media rules we created earlier and below the universal
selector rule that resets our margins and padding:
.page {
display: flex;
flex-wrap: wrap;
}

PREPARED BY: MAHMUD BAKALE & ALIJAFAR UMAR


.section {
width: 100%;
height: 300px;
display: flex;
justify-content: center;
align-items: center;
}

.menu {
background-color: #5995DA;
height: 80px;
}

.header {
background-color: #B2D6FF;
}

.content {
background-color: #EAEDF0;
height: 600px;
}

.sign-up {
background-color: #D6E9FE;
}

.feature-1 {
background-color: #F5CF8E;
}

.feature-2 {
background-color: #F09A9D;
}

.feature-3 {
background-color: #C8C6FA;

PREPARED BY: MAHMUD BAKALE & ALIJAFAR UMAR


}
If you make the browser window narrow, you'll see that this gives us our entire mobile
layout. Pretty easy, huh? No media queries required. That’s why it’s called “mobile-
first”—the mobile version doesn’t require any special handling. Also notice that flex-
wrap property in the containing .page div. This will make it very easy to implement our
tablet and desktop layouts.

By keeping these base styles outside of the media queries, we’re able to override and add
on to them as we implement our specific layouts. This is really convenient when, for
instance, your designer wants to tweak the color scheme for the entire website. Instead of
tracking down redundant background-color declarations in several @media rules, you
only have to update it here. That change automatically applies to the mobile, tablet, and
desktop layouts.

PREPARED BY: MAHMUD BAKALE & ALIJAFAR UMAR


TABLET LAYOUT
On to the tablet layout. The only difference between the mobile and tablet mockups is that
the Sign Up and Feature sections form a 2×2 grid instead of a single column.
Flexbox makes this real easy. Simply adjust the widths of the flex items to be half the
screen and flex-wrap will take care of the rest. Of course, we only want this behavior to
apply to tablet-sized screens, so it needs to go into an @media rule. Replace the existing /*
Tablet Styles */ media query with the following:
/* Tablet Styles */
@media only screen and (min-width: 401px) and (max-width: 960px) {
.sign-up,
.feature-1,
.feature-2,
.feature-3 {
width: 50%;
}
}
To see these changes, make sure your browser window is between 400 pixels and 960
pixels wide, then scroll down to the bottom of the page. You should see a colorful grid:

PREPARED BY: MAHMUD BAKALE & ALIJAFAR UMAR


Again, it doesn’t matter what the exact width of the screen is: this layout will fluidly
respond to any width in the media query’s range. Our mobile layout is also fluid, so we
now have a website that looks beautiful (if a bit empty) in every device smaller
than 960px wide.

DESKTOP LAYOUT
And that’s where our desktop layout comes in. We don’t want our web page to expand
endlessly, so we’re going to give it a fixed width and center it with auto-margins. As with
tablet styles, this needs to go into a media query. Replace the existing /* Desktop Styles
*/ media query with the following:
/* Desktop Styles */
@media only screen and (min-width: 961px) {
.page {
width: 960px;
margin: 0 auto;
}
.feature-1,
.feature-2,

PREPARED BY: MAHMUD BAKALE & ALIJAFAR UMAR


.feature-3 {
width: 33.3%;
}
.header {
height: 400px;
}
}
This gives us the correct widths for everything, and we have more real estate to play with,
so we made the header a little taller, too. Almost there, but our desktop layout calls for
some reordering: the Sign Up and Content boxes should appear underneath all
the Feature sections.

This is where flexbox really shines. Trying to create this combination of mobile and
desktop layouts would be very difficult with floats. With flexbox’s order property, it’s just
a few lines of CSS. Append these rules to the desktop media query:
.sign-up {
height: 200px;
order: 1;
}
.content {
order: 2;

PREPARED BY: MAHMUD BAKALE & ALIJAFAR UMAR


}
Ta da! A responsive website! Not bad for less than a hundred lines of CSS. More
importantly, we didn’t have to alter a single line of HTML to accommodate our mobile,
tablet, and desktop layouts.

This was just one example of laying out a responsive site. You can use these exact same
techniques to implement all sorts of other designs. Start with the base styles that apply to
your entire site, then tweak them for various device widths by selectively applying CSS
rules with @media. You could even add another media query to, say, create a dedicated
layout for ultra-widescreen monitors.

DISABLING VIEWPORT ZOOMING


We’ve got one final task for making a responsive web page. Before responsive design was
a thing, mobile devices only had a desktop layout to work with. To cope with this, they
zoomed out to fit the entire desktop layout into the width of the screen, letting the user
interact with it by zooming in when necessary.

This default behavior will prevent mobile devices from using our mobile layout, which is
obviously very terrible. To disable it, add the following element to the <head> of our

PREPARED BY: MAHMUD BAKALE & ALIJAFAR UMAR


document. Just like <meta charset='UTF-8'/>, this is a critical element that should be on
every single web page you create:
<meta name='viewport'
content='width=device-width, initial-scale=1.0, maximum-scale=1.0' />
To see this in action, we’ll need to simulate a mobile device in our desktop browser. This
is a little advanced for where we’re at right now, but we can give it a shot. Open
up [Link] in Google Chrome, then hit View > Developer > Developer Tools in
the menu bar. Then, to simulate a mobile device, click the Toggle Device Toolbar icon,
highlighted below.

You should see the zoom-disabled version of the above diagram in your browser, since it’s
now pretending to be a mobile device. (We’ll save the in-depth discussion of Chrome dev
tools for a future tutorial.)

Alternatively, if you’re reading this chapter on a smartphone, you can navigate to the
live before and after versions of our example project to experience the effect of
our viewport changes.

SUMMARY
Believe it or not, that’s actually all you need to know to create responsive websites. If we
boil it down, we’re really only concerned with three things:

• The responsive design (the mockups for each layout)

PREPARED BY: MAHMUD BAKALE & ALIJAFAR UMAR


• CSS rules for implementing each of those layouts
• Media queries for conditionally applying those CSS rules

We started this chapter by learning about the difference between fluid layouts and fixed-
width layouts. Then, we went on to create a mobile-first stylesheet that used media queries
to build tablet and desktop layouts on top of a shared set of base styles. Finally, we disabled
the default viewport zoom behavior of mobile browsers.

So, that was the easy part of responsive design. In the next chapter, we’ll discover the hard
part: images. Presenting different CSS to specific devices isn’t too bad, but optimizing
images for those devices requires a bit more planning.

RESPONSIVE IMAGES
Nº 11. of HTML & CSS Is Hard
Responsive images are hard. Like, actually hard. But don’t be scared.

In Responsive Design, we learned how to use media queries to create separate mobile,
tablet, and desktop layouts. Now, we’re going to add images to the mix. Just as media
queries let us conditionally present different CSS rules, we want to display different images
based on the user’s device.

PREPARED BY: MAHMUD BAKALE & ALIJAFAR UMAR


The problem is, images have inherent dimensions. We can’t stretch a photo that’s 500×250
pixels to anything beyond 500 pixels wide because it’ll get pixelated. Retina displays and
mobile devices complicate things even more. To make our images responsive, we now
have to take three things into consideration:
• The device’s dimensions
• The image’s dimensions
• The device’s screen resolution
This will be more difficult than media queries, which were only concerned with device
width. But don’t worry, there are standard ways to solve all these problems, and we’ll walk
you through them one step at a time.

SETUP
To experiment with responsive images, we need a responsive website to work with. This chapter
will be building off of the example web page we put together in the previous chapter. We’ll be
adding two images to the page so it looks like the following. This might seem simple, but these
images will change depending on the user’s device (which is really cool).

PREPARED BY: MAHMUD BAKALE & ALIJAFAR UMAR


If you’re continuing from the last chapter, you simply need to download these image
assets and add them to your project’s images/ folder.

If you’re just joining us, go ahead and download the complete example project, unzip it,
and open it up with Atom. If you’re not familiar with the Atom text editor, be sure to take
a read through the introduction of this tutorial series.

PREPARED BY: MAHMUD BAKALE & ALIJAFAR UMAR


In either case, your project files should look like this before moving on. Notice how we
have multiple copies of our PNG and JPG images (e.g., illustration-
[Link] and [Link]). We’ll be letting the browser pick which one of these it
should load depending on the device’s size and screen resolution.

RETINA SCREENS
This is our first time worrying about retina devices, so let’s talk a little bit about screen
resolution. Retina screens have twice as many pixels per inch than standard-resolution
screens. That is to say, each retina pixel is the equivalent of 4 standard pixels. This has a
big impact on how images are displayed in a web browser.

PREPARED BY: MAHMUD BAKALE & ALIJAFAR UMAR


To render correctly on a retina device, an image needs to be twice as big as its final display
dimensions. For example, if you want to add a 500×250 pixel image to the page, the
corresponding image file needs to be 1000×500 pixels.

This is actually a bit of a simplification—not all retina screens are created equal. For
instance, the iPhone 6 Plus has three times as many pixels per inch as a standard screen.
This tutorial focuses on the 2x use case, but the same techniques apply to 3x retina screens
as well.

What’s more, standard displays and smaller devices don’t need all those extra pixels in
high-resolution images, and sending that much unnecessary data usually results in a bad
user experience.

PREPARED BY: MAHMUD BAKALE & ALIJAFAR UMAR


RESPONSIVE SVG IMAGES
The easiest way to solve all these problems is with SVG images. They “just work.” Since
they’re vector-based, SVGs avoid the screen resolution problems that we’ll see in the next
section. Let’s take a look by adding an illustration to our [Link] page. Replace
the existing image in the .content div so that it matches the following:
<div class='section content'>
<img class='illustration' src='images/[Link]' />
</div>
Browsers automatically scale up SVGs for retina devices, so this 500×250 pixel SVG
image will render crisply on both standard and retina devices.

SVGs let us forget about screen resolution issues, but we do need to shrink the illustration
to fit neatly into our fluid tablet and mobile layouts. Firefox will do this automatically, but
if you open this page with Chrome and make your browser very narrow, you’ll find that
the image stays the same size.

To get a fluid image in Chrome, we need to tell the illustration to always fill the width of
its container. In [Link], put the following rule with the rest of the base styles, outside of
the media queries:
.illustration {
width: 100%;
}
When we specify 100% width on an image, it’ll assume we want to maintain its aspect
ratio and calculate its height automatically. This fixes the mobile layout, but now the
desktop version is huge:

PREPARED BY: MAHMUD BAKALE & ALIJAFAR UMAR


This behavior is perfect for some designs (like the full bleed photo we’ll see in the next
section), but not right now. We want to cap the width of the illustration to its inherent
width, which is 500 pixels. We can do this with an inline style:
<div class='section content'>
<img class='illustration' src='images/[Link]' style='max-width: 500px'/>
</div>
This is one of the rare times an inline style is acceptable, due to the fact that it’s describing
an innate property of the image. An image’s physical dimensions are more content than
presentation, so it makes sense for this to appear in the HTML rather than the stylesheet.

PREPARED BY: MAHMUD BAKALE & ALIJAFAR UMAR


RESPONSIVE PNG, GIF, AND
JPG IMAGES
Of course, not all images on the web are SVGs. Sometimes you need to include a photo.
PNG, GIF, and JPG images are “raster images”, meaning that they are defined pixel-by-
pixel instead of with vectors. As a result, they are much more sensitive to screen resolution
than SVGs.

If you’re not worried about optimization, responsive raster images really aren’t that much
harder than using SVG images. Try swapping out our existing [Link] with a PNG
file:
<div class='section content'>
<div class='illustration'>
<img src='images/[Link]' style='max-width: 500px'/>
</div>
</div>

PREPARED BY: MAHMUD BAKALE & ALIJAFAR UMAR


We changed around the HTML structure a bit, nesting our <img/> tag in another container.
Without it, the image would get distorted because flexbox would try to set its height to be
the same as the .content container. This requires a little tweak to our .illustration CSS rule,
too:
.illustration img {
width: 100%;
display: block;
}
Also notice the -big suffix in the image’s filename. This is the high-resolution version of
the PNG, which has dimensions of 1000×500. Retina devices need this “2x” size to display
the image crisply. If we were to use the low-resolution version of this image (500×250
pixels), it would look fine on standard screens, but fuzzy on retina devices.

Consider this the lazy way to create responsive PNG, GIF, or JPG images, as it assumes
everybody needs a high-resolution image, even if they don’t. That is to say, a 1000×500
pixel image is overkill for non-retina devices. We’ll get a little smarter about this in the
next section.

PREPARED BY: MAHMUD BAKALE & ALIJAFAR UMAR


RESPONSIVE IMAGE OPTIMIZATION
Different devices have different image requirements. Fortunately, HTML provides a way
to choose the best image for the user’s device. Over the next few sections, we’ll take a look
at three scenarios for optimizing responsive images:
• A standard-resolution screen that doesn’t need a retina-quality image.
• A retina mobile device that can use a standard-quality image because it’s been
scaled down so much.
• A desktop layout that uses a wide image, and an associated mobile layout that
uses a taller image.
The first method is the easiest, and it’s great for images smaller than 600 pixels wide
because they aren’t big enough to benefit from the second scenario. The second method is
a very important optimization for larger images, especially full-bleed photos. The third is
for when you’re feelin’ fancy.

RETINA OPTIMIZATION USING SRCSET


High-resolution images are big. Our [Link] file takes up more than twice as
much disk space as its low-resolution counterpart. It doesn’t make sense to serve all that
extra data when the user doesn’t actually need it.

Adding a srcset attribute to our <img/> element lets us present our high-resolution
image only to retina devices, falling back to the low-resolution version for standard
screens. Update our .illustration element to match the following:
<div class='illustration'>
<img src='[Link]'
srcset='images/[Link] 1x,
images/[Link] 2x'
style='max-width: 500px'/>
</div>

PREPARED BY: MAHMUD BAKALE & ALIJAFAR UMAR


The srcset attribute points to a list of alternative image files, along with properties defining
when the browser should use each of them. The 1x tells the browser to display illustration-
[Link] on standard-resolution screens. The 2x means that [Link] is for
retina screens. Older browsers that don’t understand srcset fall back to the src attribute.

Typically, the low-res and high-res versions of an image would be the exact same (except
for their dimensions), but we made [Link] yellow so you can easily
differentiate it from the retina version, which is blue.

It’s a little hard to see this in action without a real website, so we included the previous
snippet on this page. The image below should be blue if you’re viewing it on a retina
device. Otherwise, it will be yellow for standard-resolution screens.

PREPARED BY: MAHMUD BAKALE & ALIJAFAR UMAR


If you’re building these examples on a computer with a retina screen, you can also try
temporarily changing that 2x to 1x to see what a non-retina image looks like. It’s a little
fuzzy (and yellow).

SCREEN WIDTH OPTIMIZATION USING SRCSET


Great! We can save some extra bytes for non-retina devices. Regrettably, the
above srcset technique misses an important use case for larger images: if the user has a
retina smartphone, it’ll download the high-resolution image even when the standard
version would suffice.

PREPARED BY: MAHMUD BAKALE & ALIJAFAR UMAR


Imagine that we wanted to display a big photo in our .header element. The header is 960
pixels wide in our desktop layout, so our photo needs to be at least 1920 pixels wide to
display well on retina screens. We’ll also provide a 960 pixel-wide photo for standard
screens. Now, consider a smartphone with a retina screen. Smartphones are typically less
than 400 pixels wide in portrait mode, which means that the corresponding retina-quality
image would only need to be 800(ish) pixels wide.

Hey! We can serve our standard-resolution photo to retina smartphones!

The lesson here is that we want to optimize larger images based on their final rendered
dimensions, not just the device’s screen resolution. Let’s go ahead and add that big photo
to our .header element:
<div class='section header'>
<div class='photo'>
<img src='images/[Link]'
srcset='images/[Link] 2000w,
images/[Link] 1000w'
sizes='(min-width: 960px) 960px,
100vw'/>
</div>
</div>
We have the same srcset element as the last section, but instead of
the 1x and 2x descriptors, we’re providing the inherent physical width of the image.
The 2000w tells the browser that the [Link] file is 2000 pixels wide. Likewise,
the 1000w means [Link] has a width of 1000 pixels. If you’re wondering about
that w character, it’s a special unit used only for this kind of image optimization scenario.

PREPARED BY: MAHMUD BAKALE & ALIJAFAR UMAR


Image width alone isn’t enough for a device to determine which image it should load. We
also need to tell it what the final rendered width of the image will be. That’s where
the sizes attribute comes in. It defines a series of media queries along with the image’s
rendered width when that media query is in effect.

PREPARED BY: MAHMUD BAKALE & ALIJAFAR UMAR


Here, we’re saying that when the screen is at least 960px wide, the image will also be 960
pixels wide. Otherwise, the 100vw default value tells the browser that the image’s width
will be 100% of the “viewport width” (a fancy term for screen width). You can read more
about the vw unit over at MDN. All of this matches the image resizing behavior that’s in
our CSS.

Speaking of which, we need to make some changes to position our new header image
correctly. Add both of the following rules to our other base styles, right above the mobile
styles media query:
.header {
height: auto;
justify-content: inherit;

PREPARED BY: MAHMUD BAKALE & ALIJAFAR UMAR


align-items: inherit;
}

.photo img {
width: 100%;
display: block;
}
Remember that our low-resolution photo is 1000 pixels wide, which means that 2x retina
devices can use it as long as their screen is less than 500 pixels wide. In Firefox, you should
now be able to resize the browser to see the retina version (“Big”) when the window is
wider than 500 pixels and the non-retina version (“Small”) for narrower widths.

We’re now serving a 115KB image to mobile devices instead of forcing them to use the
high-res 445KB image. That’s a big deal, especially for websites that use a lot of photos.

TESTING WITH CHROME


This technique works just fine in Chrome, but we can’t really tell because it’s being clever.
Chrome will always use the high-res version if it has already been cached locally, which
means we can’t see the low-res version by simply making the browser window narrow. We
have to avoid the local browser cache by opening a new incognito window, then avoid
loading [Link] by making the window very narrow before loading the page.

ART DIRECTION USING <PICTURE>


The previous section is perfectly acceptable in terms of optimizing data usage. We could
stop there and be just fine, but we’re going to get a little bit fancier with “art direction”.
Think of art direction as responsive image optimization for designers.

It lets you optimize layouts by sending completely different images to the user depending
on their device. Compare this to the previous section, which optimized the same image for
different devices. For instance, our header photo is pretty wide. Wouldn’t it be great if we

PREPARED BY: MAHMUD BAKALE & ALIJAFAR UMAR


could crop a taller version and present that to mobile devices instead of the wide desktop
version?

For this, we need the <picture> and <source> elements. The former is just a wrapper, and
the latter conditionally loads images based on media queries. Try changing
our .header element to the following:
<div class='section header'>
<div class='photo'>
<picture>
<source media='(min-width: 401px)'
srcset='images/[Link]'/>
<source media='(max-width: 400px)'
srcset='images/[Link]'/>
<img src='images/[Link]'/>
</picture>
</div>
</div>
Conceptually, this is pretty similar to using media queries in CSS. In
each <source> element, the media attribute defines when the image should be loaded,
and srcset defines which image file should be loaded. The <img/> element is only used as

PREPARED BY: MAHMUD BAKALE & ALIJAFAR UMAR


a fallback for older browsers. You should be able to see the tall version of the photo when
you shrink your browser window:

This level of control will make your designer very happy, but the trade off is that it doesn’t
let the browser automatically pick the optimal image. This means we lost our retina
optimization from the previous section: as long as the screen width is 401 pixels or greater,
the browser will always use the high-resolution, wide-cropped image.

While it is possible to combine the best of both worlds, it gets complicated real quick. Our
recommendation is to stick to the 1x and 2x version of srcset for images less than 600
pixels wide, use the srcset plus sizes method from the previous section for bigger photos,
and reserve <picture> for when you’re trying to do something real fancy with your
designer.

PREPARED BY: MAHMUD BAKALE & ALIJAFAR UMAR


SUMMARY
Responsive images may seem rather complicated, but there’s really only two problems
we’re trying to solve:

• Make images fit into mobile layouts while respecting their intrinsic size
• Avoid making the user download unnecessarily large image files
We accomplished the former by making images always stretch to fill 100% of their
container while limiting their size with an inline max-width style. For the latter, we
used srcset to optimize for screen resolution, srcset plus sizes to optimize for device width,
and finally the <picture> element for manual control over which image file is displayed.

Responsive design is an evolving topic. Browsers only recently implemented the image
optimization techniques covered in this chapter, despite the fact that responsive design has
been the standard for half a decade. While the technology used to create a responsive
website may change, the fundamental problem of presenting the same content to different
devices will never disappear. So, even if you eventually need to learn some new tools, the
foundational concepts we just introduced should stay with you forever.

These last five chapters focused entirely on layout. We explored floats, flexbox, advanced
positioning, and how to apply all those concepts to various screen widths. This is pretty
much everything you’ll ever need to lay out web pages with HTML and CSS. The next
chapter scuffles back into the world of HTML, introducing a bunch of new elements that
will make search engines much happier with our websites.

PREPARED BY: MAHMUD BAKALE & ALIJAFAR UMAR


SEMANTIC HTML
Nº 12. of HTML & CSS Is Hard
A friendly tutorial for developing meaningful web pages

“Semantic HTML” refers to the idea that all your HTML markup should convey the
underlying meaning of your content—not its appearance. We’ve already been writing
semantic HTML (e.g., using <strong> instead of <b>), but there’s a whole set of
elements designed for the sole purpose of adding more meaning to the overall layout of
a web page. They’re called “sectioning elements”, and they look something like this:

Using these as an alternative to <div> elements is an important aspect of modern web


development because it makes it easier for search engines, screen readers, and other
machines to identify the different parts of your website. It also helps you as a developer
keep your site organized, which, in turn, makes it easier to maintain.

PREPARED BY: MAHMUD BAKALE & ALIJAFAR UMAR


We’re going back to straight HTML this chapter—no box model, flexbox, or positioning
schemes. However, that’s not to say you can’t apply all of the CSS rules from previous
chapters to these new elements. Think of sectioning elements as <div>’s, but
with meaning.

SETUP
Our example for this chapter will be a simple unstyled HTML document. Create a
new Atom project called semantic-html with a new file in it called [Link]. Add the
following:
<!DOCTYPE html>
<html lang='en'>
<head>
<meta charset='UTF-8'/>
<title>Semantic HTML</title>
</head>
<body>

<h1>Interneting Is Easy!</h1>
<ul>
<li><a href='#'>Home</a></li>

PREPARED BY: MAHMUD BAKALE & ALIJAFAR UMAR


<li><a href='#'>About</a></li>
<li><a href='#'>Blog</a></li>
<li><a href='#'>Sign Up</a></li>
</ul>
</body>
</html>
That <h1> and <ul> are presumably the top-level banner for our website—not the
main content of the web page. We’ve never had to make this distinction before, but
that’s what this whole chapter is about.

THE DOCUMENT OUTLINE


Every HTML document has an “outline,” which is how search engines and screen
readers view the hierarchy of the content on the page. The <h1> through <h6> heading
elements all contribute to a page’s document outline. Let’s check it out by adding a
dummy blog post to our [Link] file:
<h1>Semantic HTML</h1>
<p>By Troy McClure. Published January 3rd</p>
<p>This is an example web page explaining HTML5 semantic markup.</p>

<h2>The Document Outline</h2>


<p>HTML5 includes several “sectioning content” elements that
affect the document outline.</p>

<h3>Headers</h3>
<p>The <code>&lt;header&gt;</code> element is one such sectioning
element.</p>

<h3>Footers</h3>
<p>And so is the <code>&lt;footer&gt;</code> element.</p>

<h2>Inline Semantic HTML</h2>


<p>The <code>&lt;time&gt;</code> element is semantic, but it’s not
sectioning content.</p>

PREPARED BY: MAHMUD BAKALE & ALIJAFAR UMAR


<p>This fake article was written by somebody at [Link], which
is a pretty decent place to learn how to become a web developer.</p>

<p>&copy; 2017 [Link]</p>


The HTML5 Outliner is a convenient tool for inspecting the document outline of a page.
Go ahead and paste the entirety of [Link] into the text field at the bottom. You
should see the outline for our example, which currently has the following structure. It’s
a little reminiscent of the research paper outlines you learned to make in elementary
school.

Each <h1> element creates a new section in the document outline, and any less
prominent headings that follow it are considered subsections under that top-level
heading. E.g., the Semantic HTML section has two subsections in it: The Document
Outline and Inline Semantic HTML. The same goes for <h2> and <h3> elements,
and so on down to <h6>.

PREPARED BY: MAHMUD BAKALE & ALIJAFAR UMAR


Note that the actual value of the heading level doesn’t matter: what’s important is
whether or not it’s greater than or less than the heading of the current section. For
example, change the <h3> headings to <h4> and run it through the outliner tool again.
Since the <h4> is still less than the parent <h2>, this shouldn’t have any affect on the
document outline.

How’s this document outline stuff relate to semantic HTML? Well, headings are some of
the most semantic things in a web page. They play a significant role in how search engines
determine what’s important in your web page. In addition, the semantic HTML elements
we’re about to cover add more meaning to and sometimes even alter the default outlining
behavior discussed here.

ARTICLES
The <article> element represents an independent article in a web page. It should only
wrap content that can be plucked out of your page and distributed in a completely
different context. For instance, an app like Flipboard should be able to grab
an <article> element from your site, display it in its own app, and have it make perfect
sense to its readers.

PREPARED BY: MAHMUD BAKALE & ALIJAFAR UMAR


In our example, we can use <article> to mark the main content of the page as a self-
contained unit, like so:
<article>
<h1>Semantic HTML</h1>
<p>By Troy McClure. Published January 3rd</p>
<p>This is an example web page explaining HTML5 semantic markup.</p>
<!-- ... -->
<p>This fake article was written by somebody at [Link], which
is a pretty decent place to learn how to become a web developer.</p>
</article>

<p>&copy; 2017 [Link]</p>


Notice how we left the copyright notice outside the <article> element because it’s a footer
for the entire site—not specifically for our article. As we’ll discover shortly, <article>’s
are essentially mini web pages in your HTML document. They have their own headers,
footers, and document outline that are completely isolated from the rest of your site.

USING MULTIPLE ARTICLE ELEMENTS


For things like blog posts, newspaper articles, or web pages dedicated to a single topic,
there’s often only one <article> element on the page. But, it’s perfectly legal to have more
than one <article> element per page. A good example is a page that displays a bunch of

PREPARED BY: MAHMUD BAKALE & ALIJAFAR UMAR


blog posts. Each one of them can be wrapped in a separate set of <article> tags (you don’t
need to add this to our [Link] page):
<article>
<h1>First Post</h1>
<p>Some content</p>
</article>
<article>
<h1>Second Post</h1>
<p>Some more content</p>
<h2>Subsection</h2>
<p>Some details</p>
</article>
<article>
<h1>Last Post</h1>
<p>Final bit of content</p>
</article>
This tells anybody looking at our page that there are three distinct articles that can be
syndicated. Think of it as a way to merge multiple HTML files into a single document
without confusing search engines, browsers, or other machines that are trying to parse
our content.

Compare this to a bunch of generic <div> elements with arbitrary class names, and you
can begin to see how semantic HTML makes the Web a much easier place to navigate.

SECTIONS
The <section> element is sort of like an <article>, except it doesn’t need to make sense
outside the context of the document. That is, an app like Flipboard wouldn’t try to pull out
all the <section>’s of your page and present them as independent pieces of content.

PREPARED BY: MAHMUD BAKALE & ALIJAFAR UMAR


Think of <section> as an explicit way to define the sections in a document outline. Why
would we want this instead of letting the heading levels do it for us? Often times, you
need a container to wrap a section for layout purposes, and it makes sense to use the
more descriptive <section> element over a generic <div>.
Let’s section off two parts of our [Link] file:
<section> <!-- Add this -->
<h2>The Document Outline</h2>
<p>HTML5 includes several “sectioning content” elements that
affect the document outline.</p>

<h3>Headers</h3>
<p>The <code>&lt;header&gt;</code> element is one such sectioning
element.</p>

<h3>Footers</h3>
<p>And so is the <code>&lt;footer&gt;</code> element.</p>
</section> <!-- And this -->

PREPARED BY: MAHMUD BAKALE & ALIJAFAR UMAR


<section> <!-- This too! -->
<h2>Inline Semantic HTML</h2>
<p>The <code>&lt;time&gt;</code> element is semantic, but it’s not
sectioning content.</p>
</section> <!-- Don't forget this -->
This keeps our document outline the exact same while lending it some extra semantic
structure, as well as a nice hook for any CSS styles we might want to apply (e.g., a
background color for a particular section).

<SECTION> AND THE DOCUMENT OUTLINE


The previous change also has an interesting side effect on the implicit sectioning behavior
of our headings. Watch what happens when we bump the second <h2> down to a much
lower heading level:
<section>
<h6>Inline Semantic HTML</h6> <!-- Change this heading level -->
<p>The <code>&lt;time&gt;</code> element is semantic, but it’s not
sectioning content.</p>
</section>
The <h6> is lower than the <h3> that precedes it, so you might expect it to become
part of the Footer section. But, that’s not the case: the document outline is still the
exact same as before.

PREPARED BY: MAHMUD BAKALE & ALIJAFAR UMAR


By adding those <section> elements, we’re telling the document outline that it should
be defined by the nesting structure of the <section> elements instead of the heading
levels. This basically means that each <section> can have its own set
of <h1> through <h6> headings that are independent of the rest of the page.

However, you shouldn’t use the <section> element to manipulate the document outline
in this way because browsers, screen readers, and some search engines don’t properly
interpret the effect of <section> on the document outline. Instead, always define a
page’s outline via heading levels, using <section> only as a replacement for
container <div>’s when appropriate.

Also note that each <section> element should contain at least one heading, otherwise it
will add an “untitled section” to your document outline. As an example, try
updating [Link] to match the following, then run it through the outliner tool again:
<h2>Inline Semantic HTML</h2>
<section>
<!-- This will be an "Untitled Section" -->
<p>The <code>&lt;time&gt;</code> element is semantic, but it’s not
sectioning content.</p>
</section>

PREPARED BY: MAHMUD BAKALE & ALIJAFAR UMAR


This creates a new section, but since there’s no heading associated with it, the document
outline doesn’t know what to call it. This should generally be avoided when
using <section> elements.

As defined by the HTML5 specification, <section> is a pretty generic element. That,


plus the fact that browsers and screen readers can’t properly interpret its role in
document outlines makes it difficult to know when and how to leverage it properly. Our
advice is to only use <section> as a more descriptive <div> wrapper for the implicitly
defined sections of your page. Don’t use it for self-contained content (that’s
what <article> is for) or when it’s purely for layout purposes.

NAV ELEMENTS
The <nav> element lets you mark up the various navigation sections of your website.
This goes for the main site navigation, links to related pages in a sidebar, tables of
content, and pretty much any group of links. For example, we should stick our site-wide
navigation menu in a <nav> element:
<h1>Interneting Is Easy!</h1>

PREPARED BY: MAHMUD BAKALE & ALIJAFAR UMAR


<nav> <!-- Add this -->
<ul>
<li><a href='#'>Home</a></li>
<li><a href='#'>About</a></li>
<li><a href='#'>Blog</a></li>
<li><a href='#'>Sign Up</a></li>
</ul>
</nav> <!-- This too! -->
This is a great piece of semantic information for search engines. It helps them quickly
identify the structure of your entire website, making it easier to discover other pages.
As we’ll see in Asides, it’s possible to include multiple <nav> elements on a single page
if you have different sets of related links.

HEADERS
The <header> element is a new piece of semantic markup, not to be confused with
headings (the <h1>-<h6> elements). It denotes introductory content for a section,

PREPARED BY: MAHMUD BAKALE & ALIJAFAR UMAR


article, or entire web page. “Introductory content” can be anything from your
company’s logo to navigational aids or author information.

It’s a best practice to wrap a website’s name/logo and main navigation in a <header>,
so let’s go ahead and add one to our example project:
<header>
<h1>Interneting Is Easy!</h1>
<nav>
<ul>
<li><a href='#'>Home</a></li>
<li><a href='#'>About</a></li>
<li><a href='#'>Blog</a></li>
<li><a href='#'>Sign Up</a></li>
</ul>
</nav>
</header>
Headers are only associated with the nearest sectioning element—typically
a <body>, <section>, or <article> element. This means that you can use
multiple <header> elements to add introductory content to different parts of a document.

PREPARED BY: MAHMUD BAKALE & ALIJAFAR UMAR


For instance, the title, author, and publication date of our <article> is a pretty good
candidate for another <header>:
<article>
<header>
<h1>Semantic HTML</h1>
<p>By Troy McClure. Published January 3rd</p>
</header>

<p>This is an example web page explaining HTML5 semantic markup.</p>


<!-- ... -->
Without this <header>, search engines and screen readers wouldn’t know that
first <p> was separate from the main content of the article. Like <section>, it also serves
as a convenient CSS hook, since the title and author info for a blog post are often styled
differently than the rest of the article. Again, think of <header> as a more semantic
alternative to a <div> container.

FOOTERS
Conceptually, footers are basically the same as headers, except they generally come at end
of an article/website opposed to the beginning. Common use cases include things like
copyright notices, footer navigation, and author bios at the end of blog posts.

Footers behave the same as <header> in that they’re associated with the nearest
sectioning element. So, we can use it for our page’s copyright notice and the author

PREPARED BY: MAHMUD BAKALE & ALIJAFAR UMAR


information inside our <article>. Add the following two footer elements to
our [Link] page:
<article>
<header>
<h1>Semantic HTML</h1>
<p>By Troy McClure. Published January 3rd</p>
</header>

<p>This is an example web page explaining HTML5 semantic markup.</p>


<!-- ... -->

<footer> <!-- Add this -->


<p>This fake article was written by somebody at [Link],
which is a pretty decent place to learn how to become a web developer. This
footer is only for the containing <code>&lt;article&gt;</code> element.</p>
</footer> <!-- And this -->

</article>

<footer> <!-- This, too -->


<p>&copy; 2017 [Link]</p>
</footer> <!-- Don't forget to close it! -->

</body>
</html>
The <footer> inside the <article> element is only for the contents of that article, which
makes sense because it contains the author’s bio. The second footer, on the other hand, is
connected to the entire page.

ASIDES
Headers and footers are ways to add extra information to an article, but sometimes we
want to remove information from an article. For example, a sponsored blog post might

PREPARED BY: MAHMUD BAKALE & ALIJAFAR UMAR


contain an advertisement about the sponsoring company; however, we probably don’t
want to make it part of the article text. This is what the <aside> element is for.

Let’s add a fake advertisement to our [Link] file, right underneath the article’s
header:
<article>
<header>
<h1>Semantic HTML</h1>
<p>By Troy McClure. Published January 3rd</p>
</header>
<!-- Look! A fake advertisement! -->
<aside class='advert'>
<img src='[Link]'/>
</aside>

<p>This is an example web page explaining HTML5 semantic markup.</p>


Even though the image is inside the <article> element, machine readers know that it’s
only tangentially related to the article content. In addition to advertisements, <aside> is

PREPARED BY: MAHMUD BAKALE & ALIJAFAR UMAR


also appropriate for highlighting definitions, stats, or quotations. If it looks different
than the rest of the article, chances are it’s an aside.

When used outside an <article>, an <aside> is associated with the page as a whole
(much like <header> and <footer>). This makes it a good choice for marking up a site-
wide sidebar. Add the following underneath the closing </article> tag, before the
second <footer>:
<aside class='sidebar'>
<h2>Sidebar</h2>
<p>Some sidebar content</p>
<nav>
<h3>HTML &amp; CSS Tutorial</h3>
<ul>
<li><a href='#'>Introduction</a></li>
<li><a href='#'>Basic Web Pages</a></li>
<li><a href='#'>etc...</a></li>
</ul>
</nav>
<nav>
<h3>JavaScript Tutorial</h3>
<ul>
<li><a href='#'>Introduction</a></li>
<li><a href='#'>Hello, JavaScript</a></li>
<li><a href='#'>etc...</a></li>
</ul>
</nav>
</aside>
Notice the class attributes in both of these snippets. If we were worried about CSS this
chapter, we could style our <aside> elements in exactly the same way as all the <div>’s
we’ve been working with throughout this tutorial. Which brings us to…

PREPARED BY: MAHMUD BAKALE & ALIJAFAR UMAR


DIVS FOR LAYOUT
You should use semantic HTML whenever you can, since it helps machines infer the
structure of your content, and it gives you a standardized vocabulary to organize your
web pages. However, sometimes you need a container element when none of the
semantic HTML elements we just covered would make sense. There’s nothing wrong
with using a plain old <div> purely for layout purposes.

For instance, if we want to center our page using that familiar auto-margin technique,
we have to wrap the whole page in a container. It’s entirely presentational, so a <div> is
the best option:
<body>
<div class='page'> <!-- Start of container div -->
<header>
<h1>Interneting Is Easy!</h1>
<nav>
<ul>
<li><a href='#'>Home</a></li>
<li><a href='#'>About</a></li>
<li><a href='#'>Blog</a></li>
<li><a href='#'>Sign Up</a></li>
</ul>
</nav>
</header>
<!-- ... -->
<footer>
<p>&copy; 2017 [Link]</p>
</footer>
</div> <!-- End of container div -->
</body>
</html>
This is particularly relevant for flexbox, as it requires lots of <div>’s to group flex items
correctly. Occasionally, you may find that a <section> or <nav> is appropriate for these

PREPARED BY: MAHMUD BAKALE & ALIJAFAR UMAR


flex items, but it’s pretty common to find a bunch of presentational <div> elements in
a flexbox layout.

The point is, don’t use semantic elements just for the sake of using them. Implementing
them incorrectly is worse than not using them at all, so if you’re ever in doubt, use
a <div> instead.

DATES AND TIMES


For humans, dates and times come in many forms. You can refer to January 3rd, 2017 as
“1/3/2017”, “Jan 3rd”, or even “yesterday” depending on the current date. Parsing this kind
of ambiguous natural language is difficult and error-prone for machines, which is
where <time> comes in.

The <time> element represents either a time of day or a calendar date. Providing a
machine-readable date makes it possible for browsers to automatically link it to users’
calendars and helps search engines clearly identify specific dates. A simple Google search
will show you the effect of including a <time> element on your page:

Let’s make the publish date of our article unambiguous by wrapping it in <time> tags:
<article>
<header>
<h1>Semantic HTML</h1>
<p>By Troy McClure. Published <time datetime='2017-1-3'>January
3rd</time></p>
</header>
<!-- ... -->

PREPARED BY: MAHMUD BAKALE & ALIJAFAR UMAR


The machine-readable date is defined in the datetime attribute. An easy way to remember
the date format is that it goes from largest time period to smallest: year, month, then date.
Note that even though the year isn’t included in the human-readable text, this tells search
engines that our article was published in 2017.

It’s possible to include times and time zones inside of datetime, too. If we wanted to add a
3:00pm PST time to our publish date, we’d use the following:
<time datetime='2017-1-3 15:00-0800'>January 3rd</time>
The time itself is in 24-hour format, and the -0800 is the time zone offset from GMT (in
this case, -0800 represents Pacific Standard Time).

ADDRESS
The <address> element is like <time> in that it doesn’t deal with the overall structure of
a document, but rather embellishes the parent <article> or <body> element with some
metadata. It defines contact information for the author of the article or web page in
question. <address> should not be used for arbitrary physical addresses.

For instance, maybe we want to add an author email address in our article’s footer:
<footer>
<p>This fake article was written by somebody at [Link], which
is a pretty decent place to learn how to become a web developer. This footer
is only for the containing <code>&lt;article&gt;</code> element.</p>
<address>
Please contact <a href='[Link]

PREPARED BY: MAHMUD BAKALE & ALIJAFAR UMAR


McClure</a> for questions about this article.
</address>
</footer>
By default, this will be styled the same way as <em>, but you can change that with a simple
CSS rule. Also notice the new email link in the href, which you can read more about
at Mozilla Developer Network.

FIGURES AND CAPTIONS


Last, but certainly not least, are the <figure> and <figcaption> elements. The former
represents a self-contained “figure”, like a diagram, illustration, or even a code snippet.
The latter is optional, and it associates a caption with its parent <figure> element.

A common use case for both of these is to add visible descriptions to


the <img/> elements in an article, like so:
<section>
<h2>The Document Outline</h2>
<p>HTML5 includes several “sectioning content” elements that
affect the document outline.</p>

<figure>
<img src='[Link]'
alt='Diagram showing <article>, <section>, and <nav> elements'/>
<figcaption>New HTML5 semantic elements</figcaption>
</figure>
<!-- ... -->
The alt attribute is closely related to the <figcaption> element. alt should serve as a
text replacement for the image, while <figcaption> is a
supporting description displayed with either the image or its text-based equivalent.

When using <figcaption> in the above manner, you can safely omit an
image’s alt attribute without hurting your SEO. Depending on what kind of images

PREPARED BY: MAHMUD BAKALE & ALIJAFAR UMAR


you’re working with, it may be more convenient (and less redundant) to have
visible <figcaption>’s that describe them opposed to invisible alt attributes.

CSS/LEGACY CONSIDERATIONS
And finally, a quick note on legacy browsers. The semantic HTML elements in this chapter
were introduced in HTML5. All modern browser recognize them without any extra work,
but you’ll often see something like the following in global CSS stylesheets:
section, article, aside, footer, header, nav {
display: block;
}
This makes the new semantic elements behave like <div> elements (which are block
boxes, not inline boxes) in legacy browsers.

SUMMARY
Defining graphical styles with CSS is how we convey the structure of a web page to
humans. By marking it up with <header>, <article>, <figure>, and other HTML sectioning
elements, we’re able to represent those visual styles to machines, as well.

PREPARED BY: MAHMUD BAKALE & ALIJAFAR UMAR


To understand why this is important, we really have to empathize with the machines
reading our content. Before semantic HTML was a thing, developers used a bunch
of <div>’s with different and somewhat arbitrary class names to define the structure of
their pages. For example, all of the following elements are logical names for a site-wide
header:
<div class='main-menu'>
<div class='top-nav'>
<div class='top-banner'>
<div class='header'>
Machine readers used to have to make sense of all the above <div>’s and more. The new
semantic HTML elements we learned in this chapter are like standardized versions of these
class names. Now, they can simply look for a <header> element. We can still add whatever
class name we want to it for styling purposes, but search engines and screen readers now
have a predictable way to identify headers across every HTML5 website on the Internet.

The semantic elements we covered in this chapter are best practices for modern websites,
but keep in mind that they hardly scratch the surface when it comes to extra meaning you
can add to your web pages. Just for starters:
• [Link] microdata lets you alter the appearance of your site in search engine
results.
• Twitter cards define how your web page is displayed in tweets.
• Open Graph metadata changes how Facebook shares your content.
This kind of stuff is closer to the realm of technical SEO, so we’ll leave you to explore it
on your own. In the next chapter, we’ll switch gears again and introduce another critical
component of websites (especially e-commerce ones): forms.

PREPARED BY: MAHMUD BAKALE & ALIJAFAR UMAR


HTML FORMS

Nº 13. of HTML & CSS Is Hard


A friendly web development tutorial for capturing user input

HTML form elements let you collect input from your website’s visitors. Mailing lists,
contact forms, and blog post comments are common examples for small websites, but
in organizations that rely on their website for revenue, forms are sacred and revered.

Forms are the “money pages.” They’re how e-commerce sites sell their products, how
SaaS companies collect payment for their service, and how non-profit groups raise
money online. Many companies measure the success of their website by the
effectiveness of its forms because they answer questions like “how many leads did our
website send to our sales team?” and “how many people signed up for our product last

PREPARED BY: MAHMUD BAKALE & ALIJAFAR UMAR


week?” This often means that forms are subjected to endless A/B tests and
optimizations.

There are two aspects of a functional HTML form: the frontend user interface and the
backend server. The former is the appearance of the form (as defined by HTML and CSS),
while the latter is the code that processes it (storing data in a database, sending an email,
etc). We’ll be focusing entirely on the frontend this chapter, leaving backend form
processing for a future tutorial.

SETUP
Unfortunately, there’s really no getting around that fact that styling forms is hard. It’s
always a good idea to have a mockup representing the exact page you want to build
before you start coding it up, but this is particularly true for forms. So, here’s the
example we’ll be creating in this chapter:

PREPARED BY: MAHMUD BAKALE & ALIJAFAR UMAR


As you can see, this is a speaker submission form for a fake conference. It hosts a pretty
good selection of HTML forms elements: various types of text fields, a group of radio
buttons, a dropdown menu, a checkbox, and a submit button.

Create a new Atom project called forms and stick a new HTML file in it called speaker-
[Link]. For starters, let’s add the markup for the header. (Hey look! It
has some semantic HTML!)

<!DOCTYPE html>

PREPARED BY: MAHMUD BAKALE & ALIJAFAR UMAR


<html lang='en'>
<head>
<meta charset='UTF-8'/>
<title>Speaker Submission</title>
<link rel='stylesheet' href='[Link]'/>
</head>
<body>
<header class='speaker-form-header'>
<h1>Speaker Submission</h1>
<p><em>Want to speak at our fake conference? Fill out
this form.</em></p>
</header>
</body>
</html>
Next, create a [Link] file and add the following CSS. It uses a
simple flexbox technique to center the header (and form) no matter how wide
the browser window is:
*{
margin: 0;
padding: 0;
box-sizing: border-box;
}

body {
color: #5D6063;
background-color: #EAEDF0;
font-family: "Helvetica", "Arial", sans-serif;
font-size: 16px;
line-height: 1.3;

display: flex;
flex-direction: column;
align-items: center;
}

PREPARED BY: MAHMUD BAKALE & ALIJAFAR UMAR


.speaker-form-header {
text-align: center;
background-color: #F6F7F8;
border: 1px solid #D6D9DC;
border-radius: 3px;

width: 80%;
margin: 40px 0;
padding: 50px;
}

.speaker-form-header h1 {
font-size: 30px;
margin-bottom: 20px;
}
Notice that we’re adhering to the mobile-first development approach that we discussed in
the Responsive Design chapter. These base CSS rules give us our mobile layout and
provide a foundation for the desktop layout, too. We’ll create the media query for a fixed-
width desktop layout later in the chapter.

HTML FORMS
On to forms! Every HTML form begins with the aptly named <form> element. It
accepts a number of attributes, but the most important ones are action and method. Go
ahead and add an empty form to our HTML document, right under the <header>:
<form action='' method='get' class='speaker-form'>
</form>
The action attribute defines the URL that processes the form. It’s where the input collected
by the form is sent when the user clicks the Submit button. This is typically a special URL
defined by your web server that knows how to process the data. Common backend
technologies for processing forms include [Link], PHP, and Ruby on Rails, but again,
we’ll be focusing on the frontend in this chapter.

PREPARED BY: MAHMUD BAKALE & ALIJAFAR UMAR


The method attribute can be either post or get, both of which define how the form is
submitted to the backend server. This is largely dependent on how your web server wants
to handle the form, but the general rule of thumb is to use post when you’re changing data
on the server, reserving get for when you’re only getting data.

By leaving the action attribute blank, we’re telling the form to submit to the same URL.
Combined with the get method, this will let us inspect the contents of the form.

STYLING FORMS
Of course, we’re looking at an empty form right now, but that doesn’t mean we can’t add
some styles to it like we would a container <div>. This will turn it into a box that matches
our <header> element:
.speaker-form {
background-color: #F6F7F8;
border: 1px solid #D6D9DC;
border-radius: 3px;

width: 80%;
padding: 50px;
margin: 0 0 40px 0;
}

PREPARED BY: MAHMUD BAKALE & ALIJAFAR UMAR


TEXT INPUT FIELDS
To actually collect user input, we need a new tool: the <input/> element. Insert the
following into our <form> to create a text field:
<div class='form-row'>
<label for='full-name'>Name</label>
<input id='full-name' name='full-name' type='text'/>
</div>
First, we have a container <div> to help with styling. This is pretty common for separating
input elements. Second, we have a <label>, which you can think of as another semantic
HTML element, like <article> or <figcaption>, but for form labels. A label’s for attribute
must match the id attribute of its associated <input/> element.

Third, the <input/> element creates a text field. It’s a little different from other elements
we’ve encountered because it can dramatically change appearance depending on
its type attribute, but it always creates some kind of interactive user input. We’ll see other
values besides text throughout the chapter. Remember that ID selectors are bad—
the id attribute here is only for connecting it to a <label> element.

PREPARED BY: MAHMUD BAKALE & ALIJAFAR UMAR


Conceptually, an <input/> element represents a “variable” that gets sent to the backend
server. The name attribute defines the name of this variable, and the value is whatever the
user entered into the text field. Note that you can pre-populate this value by adding
a value attribute to an <input/> element.

STYLING TEXT INPUT FIELDS


An <input/> element can be styled like any other HTML element. Let’s add some CSS
to [Link] to pretty it up a bit. This makes use of all the concepts from the Hello,
CSS, Box Model, CSS Selectors, and Flexbox chapters:
.form-row {
margin-bottom: 40px;
display: flex;
justify-content: flex-start;
flex-direction: column;
flex-wrap: wrap;
}

.form-row input[type='text'] {
background-color: #FFFFFF;
border: 1px solid #D6D9DC;
border-radius: 3px;
width: 100%;
padding: 7px;
font-size: 14px;
}

.form-row label {
margin-bottom: 15px;
}
The input[type='text'] part is a new type of CSS selector called an “attribute selector”. It
only matches <input/> elements that have a type attribute equal to text. This lets us
specifically target text fields opposed to radio buttons, which are defined by the same

PREPARED BY: MAHMUD BAKALE & ALIJAFAR UMAR


HTML element (<input type='radio'/>). You can read more about attribute selectors
at Mozilla Developer Network.

All of our styles are “namespaced” in a .form-row descendant selector.


Isolating <input/> and <label> styles like this makes it easier to create different kinds of
forms. We’ll see why it’s convenient to avoid global input[type='text'] and label selectors
once we get to radio buttons.

Finally, let’s tweak these base styles to create our desktop layout. Add the following media
query to the end of our stylesheet.

@media only screen and (min-width: 700px) {


.speaker-form-header,
.speaker-form {
width: 600px;
}
.form-row {
flex-direction: row;
align-items: flex-start; /* To avoid stretching */
margin-bottom: 20px;
}
.form-row input[type='text'] {
width: 250px;
height: initial;
}
.form-row label {
text-align: right;
width: 120px;
margin-top: 7px;
padding-right: 20px;
}
}

PREPARED BY: MAHMUD BAKALE & ALIJAFAR UMAR


Check out that awesome use of the flex-direction property to make the <label> appear on
top of its <input/> element in the mobile layout, but to the left of it in the desktop layout.

EMAIL INPUT FIELDS


The <input/> element’s type attribute also lets you do basic input validation. For example,
let’s try adding another input element that only accepts email addresses instead of arbitrary
text values:
<div class='form-row'>
<label for='email'>Email</label>
<input id='email'
name='email'
type='email'
placeholder='joe@[Link]'/>
</div>
This works exactly like the type='text' input, except it automatically checks that user
entered an email address. In Firefox, you can try typing something that’s not an email
address, then clicking outside of the field to make it lose focus and validate its input. It
should turn red to show the user that it’s an incorrect value. Chrome and Safari don’t
attempt to validate until user tries to submit the form, so we’ll see this in action later in this
chapter.

PREPARED BY: MAHMUD BAKALE & ALIJAFAR UMAR


This is more than just validation though. By telling browsers that we’re looking for an
email address, they can provide a more intuitive user experience. For instance, when a
smartphone browser sees this type='email' attribute, it gives the user a special email-
specific keyboard with an easily-accessible @ character.

Also notice the new placeholder attribute that lets you display some default text when
the <input/> element is empty. This is a nice little UX technique to prompt the user to input
their own value.

There’s a bunch of other built-in validation options besides email addresses, which you can
read about on MDN’s <input/> reference. Of particular interest are
the required, minlength, maxlength, and pattern attributes.

STYLING EMAIL INPUT FIELDS


We want our email field to match our text field from the previous section, so let’s add
another attribute selector to the existing input[type='text'] rule, like so:
/* Change this rule */
.form-row input[type='text'] {
background-color: #FFFFFF;
/* ... */
}

/* To have another selector */

PREPARED BY: MAHMUD BAKALE & ALIJAFAR UMAR


.form-row input[type='text'],
.form-row input[type='email'] {
background-color: #FFFFFF;
/* ... */
}
Again, we don’t want to use a plain old input type selector here because that would
style all of our <input/> elements, including our upcoming radio buttons and checkbox.
This is part of what makes styling forms tricky. Understanding the CSS to pluck out exactly
the elements you want is a crucial skill.

Let’s not forget about our desktop styles. Update the corresponding input[type='text'] rule
in our media query to match the following (note that we’re preparing for the next few
sections with the select, and textarea selectors):

@media only screen and (min-width: 700px) {


/* ... */
.form-row input[type='text'],
.form-row input[type='email'], /* Add */
.form-row select, /* These */
.form-row textarea { /* Selectors */
width: 250px;
height: initial;
}
/* ... */
}
Since we can now have a “right” and a “wrong” input value, we should probably convey
that to users. The :invalid and :valid pseudo-classes let us style these states independently.
For example, maybe we want to render both the border and the text with a custom shade
of red when the user entered an unacceptable value. Add the following rule to our
stylesheet, outside of the media query:

.form-row input[type='text']:invalid,

PREPARED BY: MAHMUD BAKALE & ALIJAFAR UMAR


.form-row input[type='email']:invalid {
border: 1px solid #D55C5F;
color: #D55C5F;
box-shadow: none; /* Remove default red glow in Firefox */
}
Until we include a submit button, you’ll only be able to see this in Firefox, but you get the
idea. There’s a similar pseudo-class called :focus that selects the element the user is
currently filling out. This gives you a lot of control over the appearance of your forms.

RADIO BUTTONS
Changing the type property of the <input/> element to radio transforms it into a radio
button. Radio buttons are a little more complex to work with than text fields because they
always operate in groups, allowing the user to choose one out of many predefined options.

This means that we not only need a label for each <input/> element, but also a way to
group radio buttons and label the entire group. This is what
the <fieldset> and <legend> elements are for. Every radio button group you create
should:
• Be wrapped in a <fieldset>, which is labeled with a <legend>.
• Associate a <label> element with each radio button.
• Use the same name attribute for each radio button in the group.
• Use different value attributes for each radio button.

PREPARED BY: MAHMUD BAKALE & ALIJAFAR UMAR


Our radio button example has all of these components. Add the following to
our <form> element underneath the email field:
<fieldset class='legacy-form-row'>
<legend>Type of Talk</legend>
<input id='talk-type-1'
name='talk-type'
type='radio'
value='main-stage' />
<label for='talk-type-1' class='radio-label'>Main Stage</label>
<input id='talk-type-2'
name='talk-type'
type='radio'
value='workshop'
checked />
<label for='talk-type-2' class='radio-label'>Workshop</label>
</fieldset>
Unlike text fields, the user can’t enter custom values into a radio button, which is why each
one of them needs an explicit value attribute. This is the value that will get sent to the server
when the user submits the form. It’s also very important that each radio button has the
same name attribute, otherwise the form wouldn’t know they were part of the same group.

We also introduced a new attribute called checked. This is a “boolean attribute”, meaning
that it never takes a value—it either exists or doesn’t exist on an <input/> element. If it
does exist on either a radio button or a checkbox element, that element will be
selected/checked by default.

STYLING RADIO BUTTONS


We have a few things working against us with when it comes to styling radio buttons. First,
there’s simply more elements to worry about. Second,
the <fieldset> and <legend> elements have rather ugly default styles, and there’s not a

PREPARED BY: MAHMUD BAKALE & ALIJAFAR UMAR


whole lot of consistency in these defaults across browsers. Third, at the time of this
writing, <fieldset> doesn’t support flexbox.

But don’t fret! This is a good example of floats being a useful fallback for
legacy/troublesome elements. You’ll notice that we didn’t wrap the radio buttons in our
existing .form-row class, opting instead for a new .legacy-form-row class. This is because
it’s going to be completely separate from our other elements, using floats instead of
flexbox.

Start with the mobile and tablet styles by adding the following rules outside of our media
query. We want to get rid of the default <fieldset> and <legend> styles, then float the radio
buttons and labels so they appear in one line underneath the <legend>:
.legacy-form-row {
border: none;
margin-bottom: 40px;
}

.legacy-form-row legend {
margin-bottom: 15px;

PREPARED BY: MAHMUD BAKALE & ALIJAFAR UMAR


}

.legacy-form-row .radio-label {
display: block;
font-size: 14px;
padding: 0 20px 0 10px;
}

.legacy-form-row input[type='radio'] {
margin-top: 2px;
}

.legacy-form-row .radio-label,
.legacy-form-row input[type='radio'] {
float: left;
}
For the desktop layout, we need to make the <legend> line up with the <label> elements
in the previous section (hence the width: 120px line), and we need to float everything to
the left so they appear on the same line. Update our media query to include the
following:
@media only screen and (min-width: 700px) {
/* ... */
.legacy-form-row {
margin-bottom: 10px;
}
.legacy-form-row legend {
width: 120px;
text-align: right;
padding-right: 20px;
}
.legacy-form-row legend {
float: left;
}
}

PREPARED BY: MAHMUD BAKALE & ALIJAFAR UMAR


As far as layouts go, this is a pretty good cross-browser solution. However, customizing
the appearance of the actual button is another story. It’s possible by taking advantage
of the checked attribute, but it’s a little bit complicated. We’ll leave you to Google
“custom radio button CSS” and explore that rabbit hole on your own.

SELECT ELEMENTS (DROPDOWN MENUS)


Dropdown menus offer an alternative to radio buttons, as they let the user select one
out of many options. The <select> element represents the dropdown menu, and it
contains a bunch of <option> elements that represent each item.

<div class='form-row'>
<label for='t-shirt'>T-Shirt Size</label>
<select id='t-shirt' name='t-shirt'>
<option value='xs'>Extra Small</option>
<option value='s'>Small</option>
<option value='m'>Medium</option>
<option value='l'>Large</option>
</select>
</div>
Just like our radio button <input/> elements, we have name and value attributes that get
passed to the backend server. But, instead of being defined on a single element, they’re
spread across the <select> and <option> elements.

STYLING SELECT ELEMENTS


And, also just like our radio buttons, <select> elements are notoriously hard to style.
However, there’s a reason for this. Dropdowns are a complex piece of interactivity, and
their behavior changes significantly across devices. For instance, on an iPhone, clicking
a <select> element brings up a native scrolling UI component that makes it much easier to
navigate the menu.

PREPARED BY: MAHMUD BAKALE & ALIJAFAR UMAR


It’s usually a good idea to let the browser/device determine the best way to preset
a <select> element, so we’ll be keeping our CSS pretty simple. Unfortunately, even the
simplest things are surprisingly hard. For instance, try changing the font size of
our <select> element:
.form-row select {
width: 100%;
padding: 5px;
font-size: 14px; /* This won't work in Chrome or Safari */
}
This will work in Firefox, but not in Chrome or Safari! To sort of fix this, we can use a
vendor-specific prefix for the appearance property:
.form-row select {
width: 100%;
padding: 5px;
font-size: 14px; /* This won't work in Chrome or Safari */
-webkit-appearance: none; /* This will make it work */
}
The -webkit prefix will only apply to Chrome and Safari (which are powered by the
WebKit rendering engine), while Firefox will remain unaffected. This is effectively a hack,
and even MDN says not to use this CSS property.

Style difficulties like this are a serious consideration when building a form. If you need
custom styles, you may be better off using radio buttons or JavaScript UI
widgets. Bootstrap Dropdowns and jQuery Selectmenu’s are common JavaScript solutions

PREPARED BY: MAHMUD BAKALE & ALIJAFAR UMAR


for customizing select menus. In any case, at least you now understand the problem. You
can read more about <select> issues here.

TEXTAREAS
The <textarea> element creates a multi-line text field designed to collect large amounts of
text from the user. They’re suitable for things like biographies, essays, and comments. Go
ahead and add a <textarea> to our form, along with a little piece of instructional text:
<div class='form-row'>
<label for='abstract'>Abstract</label>
<textarea id='abstract' name='abstract'></textarea>
<div class='instructions'>Describe your talk in 500 words or less</div>
</div>
Note that this isn’t self-closing like the <input/> element, so you always need a
closing </textarea> tag. If you want to add any default text, it needs to go inside the tags
opposed to a value attribute.

STYLING TEXTAREAS
Fortunately, styling textareas is pretty straightforward. Add the following to
our [Link] file (before the media query):
.form-row textarea {
font-family: "Helvetica", "Arial", sans-serif;
font-size: 14px;

border: 1px solid #D6D9DC;


border-radius: 3px;

min-height: 200px;
margin-bottom: 10px;
padding: 7px;
resize: none;
}

PREPARED BY: MAHMUD BAKALE & ALIJAFAR UMAR


.form-row .instructions {
color: #999999;
font-size: 14px;
margin-bottom: 30px;
}
By default, many browsers let the user resize <textarea> elements to whatever dimensions
they want. We disabled this here with the resize property.

We also need a little tweak in our desktop layout. The .instructions <div> needs to be
underneath the <textarea>, so let’s nudge it left by the width of the <label> column. Add
the following rule to the end of our media query:

@media only screen and (min-width: 700px) {


/* ... */
.form-row .instructions {
margin-left: 120px;
}
}

CHECKBOXES
Checkboxes are sort of like radio buttons, but instead of selecting only one option, they let
the user pick as many as they want. This simplifies things, since the browser doesn’t need
to know which checkboxes are part of the same group. In other words, we don’t need
a <fieldset> wrapper or shared name attributes. Add the following to the end of our form:
<div class='form-row'>
<label class='checkbox-label' for='available'>
<input id='available'
name='available'
type='checkbox'
value='is-available'/>
<span>I’m actually available the date of the talk</span>
</label>

PREPARED BY: MAHMUD BAKALE & ALIJAFAR UMAR


</div>
The way we used <label> here was a little different than previous sections. Instead of being
a separate element, the <label> wraps its corresponding <input/> element. This is perfectly
legal, and it’ll make it easier to match our desired layout. It’s still a best practice to use
the for attribute.

STYLING CHECKBOXES
For the mobile layout, all we need to do is override the margin-bottom that we put on the
rest the <label> elements. Add the following to [Link], outside of the media query:
.form-row .checkbox-label {
margin-bottom: 0;
}
And inside the media query, we have to take that 120-pixel label column into account:
@media only screen and (min-width: 700px) {
/* ... */
.form-row .checkbox-label {
margin-left: 120px;
width: auto;
}
}
By wrapping both the checkbox and the label text, we’re able to use a width: auto to make
the entire form field be on a single line (remember that the auto width makes the box match
the size of its contents).

PREPARED BY: MAHMUD BAKALE & ALIJAFAR UMAR


SUBMIT BUTTONS
Finally, let’s finish off our form with a submit button. The <button> element represents a
button that will submit its containing <form>:
<div class='form-row'>
<button>Submit</button>
</div>
Clicking the button tells the browser to validate all of the <input/> elements in the form
and submit it to the action URL if there aren’t any validation problems. So, you should
now be able to type in something that’s not an email address into our email field, click
the <button>, and see an error message.

PREPARED BY: MAHMUD BAKALE & ALIJAFAR UMAR


This also gives us a chance to see how the user’s input gets sent to the server. First, enter
some values into all the <input/> fields, making sure the email address validates correctly.
Then, click the button and inspect the resulting URL in your browser. You should see
something like this:

[Link]?full-name=Rick&email=rick%[Link]&talk-
type=workshop&t-shirt=l&abstract=Derp.&available=is-available

Everything after the ? represents the variables in our form. Each <input/>’s name attribute
is followed by an equal sign, then its value, and each variable is separated by
an & character. If we had a backend server, it’d be pretty easy for it to pull out all this
information, query a database (or whatever), and let us know whether the form submission
was successful or not.

STYLING BUTTONS
We had some experience styling buttons in the pseudo-classes section of the CSS
Selectors chapter. Back then, we were applying these styles to an <a> element, but we can
use the same techniques on a <button>.

PREPARED BY: MAHMUD BAKALE & ALIJAFAR UMAR


Clean up that ugly default <button> styling by adding the following to our stylesheet:
.form-row button {
font-size: 16px;
font-weight: bold;

color: #FFFFFF;
background-color: #5995DA;

border: none;
border-radius: 3px;

padding: 10px 40px;


cursor: pointer;
}

.form-row button:hover {
background-color: #76AEED;
}

.form-row button:active {
background-color: #407FC7;
}
As with our checkbox, we need to take that 120px label column into account, so include
one more rule inside our media query:

@media only screen and (min-width: 700px) {


/* ... */
.form-row button {

PREPARED BY: MAHMUD BAKALE & ALIJAFAR UMAR


margin-left: 120px;
}
}

SUMMARY
In this chapter, we introduced the most common HTML form elements. We now have all
these tools for collecting input from our website visitors:
• <input type='text'/>
• <input type='email'/>
• <input type='radio'/>
• <select> and <option>
• <textarea>
• <input type='checkbox'/>
• <button>
You should be pretty comfortable with the HTML and CSS required to build beautiful
forms, but actually making these forms functional requires some skills we don’t have yet.
That stuff is out of scope for this tutorial, but it might help to have some context. Generally
speaking, there are two ways to process forms:
• Use the action attribute to send the form data to a backend URL, which then
redirects to a success or error page. We got a little glimpse of this in the previous
section, and it doesn’t require any JavaScript.
• Use AJAX queries to submit the form without leaving the page. Success or error
messages are displayed on the same page by manipulating the HTML with
JavaScript.
Depending on how your organization is structured, form processing may not be part of
your job role as a frontend web developer. If that’s the case, you’ll need to coordinate
closely with a backend developer on your team to make sure the <form> submits the
correct name-value pairs. Otherwise, it’ll be up to you to make sure the frontend and
backend of your forms fit neatly together.

PREPARED BY: MAHMUD BAKALE & ALIJAFAR UMAR


Next, we have our final chapter in HTML & CSS Is Hard. We’ll round out our frontend
skills with a thorough discussion of web fonts and practical typographic principles that
every web developer should know about.

WEB TYPOGRAPHY
Nº 14. of HTML & CSS Is Hard
A friendly tutorial about web fonts and basic typographic principles

PREPARED BY: MAHMUD BAKALE & ALIJAFAR UMAR


“Web typography” refers to the appearance of all the text on your website. It includes basic
CSS text properties like what font to use and whether it should be italic or not, but
typography is much more than that. It’s about the space between and around letters, words,
and lines. It’s the size of different runs of text in relation to one another, and the history
behind each font family.

A lot of your typography decisions will come from a designer. The only problem is that
typography is an invisible art. To actually understand what your designer is asking for, you
need to be able to see typography the same way they do.

This chapter isn’t just about the mechanics of adding web fonts to your site or the CSS
properties to move your text around. We’ll also explain how to properly leverage all these
tools to make beautiful, professional websites. By the end of the chapter, you should not
only know what your designer is talking about when they say something like, “Can we

PREPARED BY: MAHMUD BAKALE & ALIJAFAR UMAR


increase the leading of that paragraph?”, but also understand why they want you to increase
it.

You may forget the specific CSS properties, but the typographic concepts we’re going to
cover will stay with you for the rest of your life because they aren’t arbitrary rules—they’re
grounded in function. They make your content more readable and help you communicate
your message more effectively.

A BRIEF HISTORY OF WEB FONTS


We’re going to start this chapter by learning how to display your web pages in a custom
font because that’s the most exciting aspect of modern web typography. However, web
fonts have changed a lot over the last few years, so before we can start building out our
example, we need a little primer on the various font formats floating around the Internet.

WEB SAFE FONTS


Long, long ago, web developers only had “web safe fonts” at their disposal. These were a
collection of a dozen or so fonts that were pre-installed on most computers. There was no
such thing as a custom font file that you could send to browsers to use on your website.

PREPARED BY: MAHMUD BAKALE & ALIJAFAR UMAR


If you needed a special font, your only option was to export an image of the text you wanted
to display and include it in your web page with an <img/> element. This was ridiculously
limiting for web designers and resulted in some pretty hacky situations for developers.
Honestly, we don’t know how everybody survived through that era of HTML and CSS.

CUSTOM WEB FONTS


Around 2010, browsers began supporting custom web fonts, which was great, except
for the fact that each browser and device required a different file format. Accordingly,
most websites provided 4 different web font files:

File Format Browser/Device


.svg Very old Safari (iOS and Desktop)
.eot Internet Explorer
.ttf Everything except Internet Explorer
.woff Newer browsers

This resulted in the “Bulletproof @font-face syntax”, which you’ll likely encounter at
some point in your web development career.

PREPARED BY: MAHMUD BAKALE & ALIJAFAR UMAR


WOFF FONTS
Recently, the industry has standardized on the Web Open Font Format (WOFF), so things
have gotten a little bit simpler for us. Over 90% of modern browsers support .woff fonts,
and support for its next evolution, .woff2, is growing. WOFF2 is similar to the original
WOFF format, but offers a significant reduction in file size (which means better
performance).

PREPARED BY: MAHMUD BAKALE & ALIJAFAR UMAR


Eventually, you’ll only need to support WOFF2, but right now, we suggest providing both
WOFF and WOFF2 web fonts to get decent coverage for older browsers and improved
performance on modern ones. Unless legacy browsers make up a large chunk of your target
audience, .ttf, .svg, and .eot fonts are a thing of the past.

WHERE TO FIND WEB FONTS


There’s a ton of places on the web where you can download both free and premium web
fonts, but our three favorites are listed below. Again, which font to use is usually up to your
designer (and their budget), but as a developer, it’s still good to know the trade-offs
between these options.

Website Price Quality Selection


Font Squirrel Free Hit-or-Miss Huge
Google Fonts Free Good Decent

PREPARED BY: MAHMUD BAKALE & ALIJAFAR UMAR


Fontspring Expensive Excellent Huge

Note that Font Squirrel and Fontspring offer both web fonts and desktop fonts
(.otf and .ttf files). WOFF is designed specifically for the needs of the modern web, while
desktop fonts contain extra functionality useful for graphics editing programs like Adobe
Illustrator. Be sure to download or purchase the web font version of the fonts you want to
use—not just the desktop version.

SETUP
Ok! We’re ready to experiment with web fonts. We’re going to be building this example
website. We figured you probably don’t want to start this one from scratch, so go ahead
and download the initial project. Unzip it and open up the web-typography folder with your
favorite text editor. If you don’t have a favorite text editor, you might want to check
out Atom.

We’ve got 6 HTML documents all using the same [Link] stylesheet. We’ll be
demonstrating various typographic principles by adding some page-specific styles to
each of these HTML files.

PREPARED BY: MAHMUD BAKALE & ALIJAFAR UMAR


Open up one of the HTML files with a web browser, and you’ll find that our initial project
is pretty close to the final example, minus all the web fonts and other CSS typography
properties.

LOCALLY HOSTED WEB FONTS


There are two distinct methods of adding web fonts to your website: locally hosted or
externally hosted. We’ll take a look at both in this chapter. First, we’ll be adding a locally
hosted web font to our example project. This is a three-step process:
1. Download a web font and add it to your project.
2. Embed the web font in your stylesheet.
3. Use the font elsewhere in your stylesheet.

PREPARED BY: MAHMUD BAKALE & ALIJAFAR UMAR


We’ll be experimenting in the [Link] and [Link] files. Go ahead and open those
up in your text editor if you haven’t already.

HOSTING A WOFF FILE


So, we need to get our hands on a web font. Our example uses the free Roboto font, which
you should download from Font Squirrel. Make sure to click the Webfont Kit tab, not
the Download TTF button. Unclick all the formats except WOFF, since that’s the only
one we’ll be using, then click the Download @font-face Kit button.

This will give you a ZIP file with a license, some instructions, and a web fonts folder
containing a ton of subdirectories. The Roboto font comes in a bunch of different font
faces like light, regular, bold, italic, and condensed. Each of those folders contains a
different face. The one we want is called roboto_light_macroman. Open up that folder and
copy the [Link] file into our web-typography project.

PREPARED BY: MAHMUD BAKALE & ALIJAFAR UMAR


EMBEDDING A WEB FONT
Sweet. We’ve got a WOFF file. To actually use it in our web page, we need to embed
it into our stylesheet with the @font-face “at-rule”. Web fonts must always be included
at the top of a stylesheet, so add the following to the very beginning of [Link]:
@font-face {
font-family: 'Roboto';
src: url('[Link]') format('woff');
}
The font-family property defines how we’ll refer to this font later on. This operates as an
internal label, so it can be anything you want. It doesn’t need to relate to the official name
of the font, but it’s usually more intuitive if it does. As we’ll see in a moment, it’s a good
idea to keep the name as generic as possible (e.g., Roboto instead of Roboto Light).

Next, we have the src property, which defines the path to the .woff file via
the url() notation. The path can be absolute, relative, or root-relative. If you use a relative
path like we did here, it will always be relative to the .css file—not the HTML document.
The format() notation lets browsers know which web font file format it is.

If you reload [Link] page, you won’t see any change because @font-face only
gave us access to our .woff file. We still need to use it somewhere else in our stylesheet.

USING A WEB FONT


Remember from Defining Fonts that the CSS font-family property defines which font a
particular HTML element uses. After adding our @font-face at-rule, we can use Roboto as
a valid value for font-family anywhere else in our stylesheet.

Let’s make Roboto Light the default font for our entire example project by changing
the font-family in the body selector of [Link]:
body {

PREPARED BY: MAHMUD BAKALE & ALIJAFAR UMAR


font-family: 'Roboto', sans-serif; /* Add 'Roboto' here */
font-size: 18px;
line-height: 1.8em;
color: #5D6063;
}
Everything should now render as Roboto Light, which means we lost our comparison
with the sans-serif system font in [Link]. Fix this by adding a page-specific
style to the <head> of our [Link] file:
<style>
.system-fonts {
font-family: sans-serif;
}
</style>
The .system-fonts class is applied to the second box in [Link]. The above rule
takes precedence over the body rule in [Link], so when you open up [Link] in
a browser, you should see our Roboto Light web font on the top and the default system
font on the bottom:

PREPARED BY: MAHMUD BAKALE & ALIJAFAR UMAR


FONT FAMILIES AND FONT FACES
A single font “family” is made up of multiple font “faces”. Each font face is a different
weight or style in the family. “Weight” refers to the boldness of a particular face, and
“style” refers to whether it’s roman (upright), italic, condensed, extended, or some other
variant in the family.

In our example, Roboto Light is one font face in the Roboto family. The other 17 faces in
the ZIP file we downloaded earlier can be visualized like so:

In CSS, font weights are expressed as numeric values between 100 and 900. Fortunately,
there are relatively standardized, human-friendly terms for each of these numeric values.
“Black” usually means 900, “bold” is 700, “regular” is 400, etc. As you can see above,
most families don’t supply a face for every single weight. Roboto is missing “extra light”
(200), “semi bold” (600), and “extra bold” (800).

It’s worth noting that each style and weight combination is designed as an entirely distinct
face. In a high-quality font family, the condensed styles aren’t simply squashed versions
of the roman faces, nor is the bold face merely a thicker version. Each letter in every face
is hand-crafted to ensure it provides a uniform flow to its text.

PREPARED BY: MAHMUD BAKALE & ALIJAFAR UMAR


This is particularly apparent in the italic and roman faces of many serif fonts. For instance,
the lowercase “a” in Century Schoolbook FS (the font you’re reading right now) takes on
a completely different shape when it’s italicized.

FAKIN’ IT
Why does this weight and style stuff matter to us? The design of most websites utilizes
multiple faces in the same family, so we need to know how to embed several .woff files
that represent related faces.

But first, let’s take a look at what happens when we don’t offer multiple faces. Update the
left-hand paragraph in [Link] to include an <em> and a <strong> element:
<section class='section section--gray'>
<h2>Web Fonts</h2>

<p>This paragraph is using a web font call <em>Roboto Light</em>. It’s a


little more refined and lends some <strong>unique character</strong> to
the web page.</p>
</section>
When you reload the page, you’ll notice that the bold text isn’t really all that bold. This is
because it’s being synthesized. We didn’t supply a bold font face for the <strong> element
to use, so the browser is trying to fake it by auto-converting Roboto Light into a thicker

PREPARED BY: MAHMUD BAKALE & ALIJAFAR UMAR


face. The same thing is going on with the italics in the <em> element, but it’s a little bit
harder to tell. This auto-conversion almost always results in low-quality typography.

To verify that the bold and italic faces really are being synthesized, try adding the following
rule to [Link]. The font-synthesis property determines if a browser is allowed to fake it
or not. At the time of this writing, only Firefox actually pays attention to font-synthesis, so
this won’t work in Chrome or Safari:
/* This will only work in Firefox */
em, strong {
font-synthesis: none;
}
Open up [Link] in Firefox, and the <em> and <strong> elements will no longer be
italic or bold—the entire paragraph will be in roman Roboto Light.

MULTIPLE FONT FACES (THE WRONG WAY)


Let’s try adding Roboto Light Italic and Roboto Bold faces to our example project. Copy
over the following files from the Roboto ZIP file we downloaded earlier into our web-
typography folder:
• roboto_bold_macroman/[Link]
• roboto_lightitalic_macroman/[Link]
A .woff file represents a single face in a particular font family, and @font-face lets us
embed that face in our stylesheet. The naive way to embed these new WOFF files would
be to simply add more @font-face declarations and change the font-
family and src properties as necessary. Try adding the following to the top of [Link]:
/* DON'T NAME FONT FAMILIES LIKE THIS */
@font-face {

PREPARED BY: MAHMUD BAKALE & ALIJAFAR UMAR


font-family: 'Roboto Light Italic';
src: url('[Link]') format('woff');
}

@font-face {
font-family: 'Roboto Bold';
src: url('[Link]') format('woff');
}
Then, to use these faces in our <em> and <strong> elements, we need the
following rules:
/* THIS IS A LITTLE AWKWARD */
em {
font-family: 'Roboto Light Italic', serif;
}

strong {
font-family: 'Roboto Bold', serif;
}
This will work, and you should now see proper italic and bold fonts when you reload web-
[Link] in your browser. The problem is that manually specifying the font-family every
time we want to use an italic or bold font is a little weird. We should be using the CSS font-
style and font-weight properties for this.

PREPARED BY: MAHMUD BAKALE & ALIJAFAR UMAR


We ended up in this awkward situation because of the way we embedded our
new .woff files. Using separate font-family values in @font-face makes them look like
entirely unrelated font faces. It doesn’t reflect the fact that they are all actually part of the
Roboto family.

For this reason, you should never use the above technique to embed multiple faces that
are in the same font family. Go ahead and delete both of the above snippets before moving
on.

MULTIPLE FONT FACES (THE RIGHT WAY)


To maintain the familial relationship between our three font faces, they all need to use a
shared Roboto value for their font-family property. To distinguish between our light, italic,
and bold faces, we’ll add font-style and font-weight properties to the at-rule. Replace all
the @font-face declarations in [Link] with the following:
@font-face {
font-family: 'Roboto';
src: url('[Link]') format('woff');
font-style: normal;
font-weight: 300;
}

@font-face {
font-family: 'Roboto';
src: url('[Link]') format('woff');
font-style: italic;
font-weight: 300;
}

@font-face {
font-family: 'Roboto';
src: url('[Link]') format('woff');
font-style: normal;

PREPARED BY: MAHMUD BAKALE & ALIJAFAR UMAR


font-weight: 700;
}
Think of each @font-face at-rule as a description of the underlying .woff file. The
first @font-face is saying it’s a Roboto font that’s roman (normal) and has a font weight of
300 (aka “light”). The second says it’s also in the Roboto family and has a weight of 300,
but it’s italic. Finally, the third at-rule lets our the browser know that Roboto-Bold-
[Link] contains the 700-weight (aka “bold”) roman face.

Letting the browser know that our font faces are related makes our CSS much more
intuitive. We can set the default font family and weight in our body selector. Then, when
we want to use italics or bold for a particular element, we can simply specify a font-
style or font-weight and the browser will pull the corresponding .woff file:
body {
font-family: 'Roboto', sans-serif;
font-weight: 300;
/* ... */
}

em {
font-style: italic;
}

PREPARED BY: MAHMUD BAKALE & ALIJAFAR UMAR


strong {
font-weight: bold; /* Or 700 */
}

These happen to be the default font-style and font-weight values


for <em> and <strong> elements, so we don’t really need to include the last two rules here.
Note that the only human-friendly keywords available for font-weight are normal (400)
and bold (700). Any other boldness levels need to set numerically.

EXTERNALLY HOSTED WEB FONTS


Ok! That was complicated. Next, we’re going to explore the easier method of using web
fonts: externally hosted via Google Fonts. This lets us skip the first two steps of locally
hosted fonts. Instead of adding .woff files to our project and embedding them with @font-
face, we can let Google Fonts do this part for us.

In this section, we’re going to be working on [Link], so open up that file in both
your text editor and a web browser. If you want a brief history of typography going all
the way back to the first printing press, take a quick read through the example text.

PREPARED BY: MAHMUD BAKALE & ALIJAFAR UMAR


Right now, each section in [Link] is using Roboto Light, but we’re going to
change all of them to be representative of the period they’re talking about.

Let’s begin by changing the font for the Gothic/Blackletter section. In Google Fonts,
search for UnifrakturMaguntia. It should look like something a monk wrote in the
middle ages. Click Select this font. In the pop-up menu, you’ll see a <link/> element.
Copy this into the <head> of [Link], above the <link/> element that includes
our [Link] stylesheet.

<link href="[Link] rel="stylesheet">

Remember that <link/> is how we include an external stylesheet, and that’s exactly what
the above HTML is doing. However, instead of linking to a local CSS file, it’s including
some CSS defined by Google Fonts. If you paste the href value into your browser, you’ll
find the same @font-face declaration that we used in the previous section—except we
didn’t actually have to write it this time. Yay!

PREPARED BY: MAHMUD BAKALE & ALIJAFAR UMAR


Now that we’ve embedded our UnifrakturMaguntia web font, we should be able to use it
to style any HTML element we want. Add the following to the <head> of [Link]:
<style>
.blackletter {
font-family: 'UnifrakturMaguntia', cursive;
}
</style>
That first section has a class='blackletter' attribute, so it should now be printed in gothic
letters:

Google Fonts are a quick and easy solution, but professional sites should typically use
locally hosted web fonts. This gives you a lot more flexibility (you’re not limited to
Google’s font offering) and can have performance/reliability gains if you’ve optimized the
rest of your site correctly.

TOO MANY FONT FILES


Speaking of performance, let’s do something awful. There’s another 10 sections on
our [Link] page, and we want to give each one its own web font. We can embed

PREPARED BY: MAHMUD BAKALE & ALIJAFAR UMAR


multiple fonts in a single <link/> element, so change our Google Fonts stylesheet to include
the rest of them:
<link
href="[Link]
ville|Lobster|Questrial|Rokkitt|Rufina|Sorts+Mill+Goudy|UnifrakturMaguntia" rel="stylesheet">
Note that you can generate this in Google Fonts by selecting multiple fonts before
copying the <link/> element. Next, add all these new fonts to the <style> element
of [Link]:
.old-style {
font-family: 'Sorts Mill Goudy', serif;
}
.transitional {
font-family: 'Libre Baskerville', serif;
}
.didot {
font-family: 'Rufina', serif;
}
.slab {
font-family: 'Rokkitt', serif;
}
.fat-face {
font-family: 'Alfa Slab One', cursive;
}
.grotesque {
font-family: 'Roboto', sans-serif;
}
.geometric {
font-family: 'Questrial', sans-serif;
}
.humanist {
font-family: 'Lato', sans-serif;
}
.display {
font-family: 'Lobster', cursive;
}

PREPARED BY: MAHMUD BAKALE & ALIJAFAR UMAR


.monospace {
font-family: 'Droid Sans Mono', monospace;
}
Now, each section of [Link] is rendered in a font from the era it’s describing. This
serves as a nice introduction to the historic significant of different fonts, but you
should never, ever include this many web fonts on a real web page.
Don’t forget that each web font is actually a .woff or .woff2 file that your browser needs
to load before it can render the page. More fonts means longer load times. The key to using
web fonts effectively is to find a balance between performance (fewer web fonts) and a
beautifully typeset document (more web fonts).

And that’s more than you could ever want to know about web fonts. The rest of this chapter
shifts gears into basic typographic principles. These are simple guidelines (with simple
CSS implementations) that often make the difference between a professional web page and
an amateur one.

PARAGRAPH INDENTS
Separating paragraphs from one another is one of the most fundamental functions of
typography. There’s two generally accepted solutions: either use a first-line indent or a
margin between the paragraphs. Your readers (hopefully) aren’t stupid—they don’t need
two signs that a new paragraph is happening, so never use both an indent and a margin.
That would be redundant.

PREPARED BY: MAHMUD BAKALE & ALIJAFAR UMAR


The CSS text-indent property defines the size of the first-line indent of a particular element
(usually a <p>). We can explore this in our [Link] page. Go ahead and change the
existing bottom margin styles in the first section to an indent by adding the following rules
to the <style> element:
<style>
.paragraph-indent p {
text-indent: 1em;
margin-bottom: 0;
}
.paragraph-indent p:first-of-type {
text-indent: 0;
}
</style>
Note that the first paragraph after a heading should never be indented because, well, it’s
usually pretty obvious that it’s a new paragraph. This is a pretty good use case for the :first-
of-type pseudo-class.

And here’s a negative example so we remember what not to do. Add this to the page-
specific styles in [Link]:

/* DESIGNERS WILL JUDGE YOU FOR THIS */


.never-both p {
text-indent: 1em;

PREPARED BY: MAHMUD BAKALE & ALIJAFAR UMAR


margin-bottom: 1em;
}
It might seem silly, but we’re not kidding when we say that good designers will judge you
for this.

TEXT ALIGNMENT
The alignment of text has a subconscious impact on how you read it. You’ve probably
never noticed it before, but your eyes don’t move in a smooth motion as they read over a
paragraph—they jump from word to word and from line to line. Your eyes fixate on certain
spots and skip over other ones.

In a well-designed HTML document, text alignment is never an arbitrary decision. It takes


into account this little bit of human physiology. Good text alignment actually makes it
easier for users to read your content by giving their eyes an anchor to jump to when they
move from line to line.

The next few sections explain the proper times to use left, center, right, and justified text
alignment. All of these examples rely on the text-align property, which controls the text
alignment of a particular HTML element. We set up the [Link] page in our
example project with some convenient scenarios.

PREPARED BY: MAHMUD BAKALE & ALIJAFAR UMAR


LEFT ALIGNMENT
Most of your text should be left-aligned because it gives the reader a vertical anchor to
jump back to on every line. Long runs of text, in particular, should almost always be left-
aligned. Short runs of text and headings have a little bit more leeway.

Left alignment is the default value for text-align, but if we wanted to be explicit, we could
add the following rule to the <style> element of our [Link] file:
<style>
.left {
text-align: left;
}
</style>
Of course, if you’re working on a website that’s in a language that’s written right-to-left
instead of left-to-right (like Arabic), you can go ahead and swap all this advice with
the Right Alignment section below.

CENTER ALIGNMENT
Center-aligned text doesn’t have that anchor, so it’s easier for the eye to get lost when it
tries to jump to the next line. It’s best suited for short line lengths (more on that later) and
for special kinds of content like poems, lyrics, and headings.

PREPARED BY: MAHMUD BAKALE & ALIJAFAR UMAR


Go ahead and center-align the second paragraph in [Link] with another page-
specific style:
.center {
text-align: center;
}
Notice how the page now feels a little disjointed. The center-aligned second paragraph
breaks the flow of the left-aligned first paragraph. Generally speaking, text alignment
should be consistent throughout a web page. If you’re going to center a heading,
center all of your headings.

RIGHT ALIGNMENT
Another consideration when choosing text alignment is the relationship it creates with the
surrounding elements. For instance, take a look at that third section in [Link]. We
want to move the image’s caption to the left of the image and right-align it to make it look
like it’s attached to the image:

PREPARED BY: MAHMUD BAKALE & ALIJAFAR UMAR


Our example image is wrapped in a <figure> and the caption text is in a <figcaption>, so
adding the following to the <style> element of [Link] should result in the above
layout.
figcaption {
display: none;
}
@media only screen and (min-width: 900px) {
figure {
position: relative;
}
figcaption {
display: block;

font-style: italic;
text-align: right;
background-color: #FFFFFF;

position: absolute;
left: -220px;
width: 200px;
}
}
This also happens to be a good example of advanced positioning. The relative position of
the <figure> sets the coordinate system for the <figcaption>’s absolute positioning. By
nudging the caption left by 220px and giving it an explicit width of 200px, we get a nice
20-pixel margin between the image and its caption.

Like centered text, right alignment should usually be reserved for these kinds of special
design scenarios because its jagged left edge makes it harder for the reader to find the next
line.

PREPARED BY: MAHMUD BAKALE & ALIJAFAR UMAR


JUSTIFIED TEXT
Justified text is created by subtly adjusting the space between words/letters and splitting
long words with hyphens until each line is the same width. Without a high-quality
hyphenation engine, justified text results in awkwardly large spaces between words. These
uneven spaces make it harder for the eye to move horizontally across the text.

Unfortunately, most browsers don’t have any kind of built-in hyphenation engine, so
you’re better off avoiding justified text in HTML documents. We can take a look by adding
one more text-align rule to our [Link] file:
.justify {
text-align: justify;
}
Compare this with the left-aligned paragraph. It’s subtle, but the left-aligned paragraph is
more uniform and inviting.

VERTICAL TEXT SPACING


Just as alignment isn’t an arbitrary decision, neither is the space between text. In this
section, we’re concerned with the responsible use of three CSS properties:

PREPARED BY: MAHMUD BAKALE & ALIJAFAR UMAR


• margin-top (or padding-top)
• margin-bottom (or padding-bottom)
• line-height
The first two should be pretty familiar by now, and they define the vertical space between
separate paragraphs. The new line-height property determines the amount of space
between lines in the same paragraph. In traditional typography, line-height is called
“leading” because printers used little strips of lead to increase the space between lines of
text.

Together, these properties control the “vertical rhythm” of a web page. There’s all sorts of
techniques to figure out the “optimal” vertical rhythm for a given layout, but the general
principles are:
• Give things enough space to breath.
• Use consistent spacing throughout the page.
To demonstrate this, we’re going to destroy the vertical rhythm in the second half of
our [Link] page. Go ahead and add the following page-specific styles
to [Link]
<style>
.messy {
line-height: 1.2em;
}
.messy h2 {
line-height: .9em;
}
.messy:last-of-type {
line-height: 1.5em;
}
.messy:last-of-type h2 {
margin-bottom: .3em;
}
.messy .button:link,
.messy .button:visited {

PREPARED BY: MAHMUD BAKALE & ALIJAFAR UMAR


margin-top: 0;
}
</style>
A few small changes to line height, paddings, and margins can have a dramatic impact on
the quality of a page:

There’s a surprising amount of math and psychology that goes into calculating the vertical
rhythm of a page, but that’s a job for your designer. As a developer, you need to know the
CSS properties to implement what they’re asking for. More importantly, you have to
understand that your designer really cares about this kind of stuff, so you should be paying
very careful attention to your margin, padding, and line-height properties.

PREPARED BY: MAHMUD BAKALE & ALIJAFAR UMAR


LINE LENGTH
If the vertical spacing of your text isn’t arbitrary, it should be no surprise that the
horizontal spacing isn’t, either. “Line length” or “measure” refers to the horizontal
length of your text. You can think of it as the number of characters or words that fit into
a single line. Measure has everything to do with the following CSS properties:
• width
• margin-left (or padding-left)
• margin-right (or padding-right)
A good rule-of-thumb is to limit the number of characters on a single line to around 80.
Like alignment, this subtly affects the readability of your content. It takes energy for your
eye to move from the left edge of a paragraph to the right, and the farther it has to scan, the
faster it gets tired. Longer lines also make it easier to get lost when you finish a line and
need to jump back to the beginning of the next line.

These are the reasons why so many websites (including this one) use fixed-width layouts or
split content into multiple columns on wider screens. Without constraining the width of the
page or dividing it into manageable columns, line length becomes unacceptably long.

In our example project, the [Link] file has decent measure. Let’s see what
happens when we break the bottom half of the page by adding the following to its <head>:
<style>
@media only screen and (min-width: 580px) {
.not-so-manageable {

PREPARED BY: MAHMUD BAKALE & ALIJAFAR UMAR


max-width: 100%;
margin-left: 2em;
margin-right: 2em;
}
}
</style>
Now, the second section stretches to fill the full width of the browser window. It feels a
little bit more unapproachable due to the long line length. Again, the goal of good web
typography is to make it as easy as possible for visitors to digest your content.

OTHER BASIC
TYPOGRAPHY GUIDELINES
That should be enough to get you on your way towards quality web typography.
Typography is a whole industry, and we’ve barely scratched the surface. However,
getting any deeper into it would be more design than web development, so we’ll just
leave you with a few final guidelines:
• Use a font-size between 14px and 20px for the body element.
• Use “curly quotes” and apostrophes with the &rsquo;, &lsquo;, &rdquo;,
and &ldquo; HTML entities.
• Use proper dashes (&ndash;, &mdash;) and other symbols (&copy;).
• Don’t use text-decoration: underline except for hover states.
• Use real italic fonts over synthesized ones if not it’s too much of a performance
burden.
If you find this stuff fascinating, Practical Typography has a fantastic list of general rules
to follow when typesetting a document.

SUMMARY
The goal of this chapter was twofold:

PREPARED BY: MAHMUD BAKALE & ALIJAFAR UMAR


• Learn the mechanics of web fonts and basic CSS typography properties.
• Understand how designers think about typography.
You might not be able to create a beautifully typeset web page from scratch after reading
this chapter, but that wasn’t the point. It was to make you aware of the invisible art of
typography. You should now have the vocabulary to talk about things like font families,
faces, weights, and styles, as well as leading, measure, and vertical rhythm.

The most important thing you should take away from this chapter is the fact that nothing
is arbitrary in a well-designed web page. The font sizes, indent style, text alignment, line
height, margins, and every other tiny facet of the page was carefully considered. There was
a purpose behind all of these decisions.

All of the CSS properties we’ve covered throughout this tutorial are actually kind of simple.
When it comes down to it, we’ve really just been moving a bunch of boxes around,
changing some colors, and altering the appearance of our text. The meaning behind these
things comes from the underlying design and the business goals of the website you’re
implementing.

But, that’s for another tutorial. Believe it or not, you’ve reached the end of HTML & CSS
is Hard. We’ve covered all the HTML elements and CSS properties you need to build
professional web pages. The only thing missing is experience. Your next step is to practice
all these new skills by building a bunch of web pages from scratch.
Stay tuned for more tutorials!

PREPARED BY: MAHMUD BAKALE & ALIJAFAR UMAR

You might also like