→ From Coder to Shipper
From Coder to Shipper · Frontend

Frontend — HTML · CSS · Bootstrap · JS

The browser side of the web, in one mental model. AI will write these files for you — this deck is the map so you can read them, judge them and fix them.

← / → to navigate · EN/VI switch below

Big picture

A web page = three jobs

Every page you've used — shop, dashboard, bank app — splits its work into these three files.

HTML — structure & content

The words, images, buttons and their order. The skeleton, and the stuff inside it.

CSS — style & layout

Colours, spacing, where things sit. Turns a plain stack of boxes into a designed page.

JS — behavior

What happens when you click, type or scroll. The page stops being a picture and starts reacting.

Big picture

How a page gets to your screen

The frontend is the client side. The server's job ends the moment it hands over three kinds of files — everything after happens in your browser.

1 · Server

Sends the page as plain files: HTML + CSS + JS.

2 · Browser

Parses the HTML into a tree, applies the CSS, runs the JS.

3 · You

See painted pixels — and click them. The frontend is everything between the server and your eyes.

server ──(html · css · js)──▶ browser ──(pixels)──▶ your eyes

Big picture · the loop

What happens when you open a URL

Four beats. After beat 3 the page is alive in your browser — and beat 4 repeats on every click.

  1. 1

    You open a URL

    Your browser asks a server: 'give me this page'.

  2. 2

    Server answers with files

    It sends HTML + CSS + JS. The whole answer is just text files.

  3. 3

    Browser builds the page

    HTML becomes a tree of elements, CSS paints and places them, JS starts running.

  4. 4

    You click — the loop repeats

    JS reacts on the spot; for new data it can ask the server again (an API call) — no reload.

Big picture · your role

The AI writes. You steer.

This deck is that map — recognize, judge, fix.

What AI gives you

Working files: HTML with real structure, CSS that looks professional, JS that reacts. You'll rarely type these by hand.

What you do

Read the structure, judge the design, test the behavior. You need the map — not a driver's license.

The next four dividers are the map itself: HTML, CSS, Bootstrap, JS.

01
Part 1

HTML — the skeleton

Tags with meaning, nested into a tree. The only file that decides what a page IS.

HTML · anatomy

A whole page, 11 lines

Two halves: <head> is metadata and links (invisible), <body> is everything you can see.

index.html
<!doctype html>
<html>
  <head>                      ← invisible: title, CSS links
    <title>My page</title>
    <link rel="stylesheet" href="style.css">
  </head>
  <body>                      ← everything the user sees
    <h1>Hello, world</h1>
    <p>This is the first paragraph.</p>
    <p id="status"></p>
  </body>
</html>
Live — try it

Hello, world

This is the first paragraph.

click me — I can be edited

Right side is the live render of this exact page — click the status line, it becomes editable. Tags come in pairs: <h1>…</h1>.

HTML · how it works

Three rules — that's the whole syntax

HTML has almost no syntax. Keep these three and you can read any page.

Tags come in pairs

<div> opens, </div> closes. Whatever sits between is the tag's content.

Tags nest into a tree

Tags inside tags, always closed properly. The nesting order IS the page's structure.

Attributes add details

Extra info inside the opening tag: <a href="/shop">. href says where the link goes.

HTML · vocabulary

The tags you'll recognize everywhere

You don't need to memorize HTML — you need to recognize it when you (or your AI) read it.

TagWhat it does
h1 – h6Headings, big → small. One h1 per page, the rest is structure.
p · a · imgParagraph · link · image — the three content workhorses.
div · spanGeneric containers — meaning-less boxes you wrap things in.
ul / liA bulleted list and its items.
button · input · formThe interactive trio: press it · type in it · send it.
nav · header · main · footerThe standard zones of a page: menu · top · content · bottom.
HTML · example

A menu bar, in plain HTML

A logo, a list of links, a button. No CSS yet — just structure.

navbar.html
<nav>
  <a class="logo">MyShop</a>
  <ul>
    <li><a href="/shop">Shop</a></li>
    <li><a href="/about">About</a></li>
  </ul>
  <button>Log in</button>
</nav>
Live — try it

Right side is live — click Shop, About or Log in and the click is reported inline. Every menu bar you've seen is some version of this <nav>.

HTML · the page skeleton

A typical page, as a tree

