// fullstack developer reference

HTML & CSS
Master Guide

Everything a fullstack developer needs to know — from semantic structure to modern layout systems, animations, architecture, accessibility, and production performance.

22
Sections
40+
Exercises
8
Projects
01

HTML Fundamentals

HTML

HTML (HyperText Markup Language) is the skeleton of every webpage. It provides structure and meaning to content — not styling. Understanding it deeply is non-negotiable for fullstack work.

Anatomy of an HTML Element

html
<!-- Opening tag  Attribute name  Attribute value  Content  Closing tag -->
<a href="https://example.com" target="_blank">Visit Example</a>

<!-- Void (self-closing) elements have no closing tag -->
<img src="photo.jpg" alt="A scenic view" width="800" height="600">
<br>  <hr>  <input>  <meta>  <link>  <source>

Global Attributes

These apply to any HTML element:

AttributePurposeExample
idUnique identifier on pageid="header"
classCSS class targeting (space-separated)class="card active"
data-*Custom data attributes for JSdata-user-id="42"
styleInline CSS (avoid in production)style="color:red"
hiddenHides element from renderinghidden
tabindexControls keyboard focus ordertabindex="0"
contenteditableMakes element editable inlinecontenteditable="true"
draggableEnables drag-and-dropdraggable="true"
langLanguage of element's contentlang="en"
titleTooltip on hovertitle="More info"
aria-*Accessibility roles/propertiesaria-label="Close"
roleARIA semantic rolerole="dialog"
🖊 Exercise 1.1 Easy
Topic: Elements & Attributes
  1. Create an HTML file with a heading, paragraph, image (with meaningful alt text), and a link that opens in a new tab.
  2. Add data-category attributes to at least 3 elements.
  3. Use title attribute on the link to show a helpful tooltip.
  4. Validate your HTML at validator.w3.org — fix all errors.
02

Document Structure

HTML

The Complete Boilerplate

html
<!DOCTYPE html>
<html lang="en">
<head>
  <!-- Character encoding — always first -->
  <meta charset="UTF-8">

  <!-- Responsive viewport -->
  <meta name="viewport" content="width=device-width, initial-scale=1.0">

  <!-- SEO meta tags -->
  <meta name="description" content="Page description for search engines">
  <meta name="keywords" content="html, css, tutorial">
  <meta name="author" content="Your Name">

  <!-- Open Graph (social media previews) -->
  <meta property="og:title" content="Page Title">
  <meta property="og:description" content="Description">
  <meta property="og:image" content="https://example.com/image.jpg">
  <meta property="og:url" content="https://example.com">

  <!-- Favicon -->
  <link rel="icon" type="image/png" href="/favicon.png">

  <!-- Fonts — preconnect for performance -->
  <link rel="preconnect" href="https://fonts.googleapis.com">

  <!-- Canonical URL (prevents duplicate content) -->
  <link rel="canonical" href="https://example.com/page">

  <!-- Stylesheet -->
  <link rel="stylesheet" href="styles.css">

  <title>Page Title | Site Name</title>
</head>
<body>
  <!-- Content goes here -->

  <!-- Scripts at end of body for performance -->
  <script src="app.js" defer></script>
</body>
</html>
💡 Pro Tip
Use defer on scripts to load them without blocking HTML parsing. Use async for scripts that don't depend on DOM or other scripts. Never use bare <script> in <head> without defer/async.
🖊 Exercise 2.1 Easy
Topic: Document Head
  1. Build a complete HTML boilerplate from memory.
  2. Add full Open Graph tags and test with opengraph.xyz.
  3. Add a <meta name="theme-color"> and test on mobile Chrome.
03

Semantic HTML

HTML Accessibility

Semantic HTML gives meaning to structure. It matters for SEO, screen readers, and maintainability. A fullstack dev who ships <div> soup is a junior dev regardless of their backend skills.

Page-Level Landmarks

html — page layout
<body>
  <header>             <!-- Site-wide header, logo, top nav -->
    <nav>               <!-- Primary navigation links -->
      <ul><li><a href="/">Home</a></li></ul>
    </nav>
  </header>

  <main>               <!-- ONE per page — the unique content -->
    <article>          <!-- Self-contained content (blog post, card) -->
      <h1>Post Title</h1>
      <section>         <!-- Themed section within article -->
        <h2>Introduction</h2>
        <p>...</p>
      </section>
    </article>

    <aside>             <!-- Sidebar, related links, ads -->
      <p>Related posts...</p>
    </aside>
  </main>

  <footer>             <!-- Copyright, links, contact -->
    <address>contact@site.com</address>
  </footer>
</body>

Content Semantics Cheatsheet

ElementUse when…Don't use for…
<h1>–<h6>Hierarchical headings — one h1 per pageBold text, decorative sizing
<p>Paragraphs of proseLine breaks or spacing hacks
<ul> / <ol>Unordered/ordered listsNavigation (use nav+ul)
<dl> <dt> <dd>Definition/description listsKey-value pairs in general
<figure> / <figcaption>Images with captions, diagramsDecorative images
<blockquote>Quoted text from another sourceIndentation styling
<cite>Title of creative work being citedAuthor attribution
<time>Dates/times (machine-readable)Durations as plain text
<mark>Highlighted/search-result textGeneral emphasis
<strong>Strong importanceBold for styling only (use CSS)
<em>Stress emphasisItalic for styling only
<abbr>Abbreviations with title="…"Acronyms that are self-evident
<details> / <summary>Native accordion / disclosureComplex interactive components
<dialog>Modal dialogs (native)Tooltips or dropdowns
<progress>Task completion barsDecorative bars
<meter>Scalar measurement within rangeGeneric bars
🖊 Exercise 3.1 Medium
Topic: Semantic Refactoring
  1. Take a page made entirely of <div> and <span> tags and refactor it to use proper semantic elements.
  2. Verify with an accessibility audit: open DevTools → Lighthouse → Accessibility. Target 90+.
  3. Use <details>/<summary> to build a FAQ section with NO JavaScript.
  4. Add <time datetime="2025-01-15"> for all dates on the page.
