What CSS is and how to add it to a page
HTML says what things are. CSS says what they look like. Every colour, every size, every bit of spacing on every page you have ever seen was a CSS decision — including the ones nobody made deliberately.
An unstyled page is not unstyled
Open an HTML file with no CSS at all:
<h1>Karachi Canteen</h1>
<p>Open from eight until six.</p>
The heading comes out large and bold. The paragraph is smaller. There is space between them, a margin around the edge, black text on white.
None of that was your decision, and it is easy to conclude that headings are simply born big. They are not. Every browser ships with a stylesheet of its own — the user-agent stylesheet — and it is styling your page before you write a single line.
This matters more than it sounds, because it explains a whole category of confusion. When your list has bullets you did not ask for, or your button has a grey border you never wrote, you are not looking at a bug. You are looking at the browser's defaults, and your job is to override them rather than hunt for where they came from.
You can see them yourself: right-click any element, choose Inspect, and look at the Styles panel. Declarations marked user agent stylesheet are the browser's, not yours.
Three ways to attach CSS
There are three, and they are not equally good.
An external stylesheet — use this one
Put the CSS in its own file and link it from the head:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8">
<title>Karachi Canteen</title>
<link rel="stylesheet" href="style.css">
</head>
<body>
<h1>Karachi Canteen</h1>
</body>
</html>
And in style.css:
h1 {
color: darkgreen;
}
Note what <link> is not: there is no closing tag, and no content. rel
declares the relationship — this is a stylesheet — and href is where to find
it. Get rel wrong and the browser fetches the file and ignores it.
This is the right default for essentially everything, for three reasons. One stylesheet can serve every page, so a colour change happens once instead of forty times. The browser caches it, so the second page a visitor opens does not re-download it. And your content stays readable, uncluttered by styling.
A style block — fine for experiments
<head>
<style>
h1 {
color: darkgreen;
}
</style>
</head>
The CSS lives in the page. Useful when you are testing an idea and cannot be bothered making a file, and genuinely useful for a tiny single-page thing. But it applies only to this page, and nothing can cache it separately.
Inline styles — avoid
<h1 style="color: darkgreen;">Karachi Canteen</h1>
This works and you should almost never write it. It styles exactly one element, so styling ten headings means editing ten tags. It cannot express hover or responsive behaviour. And it is very hard to override later, for reasons the specificity lesson will make concrete.
You will still meet it, because JavaScript sets styles this way, and email clients force it. Recognise it; do not reach for it.
What a rule looks like
h1 {
color: darkgreen;
font-size: 32px;
}
Reading it aloud: find every h1, and set its colour and font size.
h1is the selector — which elements this applies to- Everything in
{ }is the declaration block color: darkgreen;is one declarationcoloris the property,darkgreenthe value- The semicolon ends the declaration
The next lesson takes this apart properly. For now, notice the shape: colon between property and value, semicolon at the end of each line.
Where the file goes
If style.css sits beside index.html, this is enough:
<link rel="stylesheet" href="style.css">
Most projects put stylesheets in a folder:
index.html
css/
style.css
Then the path has to say so:
<link rel="stylesheet" href="css/style.css">
When your CSS appears to do nothing at all, this is the first thing to check — far more often than not, the file is not being found. Open the Network tab in devtools and reload: a stylesheet that 404s is listed in red, and that is your answer in two seconds.
Order matters, and later wins
When two rules set the same property on the same element, the one further down the file wins:
h1 {
color: darkgreen;
}
h1 {
color: crimson;
}
The heading is crimson. The first rule is not an error, it is simply overridden — which is exactly how you override the browser's defaults. Your stylesheet comes after the user-agent stylesheet, so your rules beat it.
The same applies across sources. A <style> block after your <link> beats the
linked file, because it comes later.
A first real page
index.html:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8">
<title>Lahore Canteen</title>
<link rel="stylesheet" href="style.css">
</head>
<body>
<h1>Lahore Canteen</h1>
<p>Biryani, 350 rupees. Open until six.</p>
</body>
</html>
style.css, in the same folder:
body {
font-family: system-ui, sans-serif;
margin: 40px;
}
h1 {
color: darkgreen;
}
p {
font-size: 18px;
}
Open the HTML file. Green heading, larger paragraph, space around everything.
Now delete the <link> line and reload. Everything reverts — not to nothing,
but to the browser's defaults. That is the whole lesson in one experiment: the
page was always styled, and CSS is you taking over.
Next, CSS syntax — including the thing that catches everyone, which is that a mistake in CSS produces no error message at all. The browser throws the broken line away and says nothing.
Prefer learning with a teacher?
WasiLearn Academy runs small-group classes covering this material, online and in Karachi.
See the classes