DOMAIN
A game made of real web pages

Learn to build the webby walking through it.

Every level is a live HTML document. The browser lays it out, and each element becomes a block you can stand on. The page starts broken — fix the code, and the ground rearranges under your feet.

120
lessons
4
chapters
1
real website
style.cssChange a value →
.path {
  display: flex;
  flex-direction: row;
  justify-content: flex-start;
  gap: 8px;
}
flex-direction
justify-content
gap
start
goal
<div class="path">
In a lesson, these blocks are what you walk on. Move them into a wall and you can't cross; line them up and you can.
<section class="how">

The browser is the rules engine

Nothing about CSS is simulated. The page is measured with getBoundingClientRect, so if the browser renders it, the world matches it — flex, grid, position, the lot.

Broken until your code says otherwise

A bridge too short, a gate that won't open, stairs in the wrong order. The fix is the lesson, and the world tells you the moment the way is open.

You leave with a real website

Every lesson adds a piece to the Anthill Bakery: content from HTML, style from CSS, layout from flexbox, life from JavaScript.

<ol class="course">
The course, in order

Four chapters, 120 lessons

Each lesson: one idea, an annotated example, five hints when you want them, and a level you can only cross once the code is right.

  1. 01 · HTML20

    The Builder Who Wrote Things Down

    Write HTML elements, name them with attributes, and nest them — then use the real tags of the web: semantic sections, headings, lists, links, images, forms and tables.

    <div>classnestingdiv / span+16
  2. 02 · CSS38

    The Tailor of Stone

    Write real CSS: selectors and the cascade, the box model, units, positioning, colour, typography, motion and variables — the whole toolkit, not just one rule.

    widthmargintype / class / id s…descendant vs child…+34
  3. 03 · Flexbox12

    The Conveyor of Ants

    Really know flexbox: the container/item split, both axes, every alignment and sizing property, the classic gotchas, the everyday patterns, and when to reach for Grid instead.

    container vs itemdisplay: flexflex-directionflex-wrap+8
  4. 04 · JavaScript50

    The Hands That Reach

    Really write JavaScript: values and types, control flow, functions and closures, arrays and objects, the DOM and events, async code with fetch, modules, debugging — and the tools worth knowing exist.

    let, const, and why…string, number, boo…objects and arrays …== vs ===, coercion…+46
<section id="build">
Build a real website as you play

Anthill Bakery

Every lesson you finish adds a piece to a real website. It starts as a blank page. HTML gives it content, CSS gives it style, flexbox arranges it, and JavaScript brings it to life.

  • HTML adds the content · 20 pieces
  • CSS styles it · 38 pieces
  • Flexbox lays it out · 12 pieces
  • JavaScript makes it respond · 50 pieces
Anthill Bakery — tiny bakes, big crumbs anthill.bakery
What you'll have built
<nav class="map">
Every lesson, one chart

The map

