Lesson Progress
0% Complete

CSS (Cascading Style Sheets) controls how your HTML looks and how it is laid out on the page. Good CSS makes a site readable, consistent, responsive, and easier to maintain as it grows.


1) How CSS Works (The “Cascade”)

CSS rules can come from different places (browser defaults, your stylesheet, inline styles). When more than one rule applies, the browser decides which one wins based on:

  • Specificity: More specific selectors override less specific ones.
  • Source order: If specificity is equal, the later rule wins.
  • Importance: !important overrides most other rules (use very sparingly).

Best practice: Aim for predictable CSS by keeping selectors simple and using a consistent naming approach.


2) CSS Syntax and Selectors

A CSS rule has a selector and declarations:

p {
  color: #222;
  line-height: 1.6;
}

Common selectors

  • Type selector: targets all elements of that type
    h1 { ... }
  • Class selector: reusable styling
    .button { ... }
  • ID selector: should be unique per page (often best avoided for styling)
    #main-nav { ... }
  • Descendant selector: elements inside other elements
    .card p { ... }
  • Child selector: direct children only
    .card > p { ... }
  • Group selector: apply the same rules to multiple selectors
    h1, h2, h3 { ... }
  • Attribute selector: match by attribute
    input[type="email"] { ... }
  • Pseudo-classes (states):
    a:hover { ... }, button:focus { ... }
  • Pseudo-elements (parts of an element):
    p::first-line { ... }, .badge::after { ... }

Specificity in practice

These selectors become progressively more specific:

button { }        /* low */
.button { }       /* higher */
header .button { }/* higher */
#nav .button { }  /* very high */

Guideline: Prefer classes for styling. Keep selectors short to avoid “fighting the CSS”.


3) Organising and Reusing Styles

Reusable styles save time and reduce bugs.

Use consistent naming (simple BEM-style)

.card { }
.card__title { }
.card--featured { }

Separate layout from component styling

  • Layout utilities: spacing, containers, grids
  • Component styles: buttons, cards, forms

Example:

.container {
  max-width: 1100px;
  margin: 0 auto;
  padding: 0 1rem;
}

.button {
  display: inline-block;
  padding: 0.75rem 1rem;
  border-radius: 0.5rem;
  border: 1px solid transparent;
}

4) The Box Model (Core to Layout)

Every element is a box made of:

  • Content: the text/image area
  • Padding: space inside the border
  • Border: line around padding/content
  • Margin: space outside the element
.card {
  margin: 1rem;
  padding: 1rem;
  border: 1px solid #ddd;
}

box-sizing (important for predictable sizing)

By default, width/height apply to content only. Most modern projects switch to border-box so padding and border are included in the set width:

*,
*::before,
*::after {
  box-sizing: border-box;
}

Why it matters: A width: 300px element stays 300px even when you add padding.


5) Typography Basics (Readability First)

Typography affects usability and accessibility.

Font families

Use a safe, readable stack:

body {
  font-family: system-ui, -apple-system, "Segoe UI", Roboto, Arial, sans-serif;
}

Font size and scalable units

Prefer rem for scalable sizing:

html { font-size: 16px; } /* default */
body { font-size: 1rem; } /* 16px */
h1   { font-size: 2rem; } /* 32px */

Line height and spacing

body {
  line-height: 1.6;
}
p {
  margin: 0 0 1rem;
}

Font weight

Use a limited set (e.g. 400 normal, 600 semibold, 700 bold) to keep design consistent.


6) Colours and Contrast

Colours should support readability and brand, not reduce clarity.

Use variables for a consistent palette

CSS custom properties make themes and updates easier:

:root {
  --colour-text: #1f2937;
  --colour-bg: #ffffff;
  --colour-primary: #1d4ed8;
  --colour-border: #e5e7eb;
}

body {
  color: var(--colour-text);
  background: var(--colour-bg);
}
a {
  color: var(--colour-primary);
}

Contrast and accessibility (WCAG-informed)

  • Ensure good contrast between text and background.
  • Don’t rely on colour alone to communicate meaning (e.g. “required fields” should include an icon or text, not just red).

7) Display, Visibility, and Common Layout Properties

display

  • block: takes full width (e.g. div, p)
  • inline: flows with text (e.g. span, a)
  • inline-block: inline but accepts width/height
  • flex and grid: modern layout systems

Visibility

  • display: none; removes from layout.
  • visibility: hidden; keeps space but hides content.

