Prerequisites

Welcome!

Heya! In this course, we’ll build on HTML and look into the fundamentals of CSS, the secret sauce of every beautiful web page.

Before we get started, let's see what this snippet of HTML and CSS code does.

<!doctype html>
<html>
 <head>
  <style>
   body {
    background-color: #00cd6f;
    color: #ffffff;
   }
  </style>
 </head>
 <body>
  I'm back!
 </body>
</html>

Sweet! Now you may ask: "Is this it?" The answer is no, we're just warming up!

CSS

CSS, which is short for Cascading Style Sheets, describes the presentation of web pages.

<html>
 <body style="color:red;">
  Hi, I'm the content part.
 </body>
</html>


If HTML describes and structures a web page, CSS takes care of its look and feel.

Inline styles

Do you remember the styles chapter of the HTML micro-course? Back then we've used the style attribute to format HTML elements.

<!doctype html>
<html>
 <body style="font-family:verdana;">
  I need CSS treatment.
 </body>
</html>

As if it were yesterday! Inline styles help us apply a unique style for a single HTML element.

Limitations

Inline styles, however, have quite a few limitations and lose many of the advantages of style sheets.

<!doctype html>
<html>
 <body>
  <p style="color:blue;font-size:14px;">I need CSS treatment.</p>
  <p style="color:blue;font-size:14px;">Me too.</p>
 </body>
</html>

You've still got it! If we want to apply the same style to several HTML elements, we start getting duplicate code.

Internal style sheets

We can put CSS declarations between <style> tags, right in the web page's head section.

<!doctype html>
<html>
 <head>
  <style>
   p {
    color: blue;
    font-size: 14px;
   }
  </style>
 </head>
 <body>
  <p>I need CSS treatment.</p>
  <p>Me too.</p>
 </body>
</html>

These internal style sheets work if a web page has a unique style that doesn't apply to other web pages.

Separations can be good

Often times, however, we want a style to apply to whole web sites.

<!doctype html>
<html>
 <head>
  <title>Web page 1</title>
  <style>
   p { font-size: 12px; }
  </style>
 </head>
</html>
<!doctype html>
<html>
 <head>
  <title>Web page 2</title>
  <style>
   p { font-size: 12px; }
  </style>
</head>
</html>

Yay! If we wanted to change the font size for every paragraph on the web site, we'd have to go through every single web page.

External style sheets

That's why it makes a lot of sense to style web pages and web sites by linking external style sheets.

<!doctype html>
<html>
 <head>
  <link rel="stylesheet" type="text/css" href="https://web link to css file">
 </head>
 <body>
  I could be a part-time model.
 </body>
</html>

Fantastic! The <link> tag is an empty tag that establishes a link between a web page and an external resource.

CSS files

External style sheets are text files with CSS code and a .css extension. Like HTML files, we can use any text editor to create them.

//style.css

p {
color: blue;
font-size: 14px;
}

//webpage.html

<!doctype html>
<html>
 <head>
  <link rel="stylesheet" type="text/css" href="style.css">
 </head>
 <body>
  <p>I need CSS treatment.</p>
  <p>Me too.</p>
 </body>
</html>

Sweet! The <link> tag consists of a type attribute that's "text/css", a rel attribute that's "stylesheet" and an href attribute that points to the CSS file.

Cascading order

When we open a web page, the style sheets cascade into a single sheet. If there are conflicts, the last-read style will be used.

//style.css

p {
 color: yellow;
 font-size: 14px;
}

//webpage.html

<!doctype html>
<html>
 <head>
  <link rel="stylesheet" type="text/css" href="style.css">
  <style>
   p { color: blue; }
  </style>
 </head>
 <body>
  <p>I need CSS treatment.</p>
  <p style="color:red;">Me too.</p>
 </body>
</html>


See how there's no yellow text? That's because the internal style sheet overrides the external one, leaving the final color as blue.

Rules

In a nutshell, the rules of a style sheet consist of selectors and declarations.

Let's start with selectors, which can select HTML elements based on their types, IDs, classes and more.

//style.css

/* Pick a selector: */
body {
 font-family: "Lucida Grande";
}

