CSS Fundamentals

Overview
CSS Fundamentals is a purpose-built interactive teaching tool for T Level Digital Production, Design and Development students. It replaces static slides with live, hands-on exploration: students drag sliders, toggle properties, and watch both the visual output and the generated CSS code update in real time.
The application is designed to be used:
- In class as a teacher-led demonstration tool projected onto a board
- Independently by students as a self-study reference and sandbox
- As a homework resource accessible via any modern browser
Features
- 10 progressive modules covering the core CSS curriculum from box model to responsive design
- Interactive playgrounds — every key concept has a live visual demo with controls
- Live code generation — the CSS produced by each playground is shown in syntax-highlighted code blocks so students immediately see the relationship between properties and values
- Progress bar tracking movement through the 10 modules
- Lazy-loaded modules for fast initial load
- No backend — runs entirely in the browser, deployable to any static host
Module List
| # | Module | Key Concepts |
|---|---|---|
| 1 | Box Model | content, padding, border, margin, box-sizing, margin collapse |
| 2 | Display & Flow | block, inline, inline-block, display: none vs visibility: hidden |
| 3 | Positioning | static, relative, absolute, fixed, sticky, z-index, stacking context |
| 4 | Flexbox | flex container, flex items, justify-content, align-items, flex-grow/shrink/basis |
| 5 | CSS Grid | grid tracks, fr unit, grid-template, spanning, auto-fit vs auto-fill |
| 6 | Typography | font-family stacks, font-size units, line-height, letter-spacing, text properties |
| 7 | Colours & Backgrounds | named, hex, rgb, hsl, oklch, gradients, currentColor |
| 8 | Transitions & Animations | transition properties, timing functions, @keyframes, animation properties |
| 9 | Responsive Design | viewport units, clamp(), media queries, container queries |
| 10 | Modals & Overlays | fixed positioning, z-index, backdrop-filter, animation, <dialog> element |
Teaching Notes
How to Use This App in the Classroom
As a demonstration tool (teacher-led)
- Open the app full-screen on the projector
- Navigate to the module you are teaching
- Read the introductory text with students, then move to the interactive playground
- Manipulate controls live while narrating what each property does
- Draw attention to the code block — ask students to predict what value will change before you move a slider
- Use the progression bar as a course roadmap — show students where they are in the curriculum
As a self-directed activity
- Direct students to open the app individually (shared link, local server, or USB deploy)
- Set a structured exploration task per module (see Assessment Ideas)
- Require students to record the CSS code from specific playground configurations in their notes
- Ask them to replicate an effect in a separate HTML file to consolidate learning
As a homework reference
The app works offline once the build is deployed to a static host. Share the URL for students to explore at home. The code blocks mean every playground configuration produces copyable, working CSS.
Module 1 — The Box Model
Learning objective: Students understand that every element is a rectangular box with four layers, and can predict how box dimensions are calculated.
Time allocation: 45–60 minutes
Key concepts to emphasise
- The four layers — content → padding → border → margin — are always present even when set to zero
- Margin is not part of the element. It cannot receive a background colour. This is a frequent source of confusion when students try to colour the space between elements
box-sizing: border-boxis the single most impactful CSS reset. Demonstratecontent-boxvsborder-boxusing the playground’s Total Width display- Margin collapse is unintuitive — show that two adjacent margins do not add; only the larger survives
Classroom walkthrough
- Ask students: “If I set
width: 200px, how wide is the element?” — accept answers, then reveal that it depends onbox-sizing - Open the playground. With
content-boxselected, drag padding up. Watch Total Width increase - Switch to
border-box. Drag padding again — Total Width stays at 180px. Ask: “Where did the extra space go?” - Reset padding, increase margin. Discuss: why doesn’t the margin appear in Total Width?
Discussion prompts
- “When would
content-boxever be the right choice?” (Almost never in modern development — legacy only) - “Two paragraphs both have
margin-bottom: 32pxandmargin-top: 16px. What is the gap between them?”
Common pitfalls
- Students set
margin: autoexpecting vertical centring — remind them it only works horizontally on block elements with a defined width (or in flex/grid) - Students confuse
paddingandmargin— a useful mnemonic: Padding is inside your Pocket, Margin is the Moat outside
Module 2 — Display & Flow
Learning objective: Students understand normal document flow and can choose the correct display value for a layout requirement.
Time allocation: 30–45 minutes
Key concepts to emphasise
- Normal flow is the default — the browser lays out elements before any CSS runs. Block elements stack; inline elements flow like text
inlineelements ignorewidthandheight— this surprises students who try to size a<span>inline-blockis the hybrid: flows with text but respects box dimensionsdisplay: noneremoves from both visual display and accessibility tree;visibility: hiddenpreserves space
Classroom walkthrough
- Show the playground with
blockselected — three coloured boxes stacking vertically - Switch to
inline— watch the width slider become irrelevant, items collapse to their label width - Switch to
inline-block— items flow side by side but the sliders work again - Discuss the accessibility note about
display: none
Discussion prompts
- “You want a navigation bar where links sit side by side. Which display values could you use?”
- “A
<div>and a<span>contain the same text. What is different about how they lay out by default?”
Extension: flow roots
For more advanced students: mention that display: flow-root creates a block formatting context, preventing margin collapse and containing floats. This is rarely needed but demonstrates that CSS display has more depth than three values.
Module 3 — Positioning
Learning objective: Students can identify which position value to use for a given layout requirement and understand the containing block concept.
Time allocation: 45–60 minutes
Key concepts to emphasise
staticis the default —top/leftdo nothing to static elementsrelativeoffsets from the element’s own normal-flow position, but the space is preserved (ghost space)absoluteremoves the element from flow and positions it relative to the nearest non-static ancestorfixedpositions relative to the viewport — essential for sticky headers and modalsstickyis a hybrid — behavesrelativeuntil a scroll threshold, then sticks
Classroom walkthrough
- Start with
relative— drag the top/left sliders. Draw attention to the ghost space left behind - Switch to
absolute— the ghost space collapses. The box now refers to the parent container - Switch to
fixed— note the app’s preview clips it (the element would escape to the browser chrome in a real page) - Explain the containing block: “absolute looks for the nearest positioned ancestor; if none, it uses
<html>“
Sticky gotchas to cover
position: sticky breaks if:
- No
top(orbottom) is defined - The parent is too short to scroll through
- Any ancestor has
overflow: hidden
These are extremely common bugs — worth spending time on.
Discussion prompts
- “You want a ‘Back to top’ button that always appears in the bottom-right corner, even as the user scrolls. Which position value?”
- “A tooltip must appear directly above its trigger button, wherever on the page that button is. How would you structure the HTML and CSS?”
Module 4 — Flexbox
Learning objective: Students can use the Flexbox model to build one-dimensional layouts with controlled alignment and distribution.
Time allocation: 60–90 minutes
Key concepts to emphasise
- Flex properties are split: container properties control all children; item properties let individual children override
- The main axis (direction) vs cross axis —
justify-contentacts on the main axis;align-itemson the cross axis flex-grow: 1means “take a share of available space”, not “be 100% wide”- The
flexshorthand (flex: 1,flex: auto,flex: none) is strongly preferred over setting the three sub-properties individually
Classroom walkthrough — container properties
- Start with
flex-direction: rowandjustify-content: flex-start— the default - Change
justify-contentthrough all values —space-betweenandspace-evenlyare the most visually striking - Change
align-items— usestretchvscenterto show cross-axis alignment - Enable
flex-wrap— add items until they wrap; discuss the difference from grid
Classroom walkthrough — item properties
- Click item 1, set
flex-grow: 1— it expands to fill remaining space - Click item 2, set
flex-grow: 2— now item 2 gets twice the spare space as item 1 - Set
flex-basis: 120pxon an item — its starting size changes before grow/shrink applies
Discussion prompts
- “You want three equal-width cards in a row, filling the container. What flex properties?”
- “You want a navigation bar: logo on the left, links grouped on the right. Flex approach?”
Flexbox vs Grid — when to choose
A useful heuristic to teach:
- Flexbox — layout in one direction, content drives size
- Grid — layout in two dimensions, or you want explicit cell placement
Module 5 — CSS Grid
Learning objective: Students can create two-dimensional page layouts using CSS Grid and understand track sizing, spanning, and responsive grid patterns.
Time allocation: 60–90 minutes
Key concepts to emphasise
- Grid is two-dimensional — you define both rows and columns simultaneously
- The
frunit divides available space after fixed tracks are placed — not the total container minmax(min, max)is essential for responsive gridsauto-fitvsauto-fillonly differs when items don’t fill the row
Classroom walkthrough
- Start with the preset 3-col equal (
repeat(3, 1fr)) — a classic equal-column layout - Switch to 2-col + aside (
2fr 1fr) — introduce fractional proportions - Switch to Holy Grail (
200px 1fr 200px) — fixed sidebars with flexible centre - Switch to auto-fit — resize the item count slider to show how columns automatically adjust
- Open the spanning demo — explain grid line numbers and the
1 / -1shorthand for full-width items
Explaining the fr unit
A common confusion: students think 1fr means “100% of the container.” Use this example:
grid-template-columns: 200px 1fr 1fr;
/* Container: 800px total. Fixed: 200px. Remaining: 600px. Each fr: 300px */
The playground’s preset switcher makes this easy to demonstrate live.
Discussion prompts
- “When would you choose Grid over Flexbox for a page layout?”
- “How would you make a photo gallery where images are different sizes but always fill the available width?”
Module 6 — Typography
Learning objective: Students can control all aspects of text appearance using CSS and understand why relative units are preferred for font sizing.
Time allocation: 45 minutes
Key concepts to emphasise
- The font stack is a priority list — always end with a generic family (
serif,sans-serif,monospace) - Unitless line-height (e.g.,
1.6) is a multiplier of the element’s own font-size; it inherits correctly. A pixel value does not remis the correct unit for accessible font sizing in production — it respects the user’s browser font size preference;pxoverrides itclamp()enables fluid type without media queries (covered more deeply in Module 9)
Classroom walkthrough
- Open the playground — drag font-size and watch the code block update
- Change font-family through the presets — demonstrate serif vs sans-serif legibility
- Drop line-height below 1.0 — show how text becomes unreadable; optimal is 1.5–1.7 for body
- Drag letter-spacing into negative values — discuss when negative tracking is appropriate (display headings only)
Relative units comparison table
| Unit | Relative to | Best for |
|---|---|---|
px | Nothing | Borders, shadows (not type) |
em | Parent font-size | Padding/margin relative to text size |
rem | Root (html) font-size | Font sizes — consistent, accessible |
clamp() | Viewport width + fixed bounds | Responsive headings |
Discussion prompts
- “A user has set their browser’s default font size to 20px for accessibility reasons. Which unit respects that preference?”
- “Why is
line-height: 1.6better thanline-height: 24px?”
Module 7 — Colours & Backgrounds
Learning objective: Students understand the main CSS colour formats and can create gradients.
Time allocation: 45 minutes
Key concepts to emphasise
- There are five main formats: named, hex, RGB/RGBA, HSL/HSLA, oklch
- HSL is the most human-readable — designers think in hue, saturation, and lightness
- Gradients are generated images used in the
backgroundproperty, not thecolorproperty currentColoris a powerful keyword for keeping icon and border colours in sync with text
Classroom walkthrough
- Open the HSL mixer — drag Hue across the full 0–360 range to show the colour wheel
- Set Saturation to 0 — all greys. Return to ~70% — vivid. This is a useful rule for accessible design: body text
hsl(X, 0%, 15%), accents athsl(X, 70%, 55%) - Open the gradient builder — switch between linear, radial, and conic. Add a third colour stop
Colour accessibility note
When teaching this module, it is worth briefly introducing contrast ratio (WCAG AA requires 4.5:1 for normal text). Use the lightness slider to demonstrate that low-lightness on low-lightness backgrounds or high-lightness on high-lightness backgrounds fails accessibility checks. Tools like the browser DevTools colour picker show contrast ratios.
Discussion prompts
- “A developer writes
color: rgb(108, 71, 255). A designer writeshsl(258, 70%, 64%). Are these likely the same colour?” - “You want an SVG icon to automatically match the text colour of its container when the theme changes. Which CSS keyword?”
Module 8 — Transitions & Animations
Learning objective: Students can apply CSS transitions and keyframe animations and understand the performance implications of different animated properties.
Time allocation: 60 minutes
Key concepts to emphasise
- Transitions interpolate between two states triggered by a state change (e.g.,
:hover). They need a start and an end state - Animations run on an independent timeline with full keyframe control — no trigger required
- Only
transformandopacityare cheap to animate (GPU compositor). Animatingwidth,height,top,leftcauses layout recalculation on every frame
Classroom walkthrough — transitions
- Hover the demo box — show the transition from square to circle, purple to red
- Set duration to 0ms — snaps instantly. Set to 2000ms — very slow. Discuss ideal ranges (150–400ms for UI)
- Switch timing functions —
ease-outvsease-in. Ask which feels more natural for a button press - Change
transition-propertyfromalltobackground— only colour transitions; shape snaps
Classroom walkthrough — animations
- Cycle through presets — bounce, spin, pulse, fadeIn, shake, wave
- Toggle infinite vs 1 iteration — discuss use cases
- Use the Pause/Resume button — demonstrate
animation-play-state - Look at the keyframe code block — explain percentage stops as “points in time”
Performance rule summary
/* Fast — compositor, no layout reflow */ transform: translate(), scale(), rotate() opacity /* Slow — triggers layout reflow */ width, height, top, left, margin, padding
Discussion prompts
- “You want to animate a card sliding in from off-screen.
margin-left: -300px→margin-left: 0ortransform: translateX(-300px)→transform: translateX(0)— which is better and why?” - “A loading spinner rotates forever. Which animation iteration count?”
Module 9 — Responsive Design
Learning objective: Students can build layouts that adapt to different screen sizes using viewport units, clamp(), and media queries.
Time allocation: 60 minutes
Key concepts to emphasise
- Mobile-first means writing base styles for small screens, then overriding for larger screens with
min-widthqueries — not writing desktop styles and patching mobile clamp(min, preferred, max)eliminates breakpoints for fluid sizing- Container queries (
@container) are the modern evolution of media queries — components respond to their parent’s size, not the viewport dvh(dynamic viewport height) solves the mobile browser chrome problem that100vhhas
Classroom walkthrough
- Open the viewport unit explorer — drag the width slider. Watch the 50vw marker update live
- Open the clamp explorer — set min to 14px, pref to 2.5vw, max to 36px. Drag the simulated viewport width. Point to the graph — explain the three regions (clamped at min, fluid middle, clamped at max)
- Read the media query code block together — point out mobile-first ordering
- Discuss
prefers-reduced-motion— link to accessibility
Mobile-first argument
The mobile-first approach forces you to prioritise content. A page with only base styles (no media queries applied) should still be usable on a phone. Adding breakpoints then progressively enhances the experience. Desktop-first approaches tend to produce overridden styles and specificity battles.
Discussion prompts
- “A site has
font-size: clamp(16px, 2vw, 24px). At what viewport width does the font size stop being fluid?” - “When would you use a container query instead of a media query?”
Module 10 — Modals & Overlays
Learning objective: Students can build a production-quality modal component by combining fixed positioning, z-index, backdrop effects, and CSS animation.
Time allocation: 45–60 minutes
This module is explicitly a synthesis module — every property used comes from earlier modules.
Key concepts to emphasise
- A modal requires two layers: the overlay (covers everything) and the modal box (centred in the overlay)
position: fixed; inset: 0is the cleanest way to make a full-viewport overlaybackdrop-filter: blur()requires the overlay to have a non-opaque background (even#00000001works)- The native
<dialog>element is the accessible first choice for production — it handles focus trapping, Escape key, and screen readers automatically
Classroom walkthrough
- Open the playground — adjust backdrop blur slider. Toggle it between 0 and 12px
- Lower overlay opacity. Explain that
backdrop-filterhas no visible effect at opacity 0 - Switch animation presets — compare scale, slide, fade, bounce. Ask which feels most appropriate for a “serious” app vs a playful one
- Click “Open Modal” — click the overlay to dismiss (click-outside pattern). Discuss UX: should all modals close on overlay click?
- Read the code block — trace through each property’s role
Accessibility imperative
Always mention the <dialog> element when teaching modals. A <div> modal requires:
role="dialog"andaria-modal="true"attributes- Manual focus trapping with JavaScript
- Manual Escape key handling
- Manual
aria-labelledbywiring
<dialog> provides all of this for free. The extra CSS work to style it is trivial.
Discussion prompts
- “A user opens a modal on a very long page. They can scroll the background content. Which CSS property on
<body>fixes this?” - “You have a modal inside a container with
transform: scale(0.9). The modal’sposition: fixedoverlay doesn’t cover the full screen. Why?” (This is the stacking context trap —transformcreates a new stacking context that containsfixedelements.)
Common Student Misconceptions
| Misconception | Correction |
|---|---|
“I set width: 200px but my element is 240px wide” | box-sizing: content-box adds padding and border on top. Use border-box |
| “Margin and padding do the same thing” | Margin is outside the element (no background), padding is inside |
“z-index: 9999 will always be on top” | z-index is relative within a stacking context. A z-index: 1 in a higher context beats z-index: 9999 in a lower one |
| “Flexbox and Grid are the same” | Flexbox is one-dimensional; Grid is two-dimensional |
“inline and inline-block are the same” | inline ignores width/height; inline-block respects them |
“position: sticky isn’t working” | Check: top value defined? Parent tall enough? No overflow: hidden on ancestor? |
“I can use height: 100% anywhere” | % height requires the parent to have an explicit height. Use 100vh for viewport height |
“px font sizes are fine for accessibility” | px overrides the user’s browser font size preference; use rem |
Assessment Ideas
Formative — in-class exploration tasks
Module 1 — Box Model challenge
Using the playground, find the combination of padding and border-width where
content-boxandborder-boxproduce the same total element width. (Answer: both 0.)
Module 4 — Flexbox layout challenge
Configure the Flexbox playground to produce a horizontal row of items with the first item pushed to the left and all remaining items grouped to the right. Record the CSS.
Module 5 — Grid layout challenge
Use the Grid playground to recreate a standard “blog layout”: a wide main column (roughly 2/3 width) and a narrower sidebar (1/3 width). Record the
grid-template-columnsvalue.
Module 8 — Animation audit
List three properties from the transition playground that are “expensive” to animate (trigger layout) and explain an alternative for each.
Summative — mini-project ideas
- Portfolio card component — build a responsive card using Flexbox or Grid, with hover transition and typographic hierarchy using
remunits - Navigation bar — sticky header, logo left, links right (Flexbox), with a hamburger menu (Positioning + Transitions)
- Pricing table — CSS Grid layout, colour-coded columns, hover effects, responsive breakpoints
- Animated loading screen — full-viewport fixed overlay (Modal pattern) with a keyframe animation
License
Copyright © 2025 Simon Rundell / Exeter College
This work is licensed under a Creative Commons Attribution-NonCommercial-ShareAlike 4.0 International License.
You are free to:
- Share — copy and redistribute the material in any medium or format
- Adapt — remix, transform, and build upon the material
Under the following terms:
- Attribution — give appropriate credit, provide a link to the licence, and indicate if changes were made
- NonCommercial — you may not use the material for commercial purposes
- ShareAlike — if you remix or transform this material, you must distribute your contributions under the same licence

















































































































