Foundations reference

CSS Reference

A complete reference for the visual system of a web page.

Selectors and the cascade

Rules and selectors

A rule has a selector saying which elements it applies to, and declarations saying what to do to them.

p { color: #57493D; }
.card { border: 1px solid #ddd; }
nav a { color: #B9834F; }
nav > a { text-decoration: none; }
  • A space means descendant at any depth. A greater-than sign means direct child only.
  • Style with classes. An id can never be reused and carries very high specificity.

Specificity

When two rules conflict, the more specific selector wins. Count ids, then classes, then element types.

#hero      /* (1,0,0) */
.card .title /* (0,2,0) */
nav a        /* (0,0,2) */
  • Compare left to right. The first column that differs decides it.
  • Source order breaks a tie.
  • !important on your own stylesheet means the selectors are the real problem.

The box model

Content, padding, border, margin

Padding is space inside the element and takes its background. Margin is space outside and is always transparent.

.card {
  padding: 1.5rem;      /* inside */
  border: 2px solid;    /* the line */
  margin-bottom: 2rem;  /* between */
}

box-sizing

By default width sets the content only, so padding and border are added on top.

* { box-sizing: border-box; }

/* now width means the whole box */
.card { width: 320px; padding: 1.5rem; }
  • Without it, width: 300px with 1rem padding and a 2px border renders at 336px.

Margin collapse

Two vertical margins that meet do not add. The larger wins and the smaller disappears.

.a { margin-bottom: 2rem; }
.b { margin-top: 1rem; }
/* the gap is 2rem, not 3rem */
  • Padding never collapses, which is the usual workaround.
  • Many stylesheets only ever use margin-bottom.

Layout

Flexbox

Arranges children along one axis and distributes the leftover space. Every property goes on the container.

.bar {
  display: flex;
  justify-content: space-between;
  align-items: center;
  gap: 1rem;
}
.cards { display: flex; flex-wrap: wrap; gap: 1rem; }
.card  { flex: 1 1 260px; }
  • justify-content works along the main axis, align-items along the cross axis.

Grid

Controls rows and columns at once. The fr unit divides whatever space is left after fixed sizes and gaps.

.gallery {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(240px, 1fr));
  gap: 1.5rem;
}
  • auto-fit with minmax is responsive layout with no media query at all.
  • Grid for the page skeleton, Flexbox for the pieces inside it.

Responsive design

Write the narrow layout as the base, then add complexity as the screen grows.

img { max-width: 100%; height: auto; }
.container { max-width: 60rem; margin: 0 auto; }
h1 { font-size: clamp(1.75rem, 6vw, 3rem); }

@media (min-width: 48rem) {
  .gallery { grid-template-columns: 1fr 1fr; }
}
  • Those two image declarations prevent the most common mobile bug there is.
  • Choose breakpoints by widening until the layout looks wrong, not by device name.

Type, colour and motion

Units

rem is relative to the root font size, which the reader can change. px overrides that choice.

body { font-size: 1rem; line-height: 1.6; }
.prose { max-width: 34rem; }
  • Sizing text in rem is an accessibility decision, not a stylistic one.
  • Write line-height without a unit so it multiplies each element's own size.

Custom properties

Variables declared on :root are available to the whole document, and redefining them re-themes everything that uses them.

:root {
  --brand: #B9834F;
  --ink: #2B1F17;
  --surface: #FFF9F2;
}
.btn { background: var(--brand); }

[data-theme="dark"] { --surface: #2B1F17; --ink: #FFF9F2; }
  • Name by role, not appearance. A variable called --gold holding green is worse than none.

Transitions and motion

Declare the transition on the resting state so it applies in both directions.

.btn {
  transition: background 200ms ease, transform 200ms ease;
}
.btn:hover { transform: translateY(-2px); }

@media (prefers-reduced-motion: reduce) {
  * { transition-duration: 0.01ms !important; }
}
  • transform and opacity are the cheapest properties to animate.
  • Honouring reduced motion is a few lines and matters enormously to those affected.

Focus

Never remove the focus outline. Replace it if it does not suit the design.

:focus-visible {
  outline: 3px solid var(--brand);
  outline-offset: 3px;
}
  • outline: none leaves keyboard users with no idea where they are on the page.

Want to learn how to build with this?

A reference tells you what exists. The course teaches you when to reach for it, and has you build something real while you learn.