CSS Get Started

CSS, short for Cascading Style Sheets, is the language that controls how HTML elements look and where they sit on the page. HTML alone only describes structure and meaning — headings, paragraphs, links, images — with no visual styling of its own. CSS lets you separate that structure from its presentation, so you can change colors, spacing, fonts, and entire layouts without touching a single HTML tag. This lesson takes you from zero to writing your first real stylesheet, and explains exactly how the browser decides which styles actually apply when several rules compete.

Overview: How CSS Works

A CSS rule, also called a ruleset, has two parts: a selector that says which element(s) to target, and a declaration block wrapped in curly braces that lists the properties to change and the values to change them to. When a browser loads a page, it first parses the HTML into a tree of elements called the DOM (Document Object Model). Then it reads every stylesheet available to the page and matches each selector against that tree, attaching the matching declarations to the elements they target.

Styles can come from three origins: the browser’s own built-in defaults (the user agent stylesheet — this is why an unstyled <h1> is already bold and large, and an unstyled <a> is already blue and underlined), styles the user has configured in their own browser, and the author styles you write. The browser merges all of these into one final value per property per element. This merging process is the "cascade" in Cascading Style Sheets: whenever more than one rule tries to set the same property on the same element, the cascade picks a winner using origin, specificity, and source order. We walk through that algorithm step by step later in this lesson.

Once the browser knows the final, "computed" value of every property on every element, it moves into layout: it works out the box model (content, padding, border, and margin) for each box, figures out how boxes are positioned and flow relative to each other based on properties like display, and finally paints pixels to the screen. Every CSS property you will learn in this course ultimately feeds one of these stages — cascade resolution, layout, or paint — so understanding this pipeline now will make specificity, the box model, flexbox, and grid all click into place faster later.

Three Ways to Add CSS to a Page

There are three ways to attach CSS to an HTML document. You will see all three used in real projects, even though external stylesheets are the recommended default for anything beyond a quick test.

Method How it’s written When to use it
Inline A style attribute directly on one element, e.g. <p style="color: red;"> Highest specificity of the three, but it mixes styling into markup and doesn’t scale. Reserve it for one-off overrides or styles generated dynamically by a script.
Internal A <style> block placed inside <head> Convenient for a single-page demo or quick prototype, but the rules only apply to that one HTML document.
External A separate .css file linked with <link rel="stylesheet" href="styles.css"> inside <head> The standard approach for real sites: one file can style every page, the browser caches it between page loads, and your HTML stays free of styling clutter.

Syntax

Every CSS ruleset follows the same shape:

selector {
  property: value;
  property: value;
}
  • Selector — picks which element(s) the rule applies to. It can be a tag name (p), a class (.card), an id (#main), or a more complex combination.
  • Declaration block — everything between the opening { and closing }.
  • Property — the aspect you want to change, such as color or margin.
  • Value — what to set that property to, such as red or 16px.
  • Declaration — one property: value pair. It must end with a semicolon, since the semicolon is what separates one declaration from the next inside the block.

Comments are written as /* like this */ and can span multiple lines. The browser ignores them entirely; they exist purely for the humans reading the file.

Examples

Example 1: A basic stylesheet for a whole page

Imagine a page whose <body> contains an <h1> heading followed by a couple of <p> paragraphs. This CSS, placed in a <style> block or an external file, styles the whole page at once:

body {
  background-color: #f5f5f5;
  font-family: Arial, Helvetica, sans-serif;
  color: #222;
}

h1 {
  color: navy;
  text-align: center;
}

p {
  font-size: 16px;
  line-height: 1.5;
}

Result: The whole page gets a light gray background and switches to the Arial font family with dark gray body text. The heading becomes navy blue and is centered horizontally above the paragraphs, and every paragraph renders at 16px with generous 1.5x line spacing, making the text easier to read.

This example shows the most common pattern for a starter stylesheet: target broad, generic tag selectors (body, h1, p) first to set sensible defaults across the whole document, before you reach for anything more specific.

Example 2: Styling a reusable component with classes

Now imagine a <div class="card"> that contains an <h2 class="card-title"> and an <a class="btn-primary"> acting as a button:

/* Style every element with class="card" */
.card {
  max-width: 320px;
  padding: 16px;
  border: 1px solid #ddd;
  border-radius: 8px;
  box-shadow: 0 2px 6px rgba(0, 0, 0, 0.15);
}

.card-title {
  margin: 0 0 8px 0;
  font-size: 1.25rem;
  color: #1a1a1a;
}

.btn-primary {
  display: inline-block;
  padding: 8px 16px;
  background-color: #2563eb;
  color: #ffffff;
  border: none;
  border-radius: 4px;
  text-decoration: none;
}

Result: The card renders as a rounded, lightly shadowed box no wider than 320px, with 16px of breathing room inside it and a thin gray border. Its title sits near the top in a slightly larger, near-black font. The link is transformed from default blue underlined text into a solid blue rectangular button with white, non-underlined text and rounded corners.

This is the pattern you’ll use constantly: name a CSS class after the role it plays (card, card-title, btn-primary), then reuse that same class on any element that should look the same way, anywhere in the site.

Example 3: When two rules target the same element

Suppose the page has one paragraph: <p id="lead-paragraph" class="intro">Welcome!</p>, and the stylesheet contains:

p {
  color: green;
}

.intro {
  color: purple;
}

#lead-paragraph {
  color: crimson;
}