8) Modern Layout with Flexbox (1D Layout)

Flexbox is best for laying out items in a row or column.

Basic Flex container

.nav {
  display: flex;
  gap: 1rem;
  justify-content: space-between;
  align-items: centre; /* Note: in CSS it's "center" spelling */
}

In CSS the keyword is center (American spelling), even in South Africa English.

Correct version:

.nav {
  display: flex;
  gap: 1rem;
  justify-content: space-between;
  align-items: center;
}

Common Flex patterns

Evenly spaced cards

.cards {
  display: flex;
  gap: 1rem;
  flex-wrap: wrap;
}

.card {
  flex: 1 1 250px; /* grow, shrink, base width */
}

Centre content

.hero {
  display: flex;
  align-items: center;
  justify-content: center;
  min-height: 60vh;
}

Key properties to know:

  • flex-direction (row/column)
  • justify-content (main axis)
  • align-items (cross axis)
  • gap (spacing between items)
  • flex-wrap (wrap onto new lines)

9) Modern Layout with CSS Grid (2D Layout)

Grid is ideal for rows and columns together (page layouts, galleries, dashboards).

Simple responsive grid

.gallery {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(180px, 1fr));
  gap: 1rem;
}

This automatically adjusts the number of columns based on available space.

Page layout example

.page {
  display: grid;
  grid-template-columns: 1fr;
  grid-template-areas:
    "header"
    "main"
    "footer";
  min-height: 100vh;
}

header { grid-area: header; }
main   { grid-area: main; }
footer { grid-area: footer; }

@media (min-width: 768px) {
  .page {
    grid-template-columns: 260px 1fr;
    grid-template-areas:
      "header header"
      "sidebar main"
      "footer footer";
  }

  aside { grid-area: sidebar; }
}

Key properties to know:

  • grid-template-columns / grid-template-rows
  • gap
  • grid-column / grid-row
  • grid-template-areas

10) Responsive Design Basics (CSS-first)

Responsive design means your layout adapts to different screen sizes.

Use flexible sizing

  • Prefer %, fr, rem, vw/vh, and minmax() rather than fixed pixels.
  • Use max-width to keep content readable:
.content {
  max-width: 65ch; /* good reading width */
}

Media queries

.card-list {
  display: grid;
  grid-template-columns: 1fr;
  gap: 1rem;
}

@media (min-width: 600px) {
  .card-list {
    grid-template-columns: repeat(2, 1fr);
  }
}

@media (min-width: 900px) {
  .card-list {
    grid-template-columns: repeat(3, 1fr);
  }
}

Tip: Start with a simple mobile layout, then enhance with larger breakpoints.


11) Styling Links, Buttons, and Forms (Common UI Basics)

Links

Ensure hover and focus are clear (important for keyboard users):

a {
  text-decoration-thickness: 2px;
  text-underline-offset: 0.2em;
}

a:hover {
  text-decoration: none;
}

a:focus-visible {
  outline: 3px solid var(--colour-primary);
  outline-offset: 3px;
}

Buttons

.button {
  background: var(--colour-primary);
  color: white;
  border: none;
  border-radius: 0.5rem;
  padding: 0.75rem 1rem;
}

.button:hover {
  filter: brightness(0.95);
}

.button:focus-visible {
  outline: 3px solid #000;
  outline-offset: 3px;
}

Form inputs

input, select, textarea {
  width: 100%;
  padding: 0.75rem;
  border: 1px solid var(--colour-border);
  border-radius: 0.5rem;
}

input:focus-visible, textarea:focus-visible {
  outline: 3px solid var(--colour-primary);
  outline-offset: 2px;
}

12) Practical Mini-Checklist for Clean CSS

  • Use classes for most styling.
  • Set global box-sizing: border-box.
  • Use CSS variables for colours and spacing.
  • Prefer Flexbox for rows/columns, Grid for two-dimensional layouts.
  • Keep spacing consistent (e.g. steps like 0.5rem, 1rem, 2rem).
  • Always style :focus-visible for accessibility.
  • Avoid overusing !important and very specific selectors.

Quick Practice (Apply What You Learnt)

  1. Create a .container that centres content with a max width.
  2. Build a responsive card grid using grid-template-columns: repeat(auto-fit, minmax(...)).
  3. Add a .button class with hover and :focus-visible styles.
  4. Move colours into :root variables and update your components to use them.

This foundation will make it much easier to build responsive, accessible interfaces as you move into more advanced styling and real project layouts.