Almost every web app you've used has this exact shape: bar on top, rail on the left, content in the middle.

layout.html
<body>
├── <nav>          menu bar — logo, links, 'login'
├── <div class="layout">
│   ├── <aside>    sidebar — filters, sub-menu
│   └── <main>     content — what the page is about
└── <footer>       links, copyright

# every element above is just a <div> or its friends —
# the layout you see is CSS placed on this tree

Read this tree top to bottom and you can name almost any admin dashboard's structure.

HTML · UI elements

Common UI — what it's really made of

Recognize the pattern, don't master the syntax. Most 'fancy' UI is plain HTML wearing CSS.

Button

A <button>, or an <a> styled to look like one. One element, one job.

Toggle / switch

An <input type='checkbox'> styled into a switch — or a button that flips a CSS class.

Date picker

An input plus a JS popup. The calendar itself is just a grid of tiny buttons.

Carousel

A row of <img> in a flexbox; JS decides which slide you're looking at.

Card (image + text)

<img> + <div> + a border. 'Card' is a nickname for a styled box.

Form

Inputs inside a <form>, plus one <button type='submit'>. The submit button is the whole point.

HTML · example

A login form, 7 elements

The most common UI on the web: a field to type in, and a button to send it.

login.html
<form>
  <label>Email</label>
  <input type="email" placeholder="you@example.com">

  <label>Password</label>
  <input type="password">

  <button type="submit">Log in</button>
</form>
Live — try it

Right side is live — hit Log in and the form reports back (JS would intercept it here). Each <label> describes the <input> next to it.

HTML · naming

id vs class — two ways to name an element

id — a unique name

#status addresses exactly one element on the page. Like a house number: one per address.

class — a shared badge

class="card" can sit on 50 elements at once. Like a team badge. Bootstrap works entirely with these.

CSS and JS use these same names to find elements — the first place all three files meet.

HTML · why it matters

Semantic tags carry meaning, not just shape

<div> means nothing. <nav>, <main>, <article> say what a region IS.

For people & screen readers

Screen-reader users navigate by landmarks: they jump straight to <main> and skip the menus.

For search engines

Search engines read meaning to index pages. Semantic HTML is free SEO.

For you & your AI

AI reads semantic markup far better than a soup of <div>s — and so will future-you, three months later.

HTML · example

A product card, in plain HTML

Every card on the web — product, profile, post — is this shape: image on top, title, text, action.

card.html
<div>
  <img src="product.jpg" alt="Espresso machine">
  <h3>Espresso Machine</h3>
  <p>Pulls a proper shot at home.</p>
  <button>Add to cart</button>
</div>
Live — try it
Espresso machine

Espresso Machine

Pulls a proper shot at home.

Right side is the live card — click Add to cart. This exact markup becomes a Bootstrap card next, just by adding class names.

HTML · judging & fixing

The HTML mistakes worth catching

The bugs AI (and humans) still ship. You don't have to find every one — just recognize these four.

Unclosed / mismatched tags

<div>…</span> — the tree breaks, and the layout goes haywire below it.

Duplicate ids

Two elements with id="status" — JS grabs the first, so updates land in the wrong place.

Missing alt on images

Screen readers hear nothing. Every <img> needs an alt="…" describing it.

Dead buttons & links

A button with no click handler, a link to "" — the page looks finished and does nothing.

02
Part 2

CSS — style & layout

CSS answers two questions: what does it look like, and where does it sit?

CSS · the box model

Everything on a page is a box

Every element is a rectangle with four concentric rings. This one mental model explains most of CSS.

Content

The text or image itself — the innermost ring.

Padding

Space between the content and the border. Breathing room, still inside the box.

Border

The line around it. Also where border-radius (rounded corners) lives.

Margin

Space outside the border — the gap to the neighbouring boxes.

CSS · finding things

How CSS finds what to style

Every CSS rule = an address + a list of properties. Three address types cover 95% of CSS.

Tag — by type

button { … } styles every button on the page. Coarse, but instant.

Class & id — by name

.card { … } hits only elements with class="card"; #status hits exactly one element.

The same addresses JS uses to find elements — the first handshake between the three files.

CSS · a taste

What 'style' actually means

A CSS rule = pick an element, then assign it properties. That is the entire syntax.

