CSS (Cascading Style Sheets) controls how HTML actually looks — colors, spacing, fonts, layout, and more. HTML describes what content is; CSS describes how it should appear. Keeping those two concerns separate is why you can completely redesign a site's look without touching a single line of its markup.
Linking a Stylesheet
The most common approach is an external stylesheet, linked from the HTML <head>:
<head>
<link rel="stylesheet" href="/styles/main.css" />
</head>
This keeps styling in its own file, cacheable by the browser and shareable across multiple pages — the standard approach for anything beyond a one-off demo.
The Rule Syntax
A CSS rule pairs a selector (what to style) with a block of declarations (how to style it):
p {
color: #333;
font-size: 16px;
line-height: 1.5;
}
This makes every <p> element on the page render in dark gray text at 16px, with comfortable line spacing. Each declaration is a property: value; pair — color, font-size, and line-height are properties here, each set to a specific value.
The Core Selector Types
/* Element selector — targets every <h1> */
h1 { color: navy; }
/* Class selector — targets anything with class="highlight" */
.highlight { background: yellow; }
/* ID selector — targets the single element with id="logo" */
#logo { width: 120px; }
/* Universal selector — targets everything */
* { box-sizing: border-box; }
Element selectors (like p or h1) target every instance of that tag — broad and useful for setting sensible defaults. Class selectors, prefixed with a dot, are the workhorse of everyday CSS: reusable across as many elements as you like. ID selectors, prefixed with #, target exactly one element, since an id is supposed to be unique on a page. The universal selector * targets literally every element, most commonly used for small resets like the box-sizing rule above.
Combining Selectors
/* Both a <button> AND has class="primary" */
button.primary { background: blue; }
/* Multiple selectors sharing one rule */
h1, h2, h3 { font-family: sans-serif; }
Chaining a tag and a class with no space between them (button.primary) narrows the match to elements satisfying both conditions. A comma, on the other hand, applies the same declarations to several unrelated selectors at once — useful for keeping shared styling in one place instead of repeating a rule three times.
Once more than one rule can match the same element, you need to know which one actually wins — that's exactly what CSS specificity and the cascade determine.