04

Forms & Inputs

HTML

Forms are how users talk to your backend. Getting them right — semantics, validation, accessibility — is a core fullstack skill.

Complete Form Reference

html
<form
  action="/api/submit"    <!-- Where to send data -->
  method="post"          <!-- GET or POST -->
  enctype="multipart/form-data"  <!-- Required for file uploads -->
  novalidate             <!-- Disable browser validation (use custom) -->
  autocomplete="on"
>
  <!-- Every input needs a label -->
  <label for="email">Email Address</label>
  <input
    type="email"
    id="email"
    name="email"
    placeholder="you@example.com"
    required
    autocomplete="email"
    aria-describedby="email-hint"
  >
  <span id="email-hint">We'll never share your email.</span>

  <!-- Fieldset groups related controls -->
  <fieldset>
    <legend>Preferred contact method</legend>
    <label><input type="radio" name="contact" value="email"> Email</label>
    <label><input type="radio" name="contact" value="phone"> Phone</label>
  </fieldset>

  <button type="submit">Submit</button>
  <button type="reset">Clear</button>
</form>

Input Types Reference

type="text"
Single-line text
type="email"
Email with validation
type="password"
Masked text
type="number"
Numeric + min/max/step
type="tel"
Phone (no validation)
type="url"
URL format validation
type="date"
Date picker
type="time"
Time picker
type="datetime-local"
Date + time
type="range"
Slider with min/max
type="color"
Color picker
type="file"
File upload
type="checkbox"
Boolean toggle
type="radio"
Single from group
type="search"
Search with clear btn
type="hidden"
Hidden data field
🖊 Exercise 4.1 Medium
Topic: Accessible Form Building
  1. Build a full registration form: name, email, password (with pattern validation), date of birth, gender (radio), country (select), bio (textarea), file upload for avatar, and terms checkbox.
  2. Every input must have a <label for> and use proper autocomplete attributes.
  3. Add HTML5 constraint validation attributes: required, minlength, maxlength, pattern, min, max.
  4. Style :valid and :invalid states with CSS (green/red borders).
05

Multimedia & SVG

HTML

Responsive Images

html
<!-- Basic responsive image -->
<img
  src="hero.jpg"
  srcset="hero-480.jpg 480w, hero-800.jpg 800w, hero-1200.jpg 1200w"
  sizes="(max-width: 600px) 480px, (max-width: 1000px) 800px, 1200px"
  alt="Mountain landscape at dawn"
  width="1200" height="630"
  loading="lazy"
  decoding="async"
>

<!-- Art direction with <picture> -->
<picture>
  <source media="(min-width: 800px)" srcset="desktop.webp" type="image/webp">
  <source media="(min-width: 800px)" srcset="desktop.jpg">
  <source srcset="mobile.webp" type="image/webp">
  <img src="mobile.jpg" alt="Description">
</picture>

<!-- Video with fallback -->
<video controls poster="thumbnail.jpg" preload="metadata">
  <source src="video.webm" type="video/webm">
  <source src="video.mp4"  type="video/mp4">
  <track kind="subtitles" src="subs.vtt" srclang="en" label="English">
  <p>Your browser doesn't support video.</p>
</video>

Inline SVG

svg
<!-- Inline SVG is styleable with CSS, accessible, performant -->
<svg
  xmlns="http://www.w3.org/2000/svg"
  viewBox="0 0 24 24"
  width="24" height="24"
  aria-hidden="true"    <!-- Decorative icon — hide from AT -->
  focusable="false"
>
  <path
    d="M12 2L2 7l10 5 10-5-10-5zM2 17l10 5 10-5M2 12l10 5 10-5"
    stroke="currentColor"    <!-- Inherits CSS color -->
    fill="none"
    stroke-width="2"
  />
</svg>

<!-- SVG sprite system -->
<svg style="display:none">
  <symbol id="icon-home" viewBox="0 0 24 24">...</symbol>
</svg>
<!-- Use it anywhere -->
<svg><use href="#icon-home"></use></svg>

06

CSS Selectors

CSS

Selectors are CSS's targeting system. Master them to write efficient, maintainable styles.

Selector Specificity

ℹ Specificity
Specificity is calculated as (inline, IDs, classes/attrs/pseudos, elements). Higher wins. When equal, last declared wins. !important overrides all — avoid it.
css — specificity examples
/* Specificity: (0,0,0,1) */
p { color: gray; }

/* (0,0,1,0) — class selector */
.card { color: blue; }

/* (0,0,1,1) */
p.intro { color: green; }

/* (0,1,0,0) — ID selector */
#hero { color: red; }

/* (1,0,0,0) — inline style beats all */
style="color: orange"