style.css
button {
  padding: 10px 18px;     /* room inside */
  background: #34d399;    /* colour */
  border: none;
  border-radius: 8px;     /* rounded corners */
  color: white;
  font-size: 15px;
}
Live — try it

Right side is live — that's the exact CSS from the box applied to the button. Hover it. AI writes this; knowing padding / border / radius is how you review it.

CSS · layout

Three layout tools, one job

Layout = deciding where things sit. CSS has exactly three big tools for that.

Flexbox — one direction

Line things up in a row or a column, and space them evenly. Menu bars, card rows.

Grid — two directions

Rows AND columns at once. Dashboards, photo walls, whole-page layouts.

Media queries — responsive

'If the screen is narrower than 768px, do this.' One codebase, phone and desktop both work.

CSS · flexbox

Flexbox, drawn

display: flex puts items in a line. Two axes do all the work — every other flex property is just a knob on one of these.

MAIN AXIS
1 2 3
CROSS AXIS

justify-content moves items along the MAIN axis · align-items moves them along the CROSS axis

CSS · flexbox · main axis

justify-content — spacing along the main axis

The boxes are real: each row is an actual flex container with that exact property. This is what the browser computes.

justify-content:
flex-start
123
justify-content:
center
123
justify-content:
space-between
123
justify-content:
space-around
123

space-between: items hug the edges, gaps only between · space-around: equal room for every item, half at the edges

CSS · flexbox · more knobs

Wrap, grow, direction

Three more properties cover most real flex layouts. All three boxes below are live flex containers.

flex-wrap: wrap
12345

items too big → new row

flex-grow: 1
A B · flex:1 C

B eats the leftover space

flex-direction: column
1 2 3

main axis turns vertical

wrap: overflow starts a new row · grow: one item fills what's left · column: the line becomes a column

CSS · grid

Grid — rows AND columns at once

Left: nine boxes in a 3×3. Right: boxes that span. Same idea, far less code than stacking flexboxes.

grid-template-columns: repeat(3, 1fr)
123 456 789
items can span
1 2 · span 2 cols 3 · span 2 rows 4 5

Bootstrap's col-3 is this same grid with 12 columns: col-3 = 3 of 12 = a quarter of the row

CSS · responsive

One codebase, two layouts

The media query is a switch: same elements, different arrangement per screen size.

responsive.css
/* desktop: sidebar next to content */
.layout { display: flex; }

/* phone: sidebar stacks on top */
@media (max-width: 768px) {
  .layout { flex-direction: column; }
}
Live — try it
sidebar
content
window: 820px → row

Right side is a live window — drag the slider past 768px and the sidebar stacks. Below 768px the same page rearranges itself; that is 'responsive'.

03
Part 3

Bootstrap — don't style from scratch

A CSS framework: thousands of ready-made styles you switch on with class names — and the next three slides run it live.

Bootstrap · why

Same button, two ways

That's the whole pitch: consistency for free, so you spend time on the page — not on pixels.

From scratch

You decide every pixel: padding, colour, border, hover state, size on mobile. Then do it again for every button on every page.

With Bootstrap

Add a class: class="btn btn-primary". It arrives styled, with hover and mobile behaviour included. Same for cards, nav bars, modals.

Bootstrap · live demo

Same markup — the classes are the magic

Identical HTML, same photo. The right side only adds class names — and it suddenly looks designed.

plain html — no classes
Espresso machine

Espresso Machine

Pulls a proper shot at home.

same markup + bootstrap classes
Espresso machine
Espresso Machine

Pulls a proper shot at home.

card · card-img-top · card-body · card-title · card-text · btn btn-primary

Bootstrap · live demo

The components you'll see everywhere

Everything below is real Bootstrap 5, rendered in this slide. Each piece is one or two class names.

Aero chair
Aero Chair

Ergonomic. Breathable. Actually comfortable.

View product
New Beta Live Down

navbar · card · alert · badge · btn — the vocabulary of a thousand dashboards

Bootstrap · live demo

Forms stop looking default

The same inputs you saw in the HTML part — now with form-* classes. Focus states and spacing included.

form-label · form-control · form-select · form-check form-switch · btn

Bootstrap · a taste

A page in 11 lines of classes

No <style> block at all — the page's whole look comes from the class names.

