Topic 0.3
CSS Syntax
In one line
A CSS rule is a selector followed by a block of property: value; declarations in curly braces; comments use /* */, and anything the browser can't understand is skipped silently instead of stopping the stylesheet.
Think of it like this
A shopping list for a helper who only knows certain words. You write "apples: 6; bananaz: 3; milk: 2 litres;". The helper buys the apples and the milk and quietly skips "bananaz", a word they don't know. They don't throw away the whole list, and they don't tell you. That's exactly how a browser reads CSS.
Words you'll meet
New words in this topic, in plain English. Come back here whenever one feels fuzzy.
- Ruleset
- Another name for a rule: a selector plus a declaration block.
- Declaration block
- The part of a rule inside curly braces
{ }, holding the declarations. - Colon and semicolon
- The colon
:separates a property from its value. The semicolon;ends a declaration. - Selector list
- Several selectors joined by commas, sharing one block:
h1, h2 { ... }. - Shorthand property
- A property that sets several others at once, like
border: 2px solid red. - Comment
- A note for humans, written between
/*and*/. The browser ignores it. - Invalid declaration
- A declaration the browser can't understand. It is skipped; the rest of the rule still works.
- Fallback
- A safer value written first, so older browsers still get something if they don't understand the newer value after it.
- `@supports`
- A CSS block that only applies if the browser understands a given property and value.
Step by step
01Read a rule piece by piece
Selector .card, then an opening brace, then declarations, each ending in a semicolon, then a closing brace. Read it aloud: "elements with class card: padding 16 pixels; border 1 pixel solid light grey."
.card {
padding: 16px;
border: 1px solid lightgray;
}02Group selectors and add comments
A comma-separated selector list shares one block. A comment explains why, not what: the code already says what.
/* Headings share one font so the page feels consistent. */
h1,
h2,
h3 {
font-family: Georgia, serif;
}03Make a typo and watch it be skipped
colour isn't a CSS property (CSS uses American spelling). The browser drops that declaration and still applies padding. Nothing breaks loudly, which is why CSS typos are easy to miss.
.card {
colour: red; /* unknown property: skipped */
padding: 16px; /* still applied */
}04Forget a semicolon
Without the semicolon after red, the browser reads color as having the value red font-size: 20px, which is invalid, so it drops it. The font-size text was swallowed into that value, so it's lost as well. One missing character, two lost declarations.
p {
color: red /* missing ; */
font-size: 20px;
}05Use the forgiveness on purpose: fallbacks
Put the safe value first and the newer one second. A browser that understands both uses the later one; an older browser drops the line it doesn't understand and keeps the first. You can also wrap a whole block in @supports.
.panel {
background: rgb(240, 240, 255); /* every browser */
background: color-mix(in srgb, blue 8%, white); /* newer browsers */
}
@supports (display: grid) {
.gallery { display: grid; }
}Try it yourself
- 1
Fix the broken rules one by one
In the second example, fix
.aby adding the missing semicolon. Predict the new console line forabefore you run it (a rgb(255, 0, 0) 30px). Then fix.b,.dand.fand check that each line changes. - 2
Turn the fallback around
In the third example, replace
imaginary-gradient(red, blue)with a real gradient:linear-gradient(navy, teal). Predict whetherbackgroundColorstill prints navy. (It printsrgba(0, 0, 0, 0): a gradient is an image, and thebackgroundshorthand resets the colour to transparent.) - 3
Comment out a line
In the first example, wrap the
border-radiusline in/* */. The corners become square. Commenting out is how you temporarily switch a declaration off without deleting it.
Code & diagrams
The `border` shorthand set width, style and colour on all four sides; JavaScript reads them back as separate longhand properties.
Preview
Console
Nothing logged yet.Expected console output
h2 font: Georgia, serif
border-top-width: 2px
border-top-style: solid
border-top-color: rgb(43, 76, 126)`rgb(0, 0, 0)` and `16px` are the defaults, meaning the rule did nothing. Only `.c` (the earlier valid value survived) and `.e` (case doesn't matter) worked.
Preview
Console
Nothing logged yet.Expected console output
a rgb(0, 0, 0) 16px
b rgb(0, 0, 0) 16px
c rgb(0, 0, 255) 16px
d rgb(0, 0, 0) 16px
e rgb(0, 128, 0) 16px
f rgb(0, 0, 0) 16pxThe made-up value is dropped, so the earlier `navy` stays. `@supports` applied its block because this browser understands Grid.
Preview
Console
Nothing logged yet.Expected console output
background: rgb(0, 0, 128)
radius: 12px
true
falseBreak it on purpose
Errors are the best teachers. Make each change, read the error, guess what went wrong, then reveal the answer.
Break #1
Use a // comment
Write // main title on the line above h1 { color: red; }.
Break #2
Forget a closing brace
In the first example, delete the } that closes the h1, h2 { ... } rule.
Myth vs fact
Myth
If my CSS has an error, the browser will show an error message.
Fact
CSS fails silently. The page shows no error and the console usually says nothing. Use DevTools' Styles pane, where invalid declarations are struck through with a warning icon, or a linter like Stylelint.
Myth
One mistake breaks the whole stylesheet.
Fact
An invalid declaration only loses that declaration, and an invalid selector only loses its rule. Only structural mistakes, like a missing }, spread further.
Myth
The last declaration needs no semicolon, so leave it out.
Fact
It's allowed but risky: adding a line later without noticing joins two declarations into one invalid one. Always end every declaration with ;.
Pro corner
Extra depth for experienced readers. New to this? Skip it for now and come back later.
- ▸
The CSS Syntax spec defines error recovery precisely: an invalid declaration is consumed up to the next
;at the same nesting level (or the end of the block), and an invalid rule is consumed up to its matching}. That's why brackets and quotes must balance: an unclosed(or"swallows everything until it closes. - ▸
A selector list is invalid as a whole if any one selector in it is invalid (
.d, .d:not-a-real-thingabove). The newer:is()and:where()take a forgiving selector list, so:is(.d, .d:not-a-real-thing)keeps.dworking. You'll meet them in Phase 1. - ▸
Unknown at-rules (like
@future-thing { ... }) are skipped the same way, which is how new features such as@containerand@layercould ship without breaking older browsers. - ▸
Vendor prefixes (
-webkit-,-moz-) were the old way of shipping experimental properties. They're mostly gone; modern features ship behind flags instead. Tools like Autoprefixer add any still-needed prefixes automatically, so don't hand-write them.
Remember this
- 1
A rule (also called a ruleset) has a selector, then a declaration block in curly braces
{ }. Inside the block, each declaration is a property name, a colon:, a value, and a semicolon;that ends it:h1 { color: navy; margin-bottom: 8px; }. Spaces and line breaks around these pieces don't matter, so put one declaration per line for readability. - 2
The semicolon is a separator. The last declaration in a block doesn't strictly need one, but always write it: the day you add another line below, a missing semicolon makes the browser read both lines as one broken value and drop both.
- 3
You can group selectors with a comma to share one block:
h1, h2, h3 { font-family: Georgia, serif; }is the same as writing three rules. Some values also contain commas or spaces, such as a list of fonts orborder: 2px solid red(a shorthand property that sets width, style and colour at once). - 4
Comments start with
/*and end with*/, and can span many lines. The browser ignores them. There is no//line comment in CSS://is just two characters that get glued onto the next selector and break that rule. Comments can't be nested: the first*/ends the comment. - 5
CSS is forgiving by design. When the browser meets a declaration it can't understand (an unknown property such as
colour, or an invalid value such ascolor: 12px), it drops only that declaration and keeps going. If a selector is invalid, it drops that whole rule, and if one selector in a comma-separated group is invalid, the entire group's rule is dropped. Nothing is reported on the page; DevTools shows the problem with a warning icon. - 6
This forgiveness is a feature: it lets you write fallbacks. Write a widely supported value first and a newer one after it:
background: navy; background: some-new-function(...);. Old browsers drop the line they don't understand and keep the first; new browsers use the later one. You can also ask directly with@supports (display: grid) { ... }or, from JavaScript,CSS.supports("display", "grid"). - 7
Case rules: property names and keywords are case-insensitive (
COLOR: REDworks, though everyone writes lowercase), but class names and ids are case-sensitive and must match the HTML exactly:.Carddoes not matchclass="card".
Explain it without notes
Explain the parts of a CSS rule and the purpose of the colon and the semicolon.
What does the browser do when it finds an unknown property or an invalid value?
Why does a missing semicolon often break two declarations, not one?
How can you write CSS that uses a new feature but still works in older browsers?
Practice
Fix this CSS so both declarations work: h2 { color: teal font-weight: normal }.
Write one rule that gives h1, h2 and .title the colour darkslateblue, with a comment above it explaining that titles share a colour.
Write a .hero rule that uses a solid navy background as a fallback and linear-gradient(navy, teal) for browsers that support gradients.
Trade-offs
- ↔
Silent error recovery keeps pages working when CSS has mistakes or newer features, but it also hides bugs; pair it with a linter (Stylelint) and DevTools checks.
- ↔
Comma-grouping selectors removes repetition, but one invalid selector in the group drops the whole rule; keep risky or very new selectors in their own rule, or use
:is().
Done when you can
I can write a rule with correct braces, colons and semicolons.
I can group selectors with commas and write
/* */comments.I know CSS has no
//comments.I can predict what happens to an invalid declaration, an invalid value and an invalid selector.
I can write a fallback value and an
@supportsblock.