//webpage.html

<!doctype html>
<html>
 <head>
  <link rel="stylesheet" type="text/css" href="style.css">
 </head>
 <body>I need CSS treatment.</body>
</html>

Nice! This selector, for example, finds every HTML element with the same tag on the web page and changes its font family to "Lucida Grande".

Psst: anything we write between /* and */ is considered as a comment and has no effects on the style sheet.

Declaration blocks

As you've seen, declaration blocks are enclosed in braces and consist of declarations that are separated by semicolons.

//style.css

body {
 color: darkgray; 
 font-family: "Lucida Grande";
}

//webpage.html

<!doctype html>
<html>
 <head>
  <link rel="stylesheet" type="text/css" href="style.css">
 </head>
 <body>
  I need CSS treatment.
 </body>
</html>

Great work! Even though the last declaration in a block doesn't have to finish with a semicolon, it's a great idea to include it.

Declarations

A declaration consists of a property, a colon, and a value.

Depending on the property, the value can be a number, a word or some kind of measure.

//style.css

body {
 color: darkgray;
 font-family: "Lucida Grande";
 text-align: right;
}

//webpage.html

<!doctype html>
<html>
 <head>
  <link rel="stylesheet" type="text/css" href="style.css">
 </head>
 <body>
  I need CSS treatment.
 </body>
</html>

Nice! It's a great practice to finish every declaration with a semicolon.

Type selectors

Now, let's get back to the original topic! We've already used type selectors in the past. Do you remember?

//style.css

p {
 color: green;
}

//webpage.html

<!doctype html>
<html>
 <head>
  <link rel="stylesheet" type="text/css" href="style.css">
 </head>
 <body>
  <p>I'm a paragraph, what do you want?</p>
 </body>
</html>

Fantastic! Type selectors find HTML elements based on their tags, which is why we also call them element selectors.

Unique identifiers

What if we have multiple elements but only want to select a particular element? We can use the id attribute to give it a hook.

//webpage.html

<!doctype html>
<html>
 <head>
  <link rel="stylesheet" type="text/css" href="style.css">
 </head>
 <body>
  <p id="topParagraph">I'm a paragraph, what do you want?</p>
  <p>I'm a paragraph as well.</p>
 </body>
</html>

Sweet! With the id attribute, we can create a unique identifier for an HTML element. Let's find out how we can make use of it!

ID selectors

We create an ID selector using the hash symbol and, unsurprisingly, an ID name, which is the value in an id attribute.

//style.css

#topParagraph {
 font-size: 16px;
}

//webpage.html

<!doctype html>
<html>
 <head>
  <link rel="stylesheet" type="text/css" href="style.css">
 </head>
 <body>
  <p id="topParagraph">I'm a paragraph, what do you want?</p>
  <p>I'm a paragraph as well.</p>
 </body>
</html>

Great! The ID selector selects the HTML element with a topParagraph value for its id attribute.

Psst: an HTML element can only have one ID and a web page can only have one HTML element with the same ID.

Classes

What if we have multiple HTML elements but, this time, want to select a bunch of particular elements? Let's make use of the class attribute!

//webpage.html

<!doctype html>
<html>
 <head>
  <link rel="stylesheet" type="text/css" href="style.css">
 </head>
 <body>
  <p>I'm a paragraph, what do you want?</p>
  <p class="box">I'm a paragraph as well.</p>
  <div class="box">I'm not, so what?</div>
 </body>
</html>

Fantastic! With the class attribute, we create a hook for multiple HTML elements. Let's find out how we can make use of it!

Class selectors

We create a class selector using a full stop and a class name, which is a value from a class attribute.

//style.css

.box {
 border-style: solid;
}

//webpage.html

<!doctype html>
<html>
 <head>
  <link rel="stylesheet" type="text/css" href="style.css">
 </head>
 <body>
  <p>I'm a paragraph, what do you want?</p>
  <p class="box">I'm a paragraph as well.</p>
  <div class="box">I'm not, so what?</div>
 </body>
</html>

Sweet! Classes are a great way to apply styles to multiple HTML elements, regardless of their type.