index.html
<link href="bootstrap.min.css" rel="stylesheet">

<nav class="navbar">…logo + links…</nav>

<div class="container">
  <div class="row">
    <div class="col-3">sidebar</div>
    <div class="col-9">main content</div>
  </div>
  <button class="btn btn-primary">Click me</button>
</div>

col-3 / col-9 is the grid: 12 columns, 3+9 fills the row. Change the numbers — the layout changes.

Bootstrap · vocabulary

Classes worth recognizing

You won't memorize Bootstrap — but these six show up in almost every page built with it.

ClassWhat you get
btn btn-primaryA styled button — hover and focus states included
container · row · col-*The 12-column grid: col-3 + col-9 fills one row
navbarA responsive menu bar — collapses by itself on phones
cardA bordered box for image + text + button
modalA popup window — open/close handled for you
form-controlA styled input field
Bootstrap · the grid

The 12-column grid, in one slide

Every Bootstrap layout is rows of 12 equal slots. You pick how many each block takes.

row = 12 slots

<div class="row"> is a shelf split into 12 equal parts. col-3 takes 3, col-9 takes 9 — they fill the shelf.

Numbers are the layout

col-6 + col-6 = halves, col-4 × 3 = thirds. Change the numbers and the page re-flows — no other CSS needed.

Breakpoints = free responsive

col-md-6 means '6 columns on medium screens and up, stack below.' The same row is a phone layout and a desktop layout.

04
Part 4

JavaScript — make the page DO things

HTML is the picture, CSS is its outfit — JS is the reflexes.

JavaScript · the core pattern

One listener, one update

The pattern behind every interaction on the web: listen for an event, then change the page.

app.js
const btn = document.querySelector("#save");

btn.addEventListener("click", () => {
  document.querySelector("#status")
          .textContent = "Saved ✓";
});
Live — try it
console

Right side is live — click Save and the virtual console logs the whole event. The button now DOES something: click fires, JS edits the page.

JavaScript · what it buys you

Four things every app does

JS reads and edits the DOM — the page's live tree of elements — so everything below is 'just' editing that tree.

Show / hide

Tabs, dropdown menus, toasts — the same element, switched on and off.

Validate a form

Check the email looks right before it's sent. Show an error, block the submit.

Fetch data from an API

Ask the server for JSON — a list of orders, prices, posts — then paint it into the page.

Read & edit the DOM

Find, read, change, add to the page's elements. The page is data you can manipulate.

JavaScript · the DOM cheat sheet

The methods you'll see in every AI answer

You won't memorize these — but when AI writes them, you should recognize what each line is doing.

MethodWhat it does
document.querySelector("#x")Find the first element by its CSS address — the same #x / .x names CSS uses.
document.querySelectorAll(".x")Find every matching element — a list you can loop over.
el.textContent = "…"Set plain text — safe, no HTML parsing.
el.innerHTML = "…"Set HTML markup — the browser parses and renders it.
el.addEventListener("click", fn)Run fn when the event fires. One element can listen to many.
el.classList.toggle("open")Add the class if missing, remove it if present — a switch.
input.valueRead what the user typed — or set the default.
createElement + appendBuild a new element from scratch and attach it to the page.
JavaScript · events

The three events that cover most UI

The pattern is always the same: listener → handler → edit the page. Only the event name changes.

click

The classic — buttons, links, tabs. Fires when the user activates the element.

input — every keystroke

Fires on every key pressed. The key behind live search boxes and autocomplete — no 'Search' button needed.

submit — and e.preventDefault()

Fires when a form is sent. Call e.preventDefault() in the handler to stop the page reload — then JS takes over.

JavaScript · state

A counter — state lives in a variable

Two buttons, one number. The JS variable is the truth; the page only mirrors it.

counter.js
let count = 0;
const out = document.querySelector("#count");

document.querySelector("#plus")
  .addEventListener("click", () => {
    count += 1;
    out.textContent = count;
  });

document.querySelector("#reset")
  .addEventListener("click", () => {
    count = 0;
    out.textContent = count;
  });
Live — try it
0
console

Right side is live — click +1 / Reset; the console mirrors the data-then-paint order. That order is the idea behind every app framework.

JavaScript · show / hide

Tabs — the real show/hide pattern

Show/hide is almost always just flipping a CSS class. JS never touches 'display' directly.

