CSS Syntax & Selectors

Every CSS rule has the same two parts: a selector that picks which elements to style, and a declaration block that says what to change. Learn this pattern once and you understand all of CSS.

The Anatomy of a CSS Rule

A CSS rule looks like this:

selector {
  property: value;
  property: value;
}
  • selector — targets which HTML elements this rule applies to.
  • { } — curly braces wrap all the declarations for this rule.
  • property — what you want to change (e.g. color, font-size).
  • value — what you want to set it to (e.g. red, 24px).
  • ; — a semicolon ends every declaration. Don't forget it.
🎯 Analogy: A CSS rule is like an instruction memo

"To: all paragraphs. Subject: appearance update. Details: make text grey, size 16 pixels." The selector is the "To:" field. The declarations are the instructions inside.

A Real Example

p {
  color: #333333;
  font-size: 16px;
  line-height: 1.6;
}

This rule says: find every <p> element, make the text dark grey, 16 pixels tall, with 1.6 line spacing. That's it — you just wrote CSS.

Element Selectors

The simplest selector — just write the tag name. It targets every element of that type on the page.

h1 { color: navy; }
p  { color: #444; }
a  { color: teal; }

Every <h1> turns navy. Every <p> turns dark grey. Every link turns teal.

Class Selectors

A class selector targets elements that have a specific class attribute. Write a dot followed by the class name.

/* CSS */
.highlight {
  background-color: yellow;
  font-weight: bold;
}
<!-- HTML -->
<p class="highlight">This paragraph gets a yellow background.</p>
<p>This one does not.</p>

Classes are reusable — you can apply the same class to any number of elements, and they all get the same style. This is the most common selector you'll use in real projects.

ID Selectors

An ID selector targets one specific element by its unique id attribute. Write a hash symbol followed by the ID name.

/* CSS */
#main-header {
  background-color: #0f1420;
  padding: 20px;
}
<!-- HTML -->
<header id="main-header">My Site</header>
⚠️ Avoid IDs for styling

IDs are very high specificity (we'll cover this later) and make your CSS hard to override. Save id attributes for JavaScript and anchor links. Use classes for all your styling.

Universal Selector

The asterisk * matches every single element on the page. Commonly used for resets.

* {
  box-sizing: border-box;
  margin: 0;
  padding: 0;
}

Grouping Selectors

Apply the same styles to multiple selectors by separating them with commas.

h1, h2, h3 {
  font-family: 'Georgia', serif;
  color: #111;
}

Instead of repeating the same declarations three times, you group them. Clean and efficient.

Descendant Selector

Target elements that are inside another element by putting a space between them.

/* Only <a> tags that are inside a <nav> */
nav a {
  color: white;
  text-decoration: none;
}

/* Only <p> tags inside .card */
.card p {
  font-size: 14px;
}

The space means "any descendant at any depth." So nav a matches a link inside a <ul> inside a <nav>.

Child Selector ( > )

The > combinator targets only direct children — not grandchildren.

/* Only <li> elements that are direct children of <ul> */
ul > li {
  list-style: square;
}

Pseudo-class Selectors

Pseudo-classes style elements based on their state — hover, focus, visited, etc. Write a colon after the selector.

a:hover { color: orange; }         /* when mouse is over the link */
button:focus { outline: 2px solid blue; } /* when the button is focused */
input:disabled { opacity: 0.5; }   /* when the input is disabled */
li:first-child { font-weight: bold; } /* the first li in its parent */
li:last-child { border-bottom: none; }
li:nth-child(2) { color: red; }    /* the second li */

Pseudo-element Selectors

Pseudo-elements style a part of an element — like its first line or generated content. Write two colons.

p::first-line { font-weight: bold; }    /* first line of every paragraph */
p::first-letter { font-size: 2em; }    /* the first letter (drop-cap style) */

/* ::before and ::after insert generated content */
.card::before {
  content: "★ ";
  color: gold;
}

Attribute Selectors

Target elements based on their HTML attributes.

[type="text"]  { border: 1px solid #ccc; } /* inputs with type="text" */
[disabled]     { opacity: 0.5; }            /* any element with disabled attr */
[href^="https"] { color: green; }           /* links starting with https */
[href$=".pdf"]  { color: red; }             /* links ending in .pdf */
✅ Tip — Selector Chaining

You can chain selectors together (no space) to get more specific. p.intro means "a <p> that also has class intro." .card.featured means "an element with both the card AND featured classes."

Interview Questions

What is the difference between a class and an ID selector?

A class (.) can be applied to multiple elements and is the recommended way to style things. An ID (#) should be unique per page and has very high specificity, making styles hard to override. Use classes for styling, IDs for JavaScript hooks.

What is the difference between a descendant selector and a child selector?

A descendant selector (space) targets elements at any depth inside the parent. A child selector (>) targets only direct children — one level deep.

What is a pseudo-class vs a pseudo-element?

A pseudo-class (:hover, :focus) styles an element based on its state. A pseudo-element (::before, ::first-line) styles a specific part of an element. Pseudo-classes use one colon, pseudo-elements use two.

🏋️ Exercise

Write CSS rules to do the following:

  1. Make all <h2> elements dark blue.
  2. Make any element with class warning have a red background.
  3. Make links inside .sidebar white with no underline.
  4. Make a link turn orange on hover.
See answers
h2 { color: darkblue; }

.warning { background-color: red; }

.sidebar a {
  color: white;
  text-decoration: none;
}

a:hover { color: orange; }

Summary

  • A CSS rule = selector + declaration block containing property: value; pairs.
  • Element selectors (p, h1) target all elements of that tag type.
  • Class selectors (.name) are reusable and the most common choice for styling.
  • ID selectors (#name) are unique per page — avoid them for styling, use for JS/anchors.
  • Descendant (space) targets any depth inside a parent; child (>) targets only direct children.
  • Pseudo-classes (:hover) style states; pseudo-elements (::before) style parts of elements.
  • Grouping (comma) applies the same rules to multiple selectors at once.

Related Topics