Multiple classes

Apart from creating a hook for multiple HTML elements with a single class selector, an HTML element can have multiple classes.

//style.css

.box {
 border-style: solid;
}
.primary-text {
 font-family: "Lucida Grande"
}

//webpage.html

<!doctype html>
<html>
 <head>
  <link rel="stylesheet" type="text/css" href="style.css">
 </head>
 <body>
  <p class="primary-text">I'm a paragraph, what do you want?</p>
  <p class="box">I'm a paragraph as well.</p>
  <div class="box primary-text">I'm not, so what?</div>
 </body>
</html>

See that? Multiple classes are space-separated in the class attribute and help us reuse styles that we'd otherwise have to repeat.

Data types

There are quite a few data types for property values. font-size, for example, accepts keywords, lengths and percentages.

//style.css

p {
 font-size: 18px;
}

//webpage.html

<!doctype html>
<html>
 <head>
  <link rel="stylesheet" type="text/css" href="style.css">
 </head>
 <body>
  <p>Dream of para-para-paragraphs</p>
 </body>
</html>

See that? If we use data types that are based on numbers, we can use whole or floating-point numbers.

Pixels

Before we deep-dive into properties, let's take a quick look at the most important length units.

Typically, a pixel represents a small but visible dot on our screen.

//styles.css

p {
 border-style: solid;
 border-width: 1px;
}

//webpage.html

<!doctype html>
<html>
 <head>
  <link rel="stylesheet" type="text/css" href="styles.css">
 </head>
 <body>
  <p>Dream of para-para-paragraphs</p>
 </body>
</html>

Pixels are absolute units, which means they work whenever we want things to have a particular size.

Ems-n-ems

So-called ems are relative length units that depend on the default font size. For example, 0.5em stands for half the default font size.

//styles.css

p {
 font-family: "Lucida Grande";
 font-size: 0.5em;
}

//webpage.html

<!doctype html>
<html>
 <head>
  <link rel="stylesheet" type="text/css" href="styles.css">
 </head>
 <body>
  <p>Dream of para-para-paragraphs</p>
 </body>
</html>

Good job! Ems are great on smartphone screens because they leave the question of exactly how big to make something to the web browser.

Dimensions

There are properties that allow us to control the height and width of block-level HTML elements.

//style.css

.box {
 border-style: solid;
 width: 100%;
 height: 50px;
}

//webpage.html

<!doctype html>
<html>
 <head>
  <link rel="stylesheet" type="text/css" href="style.css"/>
 </head>
 <body>
  <div class="box"></div>
 </body>
</html>

Of course! We can set the dimensions of block-level HTML elements with the width and height properties.

Fonts

So far, we've only changed the font family and the font size of HTML elements. There are many more things we can tinker with.

//style.css

.trailer {
 font-family: "Lucida Grande";
 font-size: 1.5em;
 font-style: italic;
 font-weight: bold;
}

//webpage.html

<!doctype html>
<html>
 <head>
  <link rel="stylesheet" type="text/css" href="style.css"/>
 </head>
 <body>
  <p class="trailer">I'm font of you because you're my type.</p>
 </body>
</html>

Sweet! While we can use font-style to italicize a font, we can set its weight, or thickness, with the font-weight property.

Psst: in addition to keywords like normal and bold, there are nine numeric values (100 to 900) that represent different weights.

Backup fonts

Have you ever sent a document to a friend, only to find out that they didn't have the right font to view it?

A not-so-common font family on a website, might not be available to some folks. That's why it's great to use a backup font family.

//style.css

.headline {
 font-family: "Akzidenz-Grotesk", "Helvetica", "Serif";
 font-size: 1.5em;
 font-weight: bold;
}

//webpage.html

<!doctype html>
<html>
 <head>
  <link rel="stylesheet" type="text/css" href="style.css"/>
 </head>
 <body>
  <h1 class="headline">I shot the serif</h1>
 </body>
</html>

Shorthand properties

Shorthand properties allow us to set the values of several properties in a single declaration.

//style.css

.trailer {
 font: italic bold 1.5em "Lucida Grande", sans-serif;
}

