← Back to Index

CSS Anatomy - Symbols, Structure & Terminology

A reference for all the punctuation, prefixes, and structural elements of CSS.

The anatomy of a CSS rule

RULE .card:hover > .title::before { color : red ; margin : 0 auto ; } SELECTOR DECLARATION DECLARATION PROPERTY VALUE DECLARATION BLOCK (everything between { }) Selector Declaration Property Value Declaration Block
TermWhat it isExample
RuleA selector + declaration block together.card { color: red; }
SelectorWhat to target.card:hover > .title
Declaration blockEverything between { }{ color: red; margin: 0; }
DeclarationOne property-value paircolor: red;
PropertyWhat to stylecolor
ValueHow to style itred

Selector anatomy

  #main   .card   :hover   >   .title   ::before   [data-v]
  ├──┤    ├───┤   ├────┤   │   ├────┤   ├──────┤   ├──────┤
   ID     CLASS   PSEUDO  COMB  CLASS   PSEUDO    ATTRIBUTE
                  CLASS   INATOR        ELEMENT   SELECTOR
Selector typeSyntaxExampleSpecificity column
Universal** { margin: 0; }(0, 0, 0)
Element (type)elementh1, div, pC (elements)
Class.name.card, .activeB (classes)
ID#name#main, #headerA (IDs)
Attribute[attr] or [attr=val][type="email"]B (classes)
Pseudo-class:name:hover, :focus, :not()B (classes)
Pseudo-element::name::before, ::afterC (elements)

CSS symbols - what each punctuation means

. Dot - class selector

Selects elements by class name. .card matches <div class="card">.

# Hash - ID selector

Selects a single element by ID. #main matches <div id="main">. Highest specificity of any selector.

: Single colon - pseudo-class

Selects an element in a particular state or position. The element itself exists in the DOM - the pseudo-class is a condition on it.

:hover        /* mouse is over it */
:focus        /* it has keyboard focus */
:first-child  /* it's the first child of its parent */
:not(.x)      /* it does NOT match .x */
:has(.x)      /* it contains .x */
:is(.a, .b)   /* it matches .a OR .b */
:where(.a)    /* same as :is but zero specificity */
:nth-child(2) /* it's the 2nd child */
:checked      /* checkbox/radio is checked */
:invalid      /* form field fails validation */

:: Double colon - pseudo-element

Targets something the browser generates that doesn't exist as a real DOM element. You're styling a "virtual" piece of the element.

::before           /* generated content before the element's content */
::after            /* generated content after the element's content */
::placeholder      /* placeholder text in inputs */
::selection        /* text the user has highlighted */
::view-transition-old(name)  /* snapshot of old state during view transition */
::view-transition-new(name)  /* snapshot of new state during view transition */

: vs :: - the mental model: Single colon = state/condition of a real element. Double colon = a generated virtual element that doesn't exist in your HTML. Historically, :before worked (single colon), but the double colon is the correct modern syntax.

-- Double hyphen - custom property (variable) or custom name

The -- prefix marks something as user-defined. The spec reserves this prefix so your names never collide with current or future CSS properties.

/* Custom properties (variables) */
--color-primary: #3a86ff;        /* declaration */
color: var(--color-primary);     /* usage */

/* Custom names for other features */
anchor-name: --my-button;        /* anchor positioning */
view-transition-name: --hero;    /* view transitions (-- optional here) */
@function --double(--value) {}   /* custom function name */
@property --size {}              /* registered property */
Ad

@ At-sign - at-rule

Introduces a structural rule or directive - something that controls how CSS is applied rather than styling an element directly.

/* Conditional rules - apply styles under conditions */
@media (width < 768px) { }       /* viewport condition */
@container (min-width: 400px) { } /* container condition */
@supports (display: grid) { }    /* feature detection */

/* Structural rules - define CSS structure */
@layer reset, base, components;   /* cascade layer order */
@layer base { }                   /* add styles to a layer */
@import url("file.css");          /* import another stylesheet */

/* Definitions - define reusable things */
@keyframes spin { }               /* animation sequence */
@function --name() { }            /* custom function */
@property --size { }              /* registered custom property */
@font-face { }                    /* custom font */

/* Configuration */
@view-transition { navigation: auto; }  /* opt into view transitions */
@position-try --below { }         /* anchor positioning fallback */
@scope (.card) { }                /* style scoping */

@ = "meta-level CSS." Regular rules say "style this element like that." At-rules say "here's a condition/structure/definition that governs how other rules work." They never directly style an element - they create context for rules that do.

& Ampersand - parent selector (in nesting)

Inside a nested rule, & represents the outer/parent selector. Used to compose selectors.

.card {
  & .title { }     /* → .card .title (descendant) */
  &:hover { }      /* → .card:hover (pseudo-class on parent) */
  &.featured { }   /* → .card.featured (compound - same element) */
}

> + ~ (space) - combinators

Combinators define the relationship between two selector parts:

CombinatorMeansExample
(space)Descendant (any depth).card .title - .title anywhere inside .card
>Direct child only.card > .title - .title that's a direct child of .card
+Adjacent sibling (next)h2 + p - the first p immediately after an h2
~General sibling (any after)h2 ~ p - any p that comes after an h2 (same parent)

! - !important

Placed after a value to escalate it above normal cascade resolution. Jumps to a higher tier in the cascade (above layers and specificity).

color: red !important;  /* wins over any normal declaration regardless of specificity */

[] Square brackets - attribute selector

[data-v]           /* has the attribute at all */
[type="email"]     /* attribute equals value */
[class~="card"]    /* attribute word list contains "card" */
[href^="https"]    /* attribute starts with "https" */
[src$=".png"]      /* attribute ends with ".png" */
[data*="user"]     /* attribute contains "user" anywhere */

Quick symbol cheat sheet

SymbolContextMeaning
.SelectorClass
#SelectorID
:SelectorPseudo-class (state/condition)
::SelectorPseudo-element (generated content)
--Name prefixUser-defined (custom property, function, anchor, etc.)
@Rule startAt-rule (structural/conditional/definition)
&NestingParent selector reference
>SelectorDirect child combinator
+SelectorAdjacent sibling combinator
~SelectorGeneral sibling combinator
(space)SelectorDescendant combinator
[]SelectorAttribute selector
!Value suffix!important escalation
*SelectorUniversal selector (match anything)