/* :is() takes highest specificity of its list */
:is(#hero, .card, p) { color: purple; }  /* = (0,1,0,0) */

/* :where() has ZERO specificity — great for resets */
:where(h1, h2, h3) { margin: 0; }

Complete Selector Reference

SelectorMatchesExample
*Everything* { box-sizing: border-box }
EElement typep, h1, section
.classClass attribute.card, .btn-primary
#idID attribute#header, #modal
A BB inside A (any depth).card p
A > BB direct child of Aul > li
A + BB immediately after Ah2 + p
A ~ BB sibling(s) after Ah2 ~ p
[attr]Has attribute[disabled]
[attr="val"]Exact value[type="checkbox"]
[attr^="v"]Starts with[href^="https"]
[attr$="v"]Ends with[href$=".pdf"]
[attr*="v"]Contains[class*="btn"]
:hover / :focusMouse over / keyboard focusa:hover
:nth-child(n)nth child (1-indexed)li:nth-child(odd)
:nth-of-type(n)nth of its typep:nth-of-type(2)
:first-child / :last-childFirst/last childli:last-child
:not(selector)Doesn't match selectorinput:not([type="hidden"])
:has(selector)Contains matching descendant.card:has(img)
::before / ::afterGenerated content pseudo-elements.btn::after
::placeholderInput placeholder textinput::placeholder
::selectionUser-selected text::selection
🖊 Exercise 6.1 Medium
Topic: Selector Mastery
  1. Style all external links (href starts with http) with an arrow indicator using ::after.
  2. Use :nth-child to create zebra-striped table rows without classes.
  3. Use :has() to style a .form-group differently when its input is invalid.
  4. Calculate specificity for 5 selectors of your choice — verify with browser DevTools.
07

Box Model & Display

CSS

The Box Model

Every element is a rectangular box composed of: content → padding → border → margin.

css
/* Always set this — sanest box model */
*, *::before, *::after {
  box-sizing: border-box;  /* padding/border included in width */
}

.box {
  width:   300px;
  height:  200px;
  padding: 20px 24px;   /* top/bottom left/right */
  border:  2px solid #333;
  margin:  16px auto;    /* auto = center horizontally */

  /* Border radius */
  border-radius: 12px;
  border-radius: 50%;          /* Full circle */
  border-radius: 8px 0 8px 0; /* TL TR BR BL */

  /* Outline — doesn't affect layout (good for focus) */
  outline: 2px solid blue;
  outline-offset: 4px;

  /* Box shadow */
  box-shadow: 0 4px 20px rgba(0,0,0,0.15);
  box-shadow: inset 0 2px 4px rgba(0,0,0,0.2); /* Inset */
}

Display Values

ValueBehaviorTypical Use
blockFull width, new line before/after, respects all box model propertiesdiv, p, h1–h6, section
inlineFlows with text, width/height ignoredspan, a, em, strong
inline-blockInline + respects width/height/paddingButtons, badges
flexBlock-level flex containerRow/column layouts
inline-flexInline flex containerInline button groups
gridBlock-level grid containerPage layouts
noneRemoved from layout entirelyHiding elements
contentsElement itself disappears, children remainSemantic wrappers
table / table-cellBehave like table elementsRare edge cases
⚠ Margin Collapse
Vertical margins between block elements collapse to the largest value. Padding, flex, or grid parents prevent this. Horizontal margins never collapse.
08

Typography

CSS
css — typography system
body {
  font-family: 'Inter', system-ui, -apple-system, sans-serif;
  font-size:   16px;           /* Browser default = 16px */
  line-height: 1.6;           /* Unitless — relative to font-size */
  font-weight: 400;           /* 100–900 */
  color: #1a1a1a;
}

/* Type scale using rem */
h1 { font-size: 2.5rem;  }   /* 40px */
h2 { font-size: 2rem;    }   /* 32px */
h3 { font-size: 1.5rem;  }   /* 24px */
h4 { font-size: 1.25rem; }   /* 20px */

/* Fluid typography with clamp() */
h1 {
  font-size: clamp(1.8rem, 4vw, 3.5rem);
  /*         min      ideal   max   */
}

/* Text properties */
.text-styles {
  letter-spacing:  0.05em;
  word-spacing:    0.1em;
  text-transform:  uppercase | lowercase | capitalize;
  text-decoration: underline | line-through | none;
  text-align:      left | center | right | justify;
  text-indent:     2em;
  white-space:     nowrap | pre | pre-wrap | pre-line;
  word-break:      break-word | break-all;
  overflow-wrap:   anywhere;
  hyphens:         auto;
}

/* Truncate to one line */
.truncate {
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}

/* Clamp to N lines */
.clamp-3 {
  display: -webkit-box;
  -webkit-line-clamp: 3;
  -webkit-box-orient: vertical;
  overflow: hidden;
}

/* Variable fonts */
.variable-font {
  font-variation-settings: 'wght' 600, 'wdth' 75;
}
🖊 Exercise 8.1 Easy
Topic: Type System
  1. Build a typographic scale using CSS custom properties: --text-xs through --text-5xl.
  2. Implement fluid headings with clamp() for all h1–h4.
  3. Create a blog article layout with comfortable line-length (~65ch) and line-height.
  4. Style a card component with truncated title (1 line) and clamped description (3 lines).
09

Colors & Backgrounds

CSS
css — color formats
/* All ways to express color */
.color-examples {
  color: red;                       /* Named */
  color: #ff0000;                   /* Hex */
  color: #f00;                      /* Hex shorthand */
  color: rgb(255, 0, 0);            /* RGB */
  color: rgba(255, 0, 0, 0.5);      /* RGBA with alpha */
  color: rgb(255 0 0 / 50%);        /* Modern RGB syntax */
  color: hsl(0deg 100% 50%);        /* HSL (hue saturation lightness) */
  color: hsl(0deg 100% 50% / 0.7); /* HSL with alpha */
  color: oklch(60% 0.2 30);          /* Modern: perceptually uniform */
  color: currentColor;               /* Inherits from parent color */
  color: transparent;
}

/* Backgrounds */
.bg-examples {
  background-color: #f5f5f5;

  /* Linear gradient */
  background: linear-gradient(135deg, #667eea, #764ba2);

  /* Radial gradient */
  background: radial-gradient(circle at 30% 50%, #4f9eff, #0a0d14);

  /* Conic gradient */
  background: conic-gradient(from 0deg, red, yellow, green, red);

  /* Multiple backgrounds (first is on top) */
  background:
    url(overlay.png) no-repeat center,
    linear-gradient(#000, #333);

  /* Image properties */
  background-size:     cover | contain | 300px | 50%;
  background-position: center | top right | 50% 50%;
  background-repeat:   no-repeat | repeat-x | repeat-y;
  background-attachment: fixed | scroll | local;  /* Parallax! */
  background-clip:     border-box | padding-box | text;
}
10

Spacing & Sizing Units

CSS
UnitRelative toBest used for
pxScreen pixelBorders, shadows, fine-tuned details
remRoot font-size (16px)Typography, consistent spacing
emCurrent element font-sizePadding/margins that scale with text
%Parent elementFluid widths, responsive layouts
vw / vhViewport width/heightFull-screen sections, fluid type
vmin / vmaxSmaller/larger viewport dimensionResponsive icons, squares
dvh / svh / lvhDynamic/small/large viewport heightMobile browser chrome fix
chWidth of "0" characterText column width (~65ch optimal)
frFraction of free space (Grid only)Grid column/row sizing
min-contentSmallest content can beGrid/flex intrinsic sizing
max-contentLargest content naturally isGrid/flex intrinsic sizing
fit-contentShrinks but not below min-contentButtons, inline blocks

Logical Properties (Modern Approach)

💡 Use Logical Properties
Logical properties adapt to writing direction (RTL, vertical text). Use them for international apps.
css — logical properties
.logical {
  /* Physical → Logical */
  margin-topmargin-block-start;
  margin-bottommargin-block-end;
  margin-leftmargin-inline-start;
  margin-rightmargin-inline-end;

  /* Shorthand */
  margin-block:  16px;        /* top + bottom */
  margin-inline: 24px;        /* left + right */

  widthinline-size;
  heightblock-size;
}

11

Flexbox

CSS

Flexbox is a one-dimensional layout system. Use it for rows or columns, navigation bars, button groups, centering, and card rows.

css — flexbox complete
/* ─── CONTAINER ─── */
.flex-container {
  display:         flex;
  flex-direction:  row | row-reverse | column | column-reverse;
  flex-wrap:       nowrap | wrap | wrap-reverse;
  flex-flow:       row wrap;          /* Shorthand */
  gap:             16px;              /* Space between items */
  column-gap:      20px;
  row-gap:         12px;

  /* Alignment on main axis (row = horizontal) */
  justify-content: flex-start | flex-end | center
                 | space-between | space-around | space-evenly;

  /* Alignment on cross axis (row = vertical) */
  align-items:     stretch | flex-start | flex-end
                 | center | baseline;

  /* Multi-line cross-axis alignment */
  align-content:   flex-start | flex-end | center
                 | space-between | space-around | stretch;
}

/* ─── ITEMS ─── */
.flex-item {
  flex-grow:   1;       /* Grow to fill space (0 = don't grow) */
  flex-shrink: 0;       /* Don't shrink below basis (1 = shrink) */
  flex-basis:  200px;   /* Starting size before grow/shrink */
  flex:        1 1 auto; /* Shorthand: grow shrink basis */
  flex:        1;        /* = 1 1 0 */
  flex:        auto;     /* = 1 1 auto */
  flex:        none;     /* = 0 0 auto (rigid) */

  order:       2;         /* Reorder visually (default 0) */
  align-self:  center;   /* Override container align-items */
}

/* ─── COMMON PATTERNS ─── */
/* Perfect centering */
.center { display: flex; place-items: center; }

/* Push last item to end */
.nav { display: flex; }
.nav .logo { margin-inline-end: auto; }

/* Equal-width columns */
.cols > * { flex: 1; }
🖊 Exercise 11.1 Medium
Topic: Flexbox Layouts
  1. Build a navbar: logo on left, nav links in center, CTA button on right — using only flexbox.
  2. Create a card grid where cards are equal height regardless of content length.
  3. Build a sidebar + main content layout using flexbox (sidebar fixed width, content grows).
  4. Create a "holy grail" layout: header, footer, left sidebar, right sidebar, main content — pure flexbox.
12

CSS Grid

CSS

Grid is two-dimensional. Use it for page-level layouts, dashboard grids, magazine-style designs, and any time you need both rows AND columns simultaneously.

css — grid complete
/* ─── CONTAINER ─── */
.grid {
  display: grid;

  /* Explicit columns */
  grid-template-columns: 200px 1fr 2fr;
  grid-template-columns: repeat(4, 1fr);
  grid-template-columns: repeat(auto-fill, minmax(250px, 1fr));

  /* Explicit rows */
  grid-template-rows: auto 1fr auto;

  /* Named areas */
  grid-template-areas:
    "header header header"
    "sidebar main aside"
    "footer footer footer";

  gap: 20px 16px;      /* row-gap column-gap */

  /* Implicit rows (auto-generated) */
  grid-auto-rows:    minmax(100px, auto);
  grid-auto-columns: 200px;
  grid-auto-flow:    row | column | dense;

  /* Alignment */
  justify-items:   start | end | center | stretch;
  align-items:     start | end | center | stretch;
  place-items:     center;   /* Shorthand for both */
  justify-content: start | end | center | space-between | space-around;
  align-content:   start | end | center | space-between;
}

/* ─── ITEMS ─── */
.header { grid-area: header; }
.sidebar { grid-area: sidebar; }
.main    { grid-area: main; }

/* Manual placement */
.feature {
  grid-column: 1 / 3;   /* Start line / end line */
  grid-column: 1 / -1;  /* Span full width */
  grid-column: span 2;   /* Span 2 columns */
  grid-row:    1 / 3;
  justify-self: center;
  align-self:   end;
}

auto-fill vs auto-fit

auto-fill
Creates as many columns as will fit, even if empty. Grid tracks exist even without content. Leaves empty space on the right.
auto-fit
Same as auto-fill but collapses empty tracks. Items stretch to fill the full width. Usually what you want for card grids.
🖊 Exercise 12.1 Hard
Topic: Grid Mastery
  1. Build a magazine-style layout: large featured article spanning 2 columns, 3 smaller articles below, sidebar on right — using named grid areas.
  2. Create a responsive image gallery using auto-fit + minmax(). Images should reflow automatically at any screen width.
  3. Build a Kanban board (3 columns: Todo, In Progress, Done) with CSS Grid. Each column is a grid with grid-auto-rows.
  4. Use grid-auto-flow: dense to fill gaps in an irregular card grid.
13

Positioning

CSS
css — positioning
/* static — default, flows normally */
.static { position: static; }

/* relative — offset FROM its natural position, creates stacking context */
.relative {
  position: relative;
  top: 10px; left: 20px;
}

/* absolute — removed from flow, positioned relative to nearest positioned ancestor */
.absolute {
  position: absolute;
  top: 0; right: 0;
  inset: 0;              /* Shorthand: top right bottom left */
}

/* fixed — relative to viewport, stays during scroll */
.fixed-header {
  position: fixed;
  top: 0; left: 0; right: 0;
  z-index: 1000;
}

/* sticky — scrolls with page until threshold, then sticks */
.sticky-nav {
  position: sticky;
  top: 0;             /* Required! */
  z-index: 100;
}

/* z-index — controls stacking order within same stacking context */
.modal-overlay { z-index: 1000; }
.modal         { z-index: 1001; }
.tooltip       { z-index: 2000; }
⚠ Stacking Context
opacity < 1, transform, filter, will-change, isolation: isolate all create new stacking contexts. This is why your z-index sometimes "doesn't work" — the element is in a different context.
14

Responsive Design

CSS

Media Queries

css — responsive
/* Mobile-first approach — base styles, then larger screens */
.container { width: 100%; padding: 0 16px; }

@media (min-width: 640px)  { /* sm */ }
@media (min-width: 768px)  { /* md */ }
@media (min-width: 1024px) { /* lg */ }
@media (min-width: 1280px) { /* xl */ }
@media (min-width: 1536px) { /* 2xl */ }

/* Feature queries */
@supports (display: grid) {
  .container { display: grid; }
}

/* User preferences */
@media (prefers-color-scheme: dark) {
  :root { --bg: #0a0a0a; --text: #fff; }
}
@media (prefers-reduced-motion: reduce) {
  *, *::before, *::after { animation-duration: 0.01ms !important; }
}
@media (prefers-contrast: high) {
  :root { --border: #fff; }
}

/* Container queries (game changer!) */
.card-wrapper { container-type: inline-size; container-name: card; }

@container card (min-width: 400px) {
  .card { flex-direction: row; }
}
🖊 Exercise 14.1 Medium
Topic: Responsive Design
  1. Build a product grid that shows 1 column on mobile, 2 on tablet, 4 on desktop — mobile-first.
  2. Implement a hamburger nav that collapses below 768px using only CSS (checkbox hack or :has()).
  3. Add a prefers-color-scheme dark mode implementation using CSS custom properties.
  4. Use container queries to make a card component adapt based on its parent width, not viewport.

15

CSS Variables & Cascade

CSS
css — custom properties system
/* Define on :root for global access */
:root {
  /* Color system */
  --color-primary:    oklch(65% 0.18 250);
  --color-primary-10: oklch(65% 0.18 250 / 10%);

  /* Space scale */
  --space-1: 4px;
  --space-2: 8px;
  --space-4: 16px;
  --space-8: 32px;

  /* Animation */
  --ease-out: cubic-bezier(0, 0, 0.2, 1);
  --duration-fast:   150ms;
  --duration-normal: 300ms;
}

/* Use a variable */
.btn {
  background: var(--color-primary);
  padding: var(--space-2) var(--space-4);

  /* Fallback value */
  color: var(--text-color, white);
}

/* Scoped variables (override per component) */
.theme-dark {
  --color-primary: oklch(70% 0.2 250);
}

/* Computed with calc() */
.responsive-pad {
  --base: 16px;
  padding: calc(var(--base) * 2);
}

/* CSS Layers — explicit cascade control */
@layer reset, base, components, utilities;

@layer reset {
  * { margin: 0; padding: 0; }
}
@layer components {
  .btn { padding: 8px 16px; }
}
@layer utilities {
  .mt-4 { margin-top: 16px !important; } /* OK in utilities layer */
}
16

Transforms & Transitions

CSS
css — transforms
/* 2D Transforms */
.transform-2d {
  transform: translateX(50px);
  transform: translateY(-20%);
  transform: translate(50px, 20px);
  transform: scale(1.5);
  transform: scaleX(0.5);
  transform: rotate(45deg);
  transform: skew(10deg, 5deg);
  /* Chain multiple transforms */
  transform: rotate(45deg) scale(1.2) translateX(10px);

  /* Transform origin */
  transform-origin: top left | center | 50% 50%;
}

/* 3D Transforms */
.parent-3d { perspective: 1000px; } /* Required on parent */
.card-3d   {
  transform-style: preserve-3d;
  transform: rotateY(30deg) rotateX(15deg);
  backface-visibility: hidden; /* For flip animations */
}

/* Individual transform properties (modern — compositable!) */
.compositable {
  translate: 50px 20px;
  rotate:    45deg;
  scale:     1.5;
}

/* Transitions */
.smooth {
  transition: all 300ms ease;        /* Avoid "all" in production */
  transition: transform 250ms cubic-bezier(0.34, 1.56, 0.64, 1),  /* Spring */
              opacity 200ms ease,
              background-color 150ms ease;
  transition-delay: 100ms;
}
.smooth:hover {
  transform: translateY(-4px) scale(1.02);
}

/* Only animate compositor-friendly properties for 60fps */
/* ✅ opacity, transform, filter (GPU-accelerated) */
/* ❌ width, height, margin, top, left (causes layout reflow) */
17

Animations & Keyframes

CSS
css — keyframe animations
/* Define keyframes */
@keyframes fadeSlideIn {
  from {
    opacity: 0;
    transform: translateY(20px);
  }
  to {
    opacity: 1;
    transform: translateY(0);
  }
}

@keyframes pulse {
  0%, 100% { transform: scale(1); }
  50%       { transform: scale(1.05); }
}

@keyframes spin {
  to { transform: rotate(360deg); }
}

/* Apply animation */
.animated {
  animation-name:            fadeSlideIn;
  animation-duration:        400ms;
  animation-timing-function: ease-out;
  animation-delay:           100ms;
  animation-iteration-count: 1 | infinite;
  animation-direction:       normal | reverse | alternate | alternate-reverse;
  animation-fill-mode:       both; /* Retain final state */
  animation-play-state:      running | paused;

  /* Shorthand */
  animation: fadeSlideIn 400ms ease-out 100ms both;
}

/* Staggered animations with delay */
.list-item:nth-child(1) { animation-delay: 0ms;   }
.list-item:nth-child(2) { animation-delay: 80ms;  }
.list-item:nth-child(3) { animation-delay: 160ms; }

/* View Transitions API (native page transitions!) */
@view-transition { navigation: auto; }
::view-transition-old(root) { animation: slideOut 300ms ease; }
::view-transition-new(root) { animation: slideIn  300ms ease; }
🖊 Exercise 17.1 Medium
Topic: CSS Animations
  1. Create a loading spinner using @keyframes and border + rotate.
  2. Build a skeleton loading screen that pulses — used for content loading states.
  3. Animate a card list so items stagger in on page load (delay each by 80ms).
  4. Build a CSS-only modal with a fade + scale animation on open/close.
  5. Wrap all animations in @media (prefers-reduced-motion: no-preference).
18

Pseudo-classes & Pseudo-elements

CSS
Pseudo-classWhen it applies
:hoverMouse is over the element
:focusElement has keyboard/programmatic focus
:focus-visibleFocus from keyboard only (not mouse click)
:focus-withinElement OR any descendant is focused
:activeBeing clicked/pressed
:visitedLink has been visited (limited styling)
:checkedCheckbox/radio is selected
:disabled / :enabledForm element is disabled/enabled
:required / :optionalForm input has/lacks required attribute
:valid / :invalidInput passes/fails constraint validation
:placeholder-shownPlaceholder is visible (input is empty)
:emptyElement has no children
:rootTop-level element (html)
:targetElement whose id matches URL hash
:is()Matches any of its arguments
:where()Same as :is() but zero specificity
:has()"Parent" selector — has matching descendant
:not()Doesn't match argument
:any-linkAny anchor with href
css — pseudo-elements
/* ::before and ::after — generated content */
.icon-link::after {
  content: " ↗";     /* Required (even empty string "") */
  display: inline-block;
}

/* Decorative element */
.card::before {
  content: "";
  position: absolute;
  inset: -2px;
  background: linear-gradient(#4f9eff, #7c5cfc);
  border-radius: inherit;
  z-index: -1;          /* Gradient border trick */
}

::placeholder  { color: #666; font-style: italic; }
::selection    { background: #4f9eff; color: #fff; }
::first-line   { font-size: 1.1em; font-weight: bold; }
::first-letter { font-size: 3em; float: left; }  /* Drop cap */
::marker       { color: #4f9eff; }               /* List bullet */
::backdrop     { background: rgba(0,0,0,0.5); }  /* <dialog> backdrop */
19

Modern CSS Features

CSS 2024–25
css — cutting edge
/* ─── CSS NESTING (native) ─── */
.card {
  background: var(--surface);

  & .title { font-size: 1.2rem; }     /* .card .title */
  &:hover  { border-color: blue; }     /* .card:hover */

  @media (min-width: 768px) {           /* Nested media query */
    display: flex;
  }
}

/* ─── @scope ─── */
@scope (.card) to (.card .inner) {
  p { color: red; }   /* Only p within .card but outside .inner */
}

/* ─── SCROLL-DRIVEN ANIMATIONS ─── */
.progress-bar {
  animation: grow linear;
  animation-timeline: scroll();       /* Driven by scroll position */
  animation-range: entry 0% cover 100%;
}
@keyframes grow {
  from { transform: scaleX(0); }
  to   { transform: scaleX(1); }
}

/* ─── ANCHOR POSITIONING (popups, tooltips) ─── */
.anchor  { anchor-name: --btn; }
.tooltip {
  position: absolute;
  position-anchor: --btn;
  top: anchor(bottom);
  left: anchor(center);
}

/* ─── color-mix() ─── */
.tinted {
  background: color-mix(in oklch, blue 30%, white);
}

/* ─── math functions ─── */
.math {
  width:  min(100%, 600px);
  height: max(200px, 50vh);
  font-size: clamp(1rem, 2.5vw, 2rem);
  width:  round(nearest, 333px, 50px);  /* 350px */
}

/* ─── @starting-style (enter animations!) ─── */
.popover {
  transition: opacity 300ms, transform 300ms;
  @starting-style {
    opacity: 0;
    transform: translateY(-8px);
  }
}
🖊 Exercise 19.1 Hard
Topic: Modern CSS
  1. Refactor a stylesheet from SASS nesting to native CSS nesting — no preprocessor.
  2. Build a reading progress bar that fills purely with scroll-driven animations.
  3. Use color-mix() to auto-generate lighter/darker variants of a brand color.
  4. Implement a dark mode using light-dark() function and color-scheme property.

20

Accessibility (a11y)

Critical
✅ Accessibility is Not Optional
In many countries accessibility is a legal requirement (ADA, WCAG 2.1 AA in EU). Beyond compliance, accessible sites are faster, more SEO-friendly, and better for all users.

ARIA — Accessible Rich Internet Applications

html — aria patterns
<!-- Labels -->
<button aria-label="Close dialog"></button>
<div aria-labelledby="dialog-title">...</div>
<input aria-describedby="hint-text">

<!-- States -->
<button aria-expanded="false" aria-controls="menu">Menu</button>
<div id="menu" aria-hidden="true">...</div>
<input aria-invalid="true" aria-errormessage="email-error">
<div role="progressbar" aria-valuenow="60" aria-valuemin="0" aria-valuemax="100"></div>

<!-- Live regions — announce dynamic changes -->
<div aria-live="polite" aria-atomic="true">
  Status messages go here
</div>
<div role="alert">Urgent: Your session is expiring.</div>

<!-- Skip navigation link -->
<a href="#main" class="skip-link">Skip to main content</a>
css — accessibility
/* Visually hidden but screen-reader accessible */
.sr-only {
  position: absolute;
  width: 1px; height: 1px;
  padding: 0; margin: -1px;
  overflow: hidden;
  clip: rect(0,0,0,0);
  white-space: nowrap;
  border: 0;
}

/* Focus styles — NEVER remove, only restyle */
:focus-visible {
  outline: 3px solid #4f9eff;
  outline-offset: 3px;
  border-radius: 4px;
}

/* Skip link */
.skip-link {
  position: absolute;
  transform: translateY(-200%);
  z-index: 9999;
}
.skip-link:focus {
  transform: translateY(0);
}

WCAG 2.1 Checklist

CriterionRequirement
Color contrast4.5:1 for normal text, 3:1 for large text (AA level)
Keyboard navAll interactive elements focusable, logical tab order
Focus visibleClear focus indicator on all interactive elements
Alt textAll meaningful images have descriptive alt attributes
Heading hierarchyLogical h1→h6 order, no skipping levels
Form labelsEvery input has associated label
Error messagesClear error messages linked to inputs
Touch targetsMin 44×44px touch target size
Resize textNo loss of content when text zoomed to 200%
Languagelang attribute on <html>
21

Performance

Production
Critical CSS
Inline above-the-fold CSS in <style> to eliminate render-blocking. Load the rest with rel="preload".
🖼
Image Optimization
Use WebP/AVIF formats. Add width/height to prevent CLS. Use loading="lazy" for below-fold images.
🎞
will-change
Hint browser to promote element to GPU layer: will-change: transform. Use sparingly — creates memory overhead.
📦
Content-visibility
content-visibility: auto skips rendering off-screen elements. Massive paint performance gains on long pages.
🔄
Reflows vs Repaints
Avoid changing layout properties (width, height, margin) in JS. Use transform and opacity — GPU-only.
📝
Font Loading
Use font-display: swap to prevent FOIT. Preload critical fonts. Subset fonts to languages needed.
html + css — performance patterns
<!-- Preload critical assets -->
<link rel="preload" as="font" href="font.woff2" crossorigin>
<link rel="preload" as="image" href="hero.webp">
<link rel="modulepreload" href="app.js">

/* Optimize long lists and pages */
.post {
  content-visibility: auto;
  contain-intrinsic-size: 0 300px;  /* Hint for scroll bar sizing */
}

/* GPU compositing for animated elements */
.animated-el {
  will-change: transform;
  contain: layout paint;  /* CSS containment */
}

/* Font performance */
@font-face {
  font-family: 'Brand';
  src: url(brand.woff2) format('woff2');
  font-display: swap;     /* Show fallback, swap when loaded */
  unicode-range: U+0000-00FF;  /* Subset to Latin */
}
22

CSS Architecture

Scalability

Methodologies Comparison

MethodologyIdeaBest for
BEMBlock__Element--Modifier naming. .card__title--largeTeams, component libraries
SMACSSCategorize: Base, Layout, Module, State, ThemeLarge apps
ITCSSInverted Triangle: Settings → Tools → Generic → Elements → Objects → Components → TrumpsDesign systems
Utility-firstOne class = one property. Tailwind CSS approach.Rapid prototyping
CSS ModulesScoped class names, colocation with component filesReact/Vue apps

Design Token System

css — token system
/* 3 tiers: Primitive → Semantic → Component */

/* Tier 1: Raw values */
:root {
  --blue-500: #3b82f6;
  --blue-600: #2563eb;
  --space-4:  16px;
}

/* Tier 2: Semantic meaning */
:root {
  --color-action:    var(--blue-500);
  --color-action-hv: var(--blue-600);
  --space-component: var(--space-4);
}

/* Tier 3: Component-specific */
.btn {
  --btn-bg:      var(--color-action);
  --btn-bg-hv:   var(--color-action-hv);
  --btn-padding: var(--space-component);

  background: var(--btn-bg);
  padding: calc(var(--btn-padding) / 2) var(--btn-padding);
}

/* Override just the component token for variants */
.btn-danger { --btn-bg: var(--red-500); }
🖊 Exercise 22.1 Hard
Topic: CSS Architecture
  1. Build a complete design token system for a SaaS app: colors (primitive + semantic), spacing scale, type scale, border-radius, shadow levels.
  2. Create a button component with 4 variants (primary, secondary, ghost, danger) and 3 sizes using only CSS custom properties — no modifier classes that duplicate rules.
  3. Structure a stylesheet using ITCSS — 7 layers, at least 2 files per layer concept.
  4. Implement a theme switcher (light/dark/high-contrast) using CSS layers and custom properties only, no JS class toggling.

Final Projects

Portfolio Quality

Build these in order. Each project combines multiple concepts and is production-portfolio worthy. Time estimates assume a solid understanding of the sections above.

🏗 Project 1: Personal Portfolio Beginner
Covers: Semantic HTML · Responsive Design · Typography · Animations · Accessibility
  1. Build a full personal portfolio site: hero section, about, skills grid, projects, contact form.
  2. Semantic HTML throughout — passes Lighthouse accessibility 90+.
  3. Fully responsive from 320px to 2560px using mobile-first media queries.
  4. Smooth scroll with scroll-behavior. Sticky header with blur backdrop-filter.
  5. Custom ::selection color and styled scrollbar.
  6. All animations respect prefers-reduced-motion.
  7. Dark/light mode toggle using CSS custom properties + localStorage.
🏗 Project 2: Blog / Article Site Beginner
Covers: Typography · Semantic HTML · Forms · Grid · Responsive
  1. Create an article page with a proper typographic hierarchy: drop cap, pull quotes, code blocks, figure captions.
  2. Related posts grid: auto-fill + minmax, each card has hover lift animation.
  3. Sidebar with sticky positioning that stays visible while scrolling article.
  4. Reading progress bar using scroll-driven animations or JS + CSS variables.
  5. Newsletter signup form with custom validation styles (:valid/:invalid).
🏗 Project 3: SaaS Landing Page Intermediate
Covers: Grid · Flexbox · Animations · CSS Variables · Positioning · Performance
  1. Hero section: gradient background mesh, animated CTA button, floating badges with keyframes.
  2. Features grid: 3-column on desktop, 2 on tablet, 1 on mobile.
  3. Pricing cards: CSS Grid + :has() to highlight selected plan.
  4. Testimonial slider: CSS-only using scroll-snap and overscroll-behavior.
  5. FAQ section with native <details>/<summary> + custom animated arrow.
  6. Performance: Critical CSS inline, image lazy loading, font-display swap, LCP <2.5s.
🏗 Project 4: Dashboard UI Intermediate
Covers: CSS Grid · Flexbox · Custom Properties · Advanced Selectors · a11y
  1. Collapsible sidebar + main layout using CSS Grid. Sidebar toggles with a CSS variable --sidebar-width.
  2. Stats cards with animated counters (CSS only using @property and counter() trick).
  3. Data table with sticky header, zebra rows, sortable column indicator styling.
  4. Notification dropdown using :popover API (popover attribute + CSS ::backdrop).
  5. Full keyboard navigation — every interactive element reachable and clear focus styling.
  6. Container queries on cards: compact when sidebar open, expanded when closed.
🏗 Project 5: E-Commerce Product Page Intermediate
Covers: Forms · Images · Grid · Animations · CSS Custom Properties
  1. Product image gallery with thumbnail row and main image — CSS Grid. Zoom on hover with transform + overflow hidden.
  2. Color/size selectors: radio inputs completely restyled with CSS — no JS, full accessibility.
  3. Quantity stepper: custom styled number input with +/– buttons.
  4. Product reviews: star rating system built purely with CSS (reversed flex and :checked).
  5. Sticky "Add to Cart" bar that appears on scroll using position: sticky + :has().
  6. Responsive: product image above description on mobile, side-by-side on desktop.
🏗 Project 6: CSS Art / Animation Showcase Intermediate
Covers: Keyframes · Transforms · Pseudo-elements · Clip-path · Filters
  1. Build a loading screen: animated logo using clip-path and SVG stroke-dashoffset.
  2. CSS-only card flip animation (3D transform, backface-visibility).
  3. Neon glow button using box-shadow layers and CSS animation.
  4. Animated gradient text using background-clip: text and keyframe hue-rotate.
  5. Pure CSS progress stepper with connecting lines using ::before pseudo-elements.
  6. Page transition system using View Transitions API.
🏗 Project 7: UI Component Library Advanced
Covers: CSS Architecture · Design Tokens · Accessibility · All CSS Features
  1. Create a complete component library: buttons (variants + sizes), badges, alerts, cards, modals, dropdowns, tabs, toasts, accordions, tooltips, progress bars, spinners.
  2. All components built with 3-tier token system. No hardcoded values.
  3. Full light and dark theme. Each component respects prefers-color-scheme.
  4. Comprehensive keyboard navigation on all interactive components.
  5. All components meet WCAG 2.1 AA — verified with axe DevTools.
  6. Build an HTML living style guide that documents every component with code examples.
🏗 Project 8: Full Website Clone + Improve Advanced
Covers: Everything · Production Quality
  1. Choose a real-world website (Stripe, Linear, Vercel, Notion) and rebuild its homepage from scratch.
  2. Modern HTML: semantic structure, Open Graph, schema.org JSON-LD markup.
  3. Improve on the original: better accessibility score, reduced motion support, container queries.
  4. Target Core Web Vitals: LCP <2.5s, CLS <0.1, FID <100ms. Verify with Lighthouse.
  5. Write a 500-word post-mortem: what CSS decisions you made and why.