//webpage.html

<!doctype html>
<html>
 <head>
  <link rel="stylesheet" type="text/css" href="style.css"/>
 </head>
 <body>
  <div class="trailer">I'm font of you because you're my type.</div>
 </body>
</html>

Sweet! The font property combines all font-related properties in a single declaration.

Psst: we have to include values for font-size and font-family; if any of the other values are missing, the default values will be used.

Borders

There's another shorthand property that allows us to set the width, style and color of an HTML element's border.

//style.css

.box {
 border: 2px dotted red;
}

//webpage.html

<!doctype html>
<html>
 <head>
  <link rel="stylesheet" type="text/css" href="style.css">
 </head>
 <body>
  <div class="box">Jack</div>
 </body>
</html>

Fantastic! How in the world did we survive without shorthand properties like border?

Colors

Before we get back to your web site, let's talk some more about colors! As we've seen, there's a bunch of standard names that we can use.

//style.css

.box {
 color: firebrick;
 background-color: goldenrod;
 border: 2px solid firebrick;
}

//webpage.html

<!doctype html>
<html>
 <head>
  <link rel="stylesheet" type="text/css" href="style.css"/>
 </head>
 <body>
  <div class="box">Gryffindor</div>
 </body>
</html>

Good stuff! There are as many as 140 standard names that include a whole lot of weird names like papayawhip and peachpuff.

Hexadecimal colors

That said, standard names don't include every possible color.

What if we want to use burnt orange? That's when hexadecimal colors come in handy.

//style.css

.box {
 color: #fff;
 background-color: #bf5700;
}

//webpage.html

<!doctype html>
<html>
 <head>
  <link rel="stylesheet" type="text/css" href="style.css"/>
 </head>
 <body>
  <div class="box">Hook 'em!</div>
 </body>
</html>

Hexadecimal colors are common on the Web. They start with a hash symbol and have three or six digits.

The box model

In this chapter, we'll talk some more about design and layout.

The so-called box model defines that there's a box around every HTML element and describes the amount of space the element takes up.

//style.css

p {
 background-color: #44b3c2;
 width: 150px;
 padding: 25px;
 border: 25px solid #f1a94e;
 margin: 25px;
}

//webpage.html

<!doctype html>
<html>
 <head>
  <link rel="stylesheet" type="text/css" href="style.css">
 </head>
 <body>
  <p>I'm the actual content.</p>
 </body>
</html>

Sweet! HTML elements consist of borders, padding, margins and, well, the actual content. But what exactly are these things?

Display

By default, block-level elements take up the full width of their surrounding elements.

Using the different display value, however, we can change that.

//style.css

.box {
 background-color: gray;
 width: 50px;
 height: 25px;
 display: inline;
}

//webpage.html

<!doctype html>
<html>
 <head>
  <link rel="stylesheet" type="text/css" href="style.css">
 </head>
 <body>
  <div class="box"></div>
  <div class="box"></div>
 </body>
</html>

Nice! But what happened to the boxes?

Inline

Let's find out by giving the boxes a border!

//style.css

.box {
 background-color: gray;
 width: 50px;
 height: 25px;
 border: 1px solid black;
 display: inline;
}

//webpage.html

<!doctype html>
<html>
 <head>
  <link rel="stylesheet" type="text/css" href="style.css">
 </head>
 <body>
  <div class="box"></div>
  <div class="box"></div>
 </body>
</html>

As it turns out, inline elements don't have widths and heights. Therefore, they take up exactly as much space as their content needs.

Inline-block

Then, how do we get the boxes lined up with the widths and heights we want them to have?

//style.css

.box {
 background-color: gray;
 width: 50px;
 height: 25px;
 border: 1px solid black;
 display: inline-block;
}

//webpage.html

<!doctype html>
<html>
 <head>
  <link rel="stylesheet" type="text/css" href="style.css">
 </head>
 <body>
  <div class="box"></div>
  <div class="box"></div>
 </body>
</html>

Way to go! Inline-block elements are like inline elements, except they can have widths and heights.

Poof!

We can choose between two different approaches to hide elements.