tabs.js
const tabs = document.querySelectorAll(".tab");

tabs.forEach(tab => tab.addEventListener("click", () => {
  tabs.forEach(t => t.classList.remove("active"));
  tab.classList.add("active");
  // CSS: .tab.active shows its panel, the rest hide
}));
Live — try it
Profile panel
console

Right side is live — click a tab; the console shows the .active class moving. The same trick powers dropdowns, toasts and accordions.

JavaScript · forms

Form validation, the real way

Catch the submit, check the value, show or clear the error — without a page reload.

validate.js
const form = document.querySelector("#signup");

form.addEventListener("submit", (e) => {
  e.preventDefault();                   // don't reload

  const email = document.querySelector("#email").value;
  const err = document.querySelector("#err");

  if (!email.includes("@")) {
    err.textContent = "That email looks wrong.";
  } else {
    err.textContent = "";              // clear it
    form.reset();
  }
});
Live — try it
console

Right side is live — submit a bad email, then a good one; the console logs each branch. This is the skeleton of every valid-email message.

JavaScript · the filter pattern

Search a list on every keystroke

input → filter the data → re-render the list. This one pattern is behind every filter UI you've ever used.

filter.js
const foods = ["Pizza", "Pho", "Sushi", "Banh mi", "Tacos"];
const input = document.querySelector("#search");
const list = document.querySelector("#list");

input.addEventListener("input", () => {
  const hits = foods.filter(f =>
    f.toLowerCase().includes(input.value.toLowerCase()));

  list.innerHTML = hits
    .map(f => "<li>" + f + "</li>")
    .join("");
});
Live — try it
  • Pizza
  • Pho
  • Sushi
  • Banh mi
  • Tacos
console

Right side is live — type in the box and the console logs each filter. filter() picks matches, map() makes rows, join() glues them.

JavaScript · fetch

fetch — and always plan for failure

Networks fail: the server is down, the wifi drops, the route doesn't exist. The catch is part of the feature.

fetch.js
async function loadOrders() {
  const list = document.querySelector("#orders");
  try {
    const res = await fetch("/api/orders");
    const orders = await res.json();
    list.innerHTML = orders
      .map(o => "<li>" + o.name + "</li>")
      .join("");
  } catch (err) {
    list.textContent = "Couldn't load orders — retry?";
  }
}
Live — try it
  • — press Load orders —
console

Right side simulates the network (no real endpoint) — Load orders, or tick Simulate failure to hit the catch. Judge any AI fetch by its catch.

JavaScript · async

fetch doesn't block the page

This is why web apps feel alive while loading — and why async bugs feel spooky.

The request runs in the background

fetch fires and JS moves on immediately. The page keeps scrolling and animating while the server thinks.

.then / await = 'when it arrives'

Callbacks queue up: 'when the data arrives, do this.' Order matters — you can't paint data that hasn't landed.

That's why spinners exist

The UI stays alive during the wait. A spinner is the interface admitting 'I'm still loading'.

Async bugs feel spooky

'Where did my data go?' is usually 'I used it before it arrived.' The await/then discipline exists for exactly that.

JavaScript · the big idea

State + render() — the seed of React & Vue

Two pieces: one source of truth, and a function that repaints the page from it.

pattern.js
// one source of truth
let state = { open: 3, cart: [] };

// the page is a picture of the state
function render() {
  document.querySelector("#open").textContent = state.open;
  document.querySelector("#cart").textContent =
    "Cart: " + state.cart.length;
}

state.open += 1;   // 1. change the data
render();          // 2. repaint the page
Live — try it
open: 3 Cart: 0
console

Right side is live — the two buttons change state, render() repaints, the console logs it. This is exactly what React & Vue automate.

The connection

One element, three files

HTML, CSS and JS all talk about the same element — each does its own job.

HTML — defines it

<p id="status"></p> — the element exists, still empty.

CSS — styles it

#status { color: red; } — whenever it has text, the text is red.

JS — changes it

document.querySelector("#status") gets filled the moment you click the button.

The server's job ends at the send. Everything you see and click is HTML, CSS and JS running in your browser.
— the whole frontend in one sentence

HTML builds it. CSS styles it. JS makes it move.

You'll now let AI generate these files — your job is to read them, judge them and fix them.