Command Palette

Search for a command to run...

Hectal
PHASE 0Beginner ~26 min· topic 3 of 4

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."

style.csswhole filecss
.card {
  padding: 16px;
  border: 1px solid lightgray;
}
Read a rule piece by piecediagram
Rendering diagram…

02Group selectors and add comments

A comma-separated selector list shares one block. A comment explains why, not what: the code already says what.

style.csswhole filecss
/* 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.

style.csswhole filecss
.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.

style.csswhole filecss
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.

style.csswhole filecss
.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. 1

    Fix the broken rules one by one

    In the second example, fix .a by adding the missing semicolon. Predict the new console line for a before you run it (a rgb(255, 0, 0) 30px). Then fix .b, .d and .f and check that each line changes.

  2. 2

    Turn the fallback around

    In the third example, replace imaginary-gradient(red, blue) with a real gradient: linear-gradient(navy, teal). Predict whether backgroundColor still prints navy. (It prints rgba(0, 0, 0, 0): a gradient is an image, and the background shorthand resets the colour to transparent.)

  3. 3

    Comment out a line

    In the first example, wrap the border-radius line in /* */. The corners become square. Commenting out is how you temporarily switch a declaration off without deleting it.

Code & diagrams

A well-formed stylesheet New tab

The `border` shorthand set width, style and colour on all four sides; JavaScript reads them back as separate longhand properties.

Preview

Press Run to see the page.

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)
The browser skips what it doesn't understand New tab

`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

Press Run to see the page.

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) 16px
Fallbacks and feature checks New tab

The made-up value is dropped, so the earlier `navy` stays. `@supports` applied its block because this browser understands Grid.

Preview

Press Run to see the page.

Console

Nothing logged yet.

Expected console output

background: rgb(0, 0, 128)
radius: 12px
true
false

Break 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; }.

terminal
$ the page shows
── what you'll see ──
The h1 keeps its default black colour. Rules after it still work.

Break #2

Forget a closing brace

In the first example, delete the } that closes the h1, h2 { ... } rule.

terminal
$ the page shows
── what you'll see ──
The headings are still blue, but the card loses its padding, border and rounded corners.

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-thing above). The newer :is() and :where() take a forgiving selector list, so :is(.d, .d:not-a-real-thing) keeps .d working. 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 @container and @layer could 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. 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. 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. 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 or border: 2px solid red (a shorthand property that sets width, style and colour at once).

  4. 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. 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 as color: 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. 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. 7

    Case rules: property names and keywords are case-insensitive (COLOR: RED works, though everyone writes lowercase), but class names and ids are case-sensitive and must match the HTML exactly: .Card does not match class="card".

Explain it without notes

01

Explain the parts of a CSS rule and the purpose of the colon and the semicolon.

02

What does the browser do when it finds an unknown property or an invalid value?

03

Why does a missing semicolon often break two declarations, not one?

04

How can you write CSS that uses a new feature but still works in older browsers?

Practice

01

Fix this CSS so both declarations work: h2 { color: teal font-weight: normal }.

02

Write one rule that gives h1, h2 and .title the colour darkslateblue, with a comment above it explaining that titles share a colour.

03

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 @supports block.