//style.css

.box {
 background-color: gray;
 width: 50px;
 height: 25px;
 border: 1px solid black;
}
#box1 {
 visibility: hidden;
}
#box2 {
 display: none;
}

//webpage.html

<!doctype html>
<html>
 <head>
  <link rel="stylesheet" type="text/css" href="style.css">
 </head>
 <body>
  <div class="box" id="box1"></div>
  <div class="box" id="box2"></div>
 </body>
</html>

Poof! Using visibility, the element is hidden but still takes up space; using display, the web page is displayed as if the element didn't exist.

Margins

Margins are the outermost part of the box model, creating white space around an element; separating it from its neighbors.

//style.css

p {
 border: 2px solid #44b3c2;
 margin-top: 10px;
 margin-right: 25px;
 margin-bottom: 10px;
 margin-left: 25px;
}

//webpage.html

<!doctype html>
<html>
 <head>
  <link rel="stylesheet" type="text/css" href="style.css">
 </head>
 <body>
  <p>I'm the actual content.</p>
 </body>
</html>

Fantastic! We can set the white space outside of an element's borders for every side of the element.

The margin shorthand

If we want to shorten the declaration, we can use a special shorthand property.

//style.css

p {
 border: 2px solid #44b3c2;
 margin: 10px 25px 10px 25px;
}

//webpage.html

<!doctype html>
<html>
 <head>
  <link rel="stylesheet" type="text/css" href="style.css">
 </head>
 <body>
  <p>I'm the actual content.</p>
 </body>
</html>

Great! The margin property uses a clockwise sequence: top, right, bottom, left.

Padding

The padding is the innermost part of the box model, creating white space around an element's content and inside of its margins and borders.

//style.css

p {
 padding: 25px;
 border: 2px solid #44b3c2;
}

//webpage.html

<!doctype html>
<html>
 <head>
  <link rel="stylesheet" type="text/css" href="style.css">
 </head>
 <body>
  <p>I'm the actual content.</p>
 </body>
</html>

Perfect! We can set the white space inside of an element's margins and borders individually or with the paddingshorthand property.

Total dimensions

By setting the width and height of an element, we're actually setting the size of its content.

The total dimensions include its padding, borders and margins.

//style.css

p {
 background-color: #44b3c2;
 width: 150px;
 height: 100px;
 padding: 25px;
 border: 25px solid #f1a94e;
 margin: 25px 0px;
}

//webpage.html

<!doctype html>
<html>
 <head>
  <link rel="stylesheet" type="text/css" href="style.css">
 </head>
 <body>
  <p>I'm the actual content.</p>
 </body>
</html>

Sweet! Including the paragraph's padding, borders and margins on every side, its total width is 300px; its total height is 200px.

Box-sizing

The element's dimension properties don't refer to the visible dimensions of an element but its actual content.

Changing the box-sizing property allows us to include the padding and borders in an element's total dimensions.

//style.css

.box {
 width: 300px;
 height: 100px;
 padding: 25px;
 border: 2px solid black;
 margin: 25px;
}
#box2 {
 box-sizing: border-box;
}

//webpage.html

<!doctype html>
<html>
 <head>
  <link rel="stylesheet" type="text/css" href="style.css">
 </head>
 <body>
  <div class="box" id="box1"></div>
  <div class="box" id="box2"></div>
 </body>
</html>

Do you see the difference? Using border-box, the dimension properties include the actual content, padding and borders (but not the margins).

Floating on

Now that we know about the box model, let's talk about positioning elements on a web page, starting with floats!

When an element is floated, it's taken out of the normal flow and placed along the left or right side of its parent.

//style.css

img {
 float: right;
 margin: 10px;
}

//webpage.html

<!doctype html>
<html>
 <head>
  <link rel="stylesheet" type="text/css" href="style.css">
 </head>
 <body>
  <p><img src="https://www.pywe.org/static/edufield/img/logo.png">I backed my car into a cop car the other day. Well, he just drove off - sometimes life's okay. I ran my mouth off a bit too much, ah what did I say? Well, you just laughed it off and it was all okay. And we'll all float on okay ...</p>
 </body>
