CSS fundamentals · 1 / 8
lesson 1

What CSS actually is

A rule is a selector plus a block of property-value pairs — and that's the whole language.

~ 12 min read·lesson 1 of 8
0 / 8

You wrote some HTML. The page works — links go places, the form submits — but the headings are giant, every paragraph is squashed against the left edge, and the whole thing looks like a 1996 Geocities page. Nothing is broken. The browser is just showing you exactly what HTML alone looks like, and HTML alone never had opinions about colour, size, or spacing. That job belongs to CSS, and the goal of this lesson is to build a clear picture of what a CSS rule actually is before you write a single line of one.

CSS stands for Cascading Style Sheets. The "cascading" part is the interesting word — we will come back to it in lesson 3. For now, treat it as: a CSS file is a long list of small instructions, and each instruction says "for elements that match this description, set these visual properties to these values."

The shape of a rule

A CSS rule has two parts, and only two parts. The first part is a selector — a short pattern that picks out which elements on the page the rule applies to. The second part is a declaration block — the curly braces and everything inside them. Each line inside the braces is a declaration, which is a property name, a colon, a value, and a semicolon.

styles.css
p {
color: #2d2418;
line-height: 1.6;
margin-bottom: 16px;
}

Read that out loud as English: "for every <p> element on the page, set the text colour to a dark brown, set the line height to 1.6, and put 16 pixels of space below it." The selector is p. The declaration block is the part between { and }. There are three declarations in this block, and each declaration is a property (color, line-height, margin-bottom) paired with a value (#2d2418, 1.6, 16px).

That is the whole shape. Every CSS rule you ever write — the simple ones and the gnarly ones — fits this template:

p{color: #2d2418; line-height: 1.6; margin-bottom: 16px;}selectordeclaration block
A CSS rule splits into a selector and a declaration block. Each declaration inside the block is property: value;.

The semicolons matter more than they look. They separate declarations. If you forget the semicolon at the end of a line, the browser will read the next line as a continuation of the current declaration, which means both declarations get thrown out. Most editors add semicolons for you — but the rule lives in the file, not in the editor.

broken.css
p {
color: red
line-height: 1.6;
}

That snippet has no semicolon after red. The browser reads the value as red line-height: 1.6 — which is not a valid colour, and which also no longer contains a line-height declaration anywhere. Both lines silently fail. The page still renders, just without the styling you thought you wrote. This is the first thing to check when "my CSS isn't doing anything."

check your understanding
You write h2 { font-size: 24px color: navy; } and the heading colour stays the browser default. What is most likely wrong?

How the browser matches rules to elements

Once the file is parsed, the browser walks the page and asks, for every element, "which of these selectors describe me?" If a selector matches, every declaration inside that rule applies to that element.

Think of it like a guest list. Each rule is one row on the list, with a description ("anyone wearing a red hat") and a set of perks ("free drink, table near the window"). When a guest walks in, the door staff check every row top to bottom and apply every perk whose description fits. One guest can match many rows; one row can match many guests.

styles.css
a {
color: #c96442;
}

.warning {
background: #fff3e0;
padding: 8px;
}

The first rule selects every <a> element on the page. The second rule selects every element with class="warning", regardless of whether it is a <div>, <p>, or anything else. A <a class="warning"> would match both rules and end up with the colour, the background, and the padding. The browser does not pick one rule and discard the other — it applies whatever each matching rule asks for.

What happens when two rules disagree about the same property — say one says color: red and another says color: blue? That is the cascading part of "cascading style sheets," and it has its own lesson (lesson 3). For now, just know it is a real situation with real rules behind it, not a coin flip.

check your understanding
An <a class="warning">Click</a> sits in a page that has a rule selecting a and another selecting .warning. Which is closest to what the browser does?

Where the CSS lives

You can drop CSS into a page in three places. Most projects use one of them and only one — but it helps to recognize the others when you see them.

The clean way is a separate file linked from the HTML's <head>:

index.html
<head>
<link rel="stylesheet" href="/styles.css" />
</head>

This is what almost every real site does. The stylesheet is cached by the browser, shared across pages, and lives in version control like any other file. Any HTML page that links it gets the same look.

The second way is a <style> block right inside the HTML:

index.html
<head>
<style>
  body { font-family: system-ui; }
</style>
</head>

This works fine — useful for one-off pages or tiny demos — but the styles are stuck inside that one file and cannot be reused.

The third way is an inline style attribute on a single element:

index.html
<p style="color: red;">This paragraph is red.</p>

Inline styles only affect the one element they sit on, and they are awkward to override (more on that in lesson 3). They are not banned — sometimes a one-off element really does need a one-off colour — but reaching for them as your default is how stylesheets become impossible to reason about.

Tip

Pick one home for your styles per project and stick with it. A separate stylesheet is the default; the other two are for narrow, deliberate cases.

The browser already has opinions

Open any HTML page with no CSS at all and headings still come out big and bold, links still come out blue and underlined, lists still have bullets. None of that is in your file. Every browser ships with its own built-in stylesheet — called the user-agent stylesheet — that gives every HTML element a sensible default look. Your CSS layers on top of those defaults, overriding the parts you want to change and inheriting the rest.

This is why a fresh page with no styles still looks like something, and why removing one of your own rules sometimes reveals a default you forgot was there. A margin you never wrote? That is the user-agent stylesheet's default for <h1>. A bullet on your nav list? Same thing — the default for <ul>. Knowing the defaults exist saves a lot of "where is this coming from?" debugging later.

check your understanding
You delete every CSS rule from your project and reload the page. What do you see?
check your understanding
Two CSS rules apply to the same paragraph: one sets color: red, the other sets font-size: 18px. What ends up on the paragraph?
next lesson →
KeepLearningcertificate
for completing
CSS fundamentals
0 of 8 read