Scroll, drag, or use the arrows
CHAPTER 1 · HTMLThe Meadow of ElementsCHAPTER 2 · CSSThe Tailor's DunesCHAPTER 3 · FLEXBOXThe Conveyor CanyonCHAPTER 4 · JAVASCRIPTThe Crystal ReachesYour First Element — <div>1<div>Names Give Things Shape — class (locked)classBoxes Inside Boxes — nesting (locked)nestingA Box of Its Own — div / span (locked)div / spanThe Watchtower — semantic tags (locked)semantic tagsThe Keystone — id / class (locked)id / classThe Sleeping Drawbridge — data-* (locked)data-*The Order of Voices — headings (locked)headingsThe Scroll of Notes — <p> (locked)<p>The Unspoken Word — strong / em (locked)strong / emThe Numbered Trail — ul / ol / li (locked)ul / ol / liThe Open Door — a href (locked)a hrefThe Unlatched Door — target / rel (locked)target / relThe Framed Picture — <img> (locked)<img>The Control Room — form controls (locked)form controlsThe Locked Gate — required (locked)requiredThe Tile Bridge — table structure (locked)table structureThe Scroll of the Head — the <head> (locked)the <head>The Unseen Picture — accessibility: alt text (locked)accessibility: …The Final Gate — putting it together (locked)putting it toge…Your First CSS Rule — width (locked)widthSpace Outside the Box — margin (locked)marginChoose the Right Selector — type / class / id selectors (locked)type / class / …Inside, or Directly Inside? — descendant vs child (>) combinator (locked)descendant vs c…One Rule, Several Selectors — grouping selectors (,) (locked)grouping select…The Ends of the Line — :first-child / :last-child (locked):first-child / …Counting Down the Row — :nth-child() (locked):nth-child()Everyone Except One — :not() (locked):not()The Latch — :checked (locked):checkedWhere Attention Lands — :focus (locked):focusContent From Nowhere — ::before / ::after (locked)::before / ::af…Whose Rule Wins — specificity & the cascade (locked)specificity & t…What Passes Down — inheritance, inherit / initial / unset (locked)inheritance, in…The Rule That Cheats — !important (locked)!importantWhat Width Actually Measures — box-sizing (locked)box-sizingRoom to Grow, a Limit Not to Cross — min-width / max-width (locked)min-width / max…When Two Gaps Become One — margin collapsing (locked)margin collapsi…Block, Inline, or Gone — display (locked)displayPixels, Percent, and the Letter M — px / % / em / rem (locked)px / % / em / r…Sized to the Screen Itself — vw / vh (locked)vw / vhArithmetic Inside a Value — calc() (locked)calc()A Size With Guardrails — clamp() / min() / max() (locked)clamp() / min()…Every Way to Write a Colour — hex / rgb() / hsl() / alpha (locked)hex / rgb() / h…Nudged, Not Removed — position: relative (locked)position: relat…Whose Corner Is Zero — position: absolute & the containing block (locked)position: absol…Stuck to the Screen, or Stuck at a Line — position: fixed vs sticky (locked)position: fixed…Which Layer Sits on Top — z-index & stacking contexts (locked)z-index & stack…What Happens at the Edge — overflow (locked)overflowRows and Columns at Once — CSS Grid basics (locked)CSS Grid basicsFaded, Hidden, or Gone — opacity vs visibility vs display (locked)opacity vs visi…Painting the Surface — background-image, size, position, repeat (locked)background-imag…Softening the Edges — border-radius, box-shadow (locked)border-radius, …A Colour That Changes Along Its Length — linear-gradient() (locked)linear-gradient…A Sign Anyone Can Read — font-family, font-size, font-weight, line-height (locked)font-family, fo…One Tidy Line — text-align, text-overflow: ellipsis (locked)text-align, tex…A Value You Can Reuse — CSS custom properties (variables) (locked)CSS custom prop…The Gate That Answers — transition, transform, :target (locked)transition, tra…The Tailor's Masterwork — putting it together (locked)putting it toge…Two Kinds of Property — container vs item (locked)container vs it…Stand in a Line — display: flex (locked)display: flexThe Tower — flex-direction (locked)flex-directionBreak the Line — flex-wrap (locked)flex-wrapThe Huddle — justify-content (locked)justify-contentThe Hanging Stairs — align-items (locked)align-itemsRoom Between the Rows — align-content (locked)align-contentThe Unbridgeable Void — gap (locked)gapThe Growing Bridge — flex-grow / flex-shrink / flex-basis (locked)flex-grow / fle…One Item, Its Own Rules — align-self / order (locked)align-self / or…The Item That Wouldn't Shrink — min-width: auto (locked)min-width: autoThe Builder's Toolkit — real patterns, and when to reach for Grid (locked)real patterns, …A Name That Can't Change — let, const, and why not var (locked)let, const, and…What Kind of Thing Is It? — string, number, boolean, null, undefined, symbol, bigint (locked)string, number,…Two Names, One Object — objects and arrays are references (locked)objects and arr…Loosely Equal, Strictly Wrong — == vs ===, coercion, truthy and falsy (locked)== vs ===, coer…Words With Holes in Them — template literals (locked)template litera…The Operator's Toolkit — arithmetic, comparison, logical, ??, ?., ternary (locked)arithmetic, com…The Gearbox — if / else and switch (locked)if / else and s…In, Of, and Around Again — for, for...of, for...in, while (locked)for, for...of, …Skip It, Don't Stop — break and continue (locked)break and conti…Called Too Soon — function declarations vs expressions, hoisting (locked)function declar…The Arrow That Forgot to Return — arrow functions and how they differ (locked)arrow functions…Measure Twice — parameters, defaults, rest, return (locked)parameters, def…Out of Reach — global, function and block scope (locked)global, functio…The Counter That Remembers — closures (locked)closuresWho Is This? — this and the call-site (locked)this and the ca…Hand Over the Instructions — callbacks and higher-order functions (locked)callbacks and h…The Brick Pile — arrays: indexing, push, pop, shift, unshift (locked)arrays: indexin…Cut, Don't Tear — splice vs slice (locked)splice vs sliceChoose, Change, Place — map, filter, forEach (locked)map, filter, fo…Add It All Up — reduce (locked)reduceThe Right Buoy — find, findIndex, some, every, includes (locked)find, findIndex…Alphabetical Numbers — sort and its gotchas (locked)sort and its go…Copy, Don't Carve — spread, array destructuring, immutability (locked)spread, array d…Dot or Bracket — properties, dot vs bracket, methods (locked)properties, dot…Unpack With New Names — object destructuring, renaming, defaults (locked)object destruct…The Shallow Copy — spread, Object.assign, shallow vs deep copy (locked)spread, Object.…The Gem Ledger — Object.keys, values, entries (locked)Object.keys, va…Missing Pieces — optional chaining on nested data (locked)optional chaini…Written Down, Read Back — JSON.parse and JSON.stringify (locked)JSON.parse and …Find Them All — querySelector and querySelectorAll (locked)querySelector a…The Visitor Who Wrote Code — textContent, innerHTML, and XSS (locked)textContent, in…The Locked Gate — classList: add, remove, toggle, contains (locked)classList: add,…Units and Attributes — setting style and attributes (locked)setting style a…Out of the Box — createElement, append, remove, traversal (locked)createElement, …Read the Form — form values and reading input (locked)form values and…Which Lever Was It? — addEventListener, the event object, common events (locked)addEventListene…Don't Follow the Link — preventDefault and stopPropagation (locked)preventDefault …One Listener for Many — bubbling and event delegation (locked)bubbling and ev…The Alarm That Won't Stop — removing event listeners (locked)removing event …Later Means Later — the event loop, setTimeout and setInterval (locked)the event loop,…A Promise of a Bridge — Promises: then, catch, finally (locked)Promises: then,…Await Your Turn — async/await and try/catch (locked)async/await and…All or Settled — Promise.all and friends (locked)Promise.all and…Ask the Server — fetch: GET and POST, headers, body, status (locked)fetch: GET and …Stuck on Loading — loading and error UI states (locked)loading and err…Named or Default — import/export, script type="module", npm, bundlers (locked)import/export, …Remember Me — localStorage, sessionStorage, console methods (locked)localStorage, s…Read the Error — DevTools debugger, stack traces, common errors (locked)DevTools debugg…Blueprints for Orbs — classes, extends, prototypes (locked)classes, extend…The Toolbox's Bottom Drawer — Map, Set, regular expressions, dates, strict mode (locked)Map, Set, regul…
The Old Ant

“Nobody learns to build by watching. Write one line, see what it does, then write the next.”

Start from zero

Free, no account needed. Progress saves in this browser.