</html>

Nice! In its simplest use, float wraps the text of a paragraph around an image.

Lining up

Floated elements go to the left or right until they reach the boundaries of their parent or another floated element.

//style.css

.box {
 width: 200px;
 height: 200px;
 float: left;
}
.blue { background: #44accf; }
.green { background: #b7d84b; }
.orange { background: #e2a741; }
.pink { background: #ee3e64; }

//webpage.html

<!doctype html>
<html>
 <head>
  <link rel="stylesheet" type="text/css" href="style.css">
 </head>
 <body>
  <div class="blue box"></div>
  <div class="green box"></div>
  <div class="blue box"></div>
  <div class="green box"></div>
 </body>
</html>

Psst: background is a shorthand property that allows us to set many background-related properties in a single declaration.

Hide-and-seek

As floated elements are taken out of the normal flow, elements that follow a floated element act as if the floated element didn't exist.

//style.css

.box {
 width: 200px;
 height: 200px;
}
.blue { background: #44accf; }
.green { background: #b7d84b; }
.orange { background: #e2a741; }
.pink { background: #ee3e64; }
.floated { float: left; }

//webpage.html

<!doctype html>
<html>
 <head>
  <link rel="stylesheet" type="text/css" href="style.css">
 </head>
 <body>
  <div class="blue floated box"></div>
  <div class="green floated box"></div>
  <div class="orange box"></div>
  <div class="pink box"></div>
 </body>
</html>

Now the orange box is right underneath the blue box, because the blue and green boxes act as if the others weren't there.

Clearing floats

That said, how can we make the orange box show up again? Well, we can use clear to put it back into the normal flow.

//style.css

.box {
 width: 200px;
 height: 200px;
}
.blue { background: #44accf; }
.green { background: #b7d84b; }
.orange { background: #e2a741; }
.pink { background: #ee3e64; }
.floated { float: left; }
.cleared { clear: left; }

//webpage.html

<!doctype html>
<html>
 <head>
  <link rel="stylesheet" type="text/css" href="style.css">
 </head>
 <body>
  <div class="blue floated box"></div>
  <div class="green floated box"></div>
  <div class="orange cleared box"></div>
  <div class="pink box"></div>
 </body>
</html>

Sweet! By setting the clear property to left, we're telling the orange box that it needs to sit below any element that uses float: left.

Web page layouts

Aside from wrapping text around images, the float property is incredibly useful to create layouts.

//style.css

#header {
 background: #44accf;
 height: 50px;
}
#content {
 background: #b7d84b;
 width: 75%;
 height: 500px;
 float: left;
}
#navigation {
 background: #e2a741;
 width: 25%;
 height: 500px;
 float: right;
}
#footer {
 background: #ee3e64;
 height: 50px;
 clear: both;
}

//webpage.html

<!doctype html>
<html>
 <head>
  <link rel="stylesheet" type="text/css" href="style.css">
 </head>
 <body>
  <div id="header"></div>
  <div id="content"></div>
  <div id="navigation"></div>
  <div id="footer"></div>
 </body>
</html>

Gorgeous! By setting the clear property to both, we're telling the footer that it needs to sit below any floated element.

Relative positions

In order to make complex layouts, we need to talk about the position property. By default, an element doesn't have a specific position.

If we set the position to relative, we position the element relative to its normal position.

//style.css

.box {
 background: #44accf;
 width: 200px;
 height: 200px;
 position: relative;
 left: 20px;
}

//webpage.html

<!doctype html>
<html>
 <head>
  <link rel="stylesheet" type="text/css" href="style.css">
 </head>
 <body>
  <div class="box"></div>
 </body>
</html>

Great! We can adjust relatively-positioned elements with top, right, bottom and left, which are called offset properties.

Absolute positions

In contrast, absolutely-positioned elements are removed from the normal flow, which means they don’t really care about others elements.

//style.css

.box {
 background: #44accf;
 position: absolute;
 top: 20px;
 right: 20px;
 left: 20px;
 bottom: 20px;
}

//webpage.html

<!doctype html>
<html>
 <head>
  <link rel="stylesheet" type="text/css" href="style.css">
 </head>
 <body>
  <div class="box"></div>
 </body>
</html>

Fantastic! We can use the four offset properties to stretch an element without defining any widths or heights.

Fixed positions

Elements with a fixed position are also removed from the normal flow but positioned relative to the browser window.

//style.css

#footer {
 background: #44accf;
 height: 20px;
 position: fixed;  
 right: 0px;
 bottom: 0px;
 left: 0px;
}

//webpage.html

<!doctype html>
<html>
 <head>
  <link rel="stylesheet" type="text/css" href="style.css">
 </head>
 <body>
  <div id="footer"></div>
 </body>
</html>

Sweet! Because they're positioned relative to the browser window, they stay where they are when we scroll.

Horizontal centering

Guess what: we can also use margins to position elements.

If we set an element's margins to auto, it uses 0px on the top and the bottom and the whole available space on the right and left side.

//style.css

p {
 background: #44b3c2;
 width: 150px;
 margin: auto;
}

//style.css

<!doctype html>
<html>
 <head>
  <link rel="stylesheet" type="text/css" href="style.css">
 </head>
 <body>
  <p>Put me in the center of attention.</p>
 </body>
</html>

Isn't that great? By setting the right and left margins to auto, we can place an element in the horizontal center of its parent.

Negative margins

Guess what: we can also use negative margins to position elements.

//style.css

#header {
 background: #44b3c2;
 width: 100%;
 height: 50px;
}
p {
 background: white;
 border: 2px solid #b7d84b;
 width: 50%;
 height: 200px;
 padding: 20px;
 margin: -25px auto 0px auto;
}

//webpage.html

<!doctype html>
<html>
 <head>
  <link rel="stylesheet" type="text/css" href="style.css">
 </head>
 <body>
  <div id="header"></div>
  <p>Fly me to the moon .. or at least lift me up a bit.</p>
 </body>
</html>

Nice! Negative margins can be very powerful when we use them correctly, for example to create overlays.

The universal selector

The universal selector matches any type of element and, therefore, selects every single element on a web page.

//style.css

* {
 border: 1px solid black;
 box-sizing: border-box;
}
*.box { background: #44b3c2; }

//webpage.html

<!doctype html>
<html>
 <head>
  <link rel="stylesheet" type="text/css" href="style.css">
 </head>
 <body>
  <div class="box"></div>
  <p><span></span></p>
  <ul>
   <li><span></span></li>
   <li><span></span></li>
  </ul>
 </body>
</html>

The universal selector, which uses the * symbol, is a great way to change the box-sizing property of every individual element on a web page.

Psst: whenever we've selected elements with simple selectors, we've implied the * symbol.

Descendants

By separating multiple selectors with a space, we can select descendant elements of an element, making the selectors more specific.

//style.css

p span {
 font-weight: bold;
}

//webpage.html

<!doctype html>
<html>
 <head>
  <link rel="stylesheet" type="text/css" href="style.css">
 </head>
 <body>
  <div class="box"></div>
  <p><span>I'm in</span></p>
  <ul>
   <li><span>I'm not</span></li>
   <li><span>I'm not</span></li>
  </ul>
 </body>
</html>

Fantastic! That way, we're selecting and styling every <span> element that's inside a <p> element.

Immediate children

The child selector selects every element that's an immediate child of the first-mentioned element.

//style.css

div > p {
 font-weight: bold;
}

//webpage.html

<!doctype html>
<html>
 <head>
  <link rel="stylesheet" type="text/css" href="style.css">
 </head>
 <body>
  <div>
   <p>I'm in</p>
  </div>
  <div>
   <ul>
    <li><p>I'm not</p></li>
   </ul>
  </div>
 </body>
</html>

Sweet! Using the > symbol, we're selecting every <p> element that's not just a descendant but an immediate child of a <div> element.

Pseudo-classes

Pseudo-classes are keywords that we add to selectors in order to style a special state of an element.

//style.css

a {
 background: black;
 color: white;
}
a:active {
 background: white;
 color: black;
}

//webpage.html

<!doctype html>
<html>
 <head>
  <link rel="stylesheet" type="text/css" href="style.css">
 </head>
 <body>
  <a href="https://pywe.org">Follow the white ... link!</a>
 </body>
</html>

Great! With the :active pseudo-class, we can style elements that are being clicked or, well, tapped. A somewhat similar pseudo-class is :hover.

First children

Another pseudo-class selector is first-child, which allows us to select elements that are the first children of their surrounding element.

//style.css

p:first-child {
 font-weight: bold;
}

//webpage.html

<!doctype html>
<html>
 <head>
  <link rel="stylesheet" type="text/css" href="style.css">
 </head>
 <body>
  <div>
   <p>I'm in</p>
   <p>I'm not</p>
  </div>
  <div>
   <div>I'm not even a paragraph</div>
   <p>I'm not</p>
  </div>
 </body>
</html>

Great! In this case, we're selecting all paragraphs that are, well, the first children of their parents.

Pseudo-elements

Like pseudo-classes, pseudo-elements are added to selectors but, instead of describing a state, they allow us to style parts of an element.

//style.css

p::first-letter {
 font-size: 2em;
}

//webpage.html

<!doctype html>
<html>
 <head>
  <link rel="stylesheet" type="text/css" href="style.css">
 </head>
 <body>
  <p>It is a truth universally acknowledged, that a single man in possession of a good fortune must be in want of a wife.</p>
 </body>
</html>

Great! Using ::first-letter, we can style the first letter of a text. A similar and pretty self-explanatory pseudo-element is ::first-line.

Attributes

Guess what: we can use any of an element's attributes and attribute values as selectors.

//style.css

a[href="https://pywe.org"] {
 font-weight: bold;
}

//webpage.html

<!doctype html>
<html>
 <head>
  <link rel="stylesheet" type="text/css" href="style.css">
 </head>
 <body>
  <a href="https://pywe.org">PyWE</a>
  <a href="https://appsto.re/us/HPb10.i" target="_blank">App Store</a>
 </body>
</html>

Perfect! We've created a selector for <a> elements with a href attribute value of "https://getmimo.com".

Psst: if we don't provide an attribute value, we select <a> elements that have an href attribute.

Grouping selectors

We can select groups of elements by separating their selectors with commas.

//style.css

div, .trailer, #listItem1 {
 border: 2px solid #44accf;
}

//webpage.html

<!doctype html>
<html>
 <head>
  <link rel="stylesheet" type="text/css" href="style.css">
 </head>
 <body>
  <div>I'm in</div>
  <p class="trailer">Me too</p>
  <ul>
   <li id="listItem1">Same here</li>
   <li>I'm not</li>
  </ul>
 </body>
</html>

Nice! This way, the same declaration block applies to all three selectors.

Combining selectors

In order to create very specific rules, we can create combinations of selectors without putting a space in between.

//style.css

.box {
 width: 200px;
 height: 200px;
}
.blue.bordered {
 border: 2px solid #7cc4dd;
}
.pink.bordered {
 border: 2px solid #f37792;
}
.blue { background: #44accf; }
.pink { background: #ee3e64; }

//webpage.html

<!doctype html>
<html>
 <head>
  <link rel="stylesheet" type="text/css" href="style.css">
 </head>
 <body>
  <div class="blue bordered box"></div>
  <div class="green bordered box"></div>
  <div class="blue box"></div>
  <div class="green box"></div>
 </body>
</html>

Spot on! By combining selectors, we're targeting those elements that have all of the specified selectors.

Specificity

Before we go out and play, let's talk about specificity, an advanced but important topic.

By deciding which styles to apply, specificity helps us resolve conflicts when multiple declarations try to set the same property.

//style.css

#box1 {
 background: green;
}
.box {
 background: red;
 width: 200px;
 height: 200px;
}
div {
 background: firebrick;
 border: 2px solid black;
}

//webpage.html

<!doctype html>
<html>
 <head>
  <link rel="stylesheet" type="text/css" href="style.css">
 </head>
 <body>
  <div class="box" id="box1"></div>
 </body>
</html>