Result: The text renders crimson, not green and not purple, even though all three rules match the same paragraph and are perfectly valid on their own.

This is the cascade in action: when multiple rules set the same property on the same element, the browser doesn’t just apply whichever one appears last — it calculates which selector is the most specific. The next section breaks down exactly how that calculation works.

How It Works Step by Step (Under the Hood)

For Example 3, the browser calculates a specificity score for each matching selector as a tuple of (inline, id, class, type) counts:

  • p is a type selector: specificity (0, 0, 0, 1).
  • .intro is a class selector: specificity (0, 0, 1, 0).
  • #lead-paragraph is an id selector: specificity (0, 1, 0, 0).

The browser compares these tuples left to right, like comparing version numbers: any id selector beats any number of class selectors, and any class selector beats any number of type selectors. Since (0,1,0,0) is higher than (0,0,1,0) and (0,0,0,1), the id rule wins and the text is crimson. Had two rules tied on specificity exactly, the cascade would fall back to source order, and whichever rule was declared last in the stylesheet (or appeared in a stylesheet linked later in the HTML) would win. An inline style attribute, if present, would beat all three of these author-stylesheet rules outright, since its specificity is effectively (1, 0, 0, 0).

For Example 2’s .card rule, the browser also has to compute the box model. With the default box-sizing: content-box, the max-width: 320px applies only to the content area; the browser then adds the padding and border outside that content box. So the card’s total rendered width tops out at 320px (content) + 16px + 16px (left/right padding) + 1px + 1px (left/right border) = 354px, and the same math applies vertically once the content’s natural height is known. This is why unexpected extra width is one of the most common CSS surprises for beginners — the box model, and the box-sizing property that controls it, is a topic covered in depth in a later lesson.

Common Mistakes

Mistake 1: Forgetting the semicolon between declarations

Because a semicolon is what separates one declaration from the next, leaving it out corrupts everything after it:

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

Without the semicolon after red, the parser cannot tell where the color value ends and the next property begins, so the whole declaration becomes invalid and both properties may be dropped. The fix is simply to terminate every declaration, including the last one in the block (trailing semicolons are optional on the last declaration, but including them anyway prevents exactly this mistake when you add a new line below it later):

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

Mistake 2: Using = instead of :

Beginners coming from HTML attributes (attribute="value") sometimes carry that syntax into CSS by mistake:

p {
  color = blue;
}

CSS declarations always separate the property from its value with a colon, never an equals sign; the line above is simply invalid and the browser ignores it entirely. The corrected version:

p {
  color: blue;
}

Best Practices

  • Use an external stylesheet linked with <link> for anything beyond a single-page throwaway demo, so styles are cached and reused across pages.
  • Prefer classes as your primary styling hook. Reserve id selectors for the rare case where an element is truly unique on the page, since their high specificity makes later overrides harder.
  • Avoid inline style attributes except for values computed at runtime by a script; they’re the hardest layer to override later.
  • Keep selectors as simple and low-specificity as they can be while still being correct — it keeps future overrides easy instead of turning into a specificity arms race.
  • Comment sections of a large stylesheet so the next person (often you, in six months) can navigate it quickly.
  • Group related rules together and keep a consistent formatting style (indentation, one declaration per line) so diffs stay readable.

Practice Exercises

  • Create an external stylesheet named styles.css, link it into an HTML page with <link>, and use it to give the <body> a background color and every <h1> a different text color than the default black.
  • Given a <button class="submit" id="main-submit"> and the rules button { color: black; }, .submit { color: white; }, and #main-submit { color: gold; }, work out by hand which color actually renders, and explain why using specificity tuples.
  • The following stylesheet fails to apply at all — find and fix the two syntax mistakes: a paragraph rule with a missing semicolon after its first declaration, and a heading rule that accidentally uses = instead of :.

Summary

  • CSS pairs selectors with declarations to control how HTML renders; declarations live inside a { } block as property: value; pairs.
  • CSS can be added inline (on one element), internally (a <style> block), or externally (a linked .css file) — external is the standard for real projects.
  • When multiple rules target the same element and property, the cascade resolves the conflict using origin, then specificity (id beats class beats type), then source order as the final tiebreaker.
  • After the cascade resolves final values, the browser still has to compute the box model and layout before anything is painted to the screen.
  • Missing semicolons and using = instead of : are two of the most common beginner syntax errors, and both silently break the surrounding declaration.