Context: Full-Stack Roadmap Chapters 1โ5 in one place โ HTML structure (Ch 1โ3) โ CSS styling (Ch 4) โ layout & responsive (Ch 5) ยท covers everything needed to build a styled, responsive, multi-page static site before JavaScript begins.
Read protocol: scan tables โ attempt the practice blank โ re-read only the section where you failed.
๐ฏ Objective: build a complete, responsive, multi-page website from scratch โ semantic HTML structure + CSS styling + Flexbox/Grid layout + mobile-first media queries.
โก Key Constraint: the box model is the root of 80% of CSS confusion โ width means content width by default (padding + border added on top); always start with * { box-sizing: border-box; }. Second biggest source of bugs: specificity โ an ID beats a class beats an element selector, and the browser silently picks the winner with no error.
๐ How the web works (mental model)
Concept One-liner Gotcha Client / Server browser asks (request) โ server answers (response) your HTML/CSS/JS runs on the client (browser) HTTP the protocol for requests; methods: GET / POST / PUT / DELETE status codes: 200 OK ยท 404 Not Found ยท 401 โ 403 DNS turns example.com โ IP address 93.184.216.34 the internetโs phone book Frontend / Backend code in the browser / code on the server full-stack = both Rendering browser reads HTML topโdown, builds a tree (DOM), paints pixels CSS loads in <head> so styles apply before the page paints
๐๏ธ HTML page skeleton (every page starts here)
<! DOCTYPE html > <!-- 1. declaration: "this is modern HTML" -->
< html >
< head > <!-- 2. metadata โ NOT visible on page -->
< meta charset = "UTF-8" >
< meta name = "viewport" content = "width=device-width, initial-scale=1.0" >
< title >Tab Title</ title > <!-- browser tab + search results -->
< link rel = "stylesheet" href = "styles.css" > <!-- external CSS -->
</ head >
< body > <!-- 3. everything the user SEES -->
...
</ body >
</ html >
<!DOCTYPE html> โ always first line; no closing tag.
<meta viewport> โ required for mobile; without it, phones render at 980px and zoom out.
<link> loads an external stylesheet โ the standard for all real projects.
๐ HTML elements โ content structure
Element Micro-syntax Job / gotcha Headings <h1> โ <h6>hierarchy, not size; never skip levels (h1โh3 is wrong); one <h1> per page Paragraph <p>text</p>block-level; browser adds margin above/below automatically Link <a href="url">text</a>href can be absolute (https://โฆ) or relative (about.html)Image <img src="path" alt="desc" width="400">no closing tag ; alt is required (accessibility + SEO); src is relative or URLLine break <br>no closing tag; use for addresses/poems โ separate ideas = separate <p> Comment <!-- text -->browser ignores it; notes to yourself Entity © โ ยฉ ยท & โ & ยท < โ <escape special characters
๐ Lists
Type Micro-syntax When Unordered <ul><li>Item</li></ul>bullets โ order doesnโt matter (ingredients) Ordered <ol><li>Step</li></ol>numbered โ sequence matters (cooking steps); browser auto-numbers Nested inner <ul>/<ol> goes inside a <li>, before its </li> sub-items; browser changes bullet style per depth
โ ๏ธ Only <li> belongs directly inside <ul>/<ol> โ raw text or <p> inside the list container is invalid.
Element Renders as Semantic meaning <strong>bold important โ screen readers stress it <em>italic emphasis โ like vocal stress <code>monospacecode, filenames, commands <sub> / <sup>HโO / xยฒ subscript / superscript <b> / <i>bold / italic no semantic meaning โ use <strong>/<em> by default
Element / Attribute Micro-syntax Job / gotcha Container <form>groups inputs; later add action="url" method="POST" for backend Text <input type="text" id="x" name="x">single-line; name = key sent to server Email / Number / Date / Password / URL <input type="email"> etc.browser validates format + shows correct mobile keyboard โ free Radio <input type="radio" name="group" value="v">pick one; same name = same group Checkbox <input type="checkbox" name="x" value="v">pick many; can share a name Dropdown <select name="x"><option value="v">Label</option></select>always set value explicitly (display text โ sent value) Textarea <textarea name="x" rows="5" cols="40"></textarea>multi-line; has a closing tag (unlike <input>) Label <label for="id">Text</label>for links to inputโs id; always include โ accessibility + click-to-focusSubmit <button type="submit">Go</button>triggers form submission Validation required ยท min="1" ยท max="100" ยท placeholder="hint"client-side; browser blocks submit if invalid
๐ Tables
< table >
< thead >< tr >< th >Name</ th >< th >Score</ th ></ tr ></ thead > <!-- header row -->
< tbody >< tr >< td >Aisyah</ td >< td >85</ td ></ tr ></ tbody > <!-- data rows -->
< tfoot >< tr >< td >Average</ td >< td >79</ td ></ tr ></ tfoot > <!-- summary row -->
</ table >
<th> = header cell (bold, centered) ยท <td> = data cell.
<thead>/<tbody>/<tfoot> โ accessibility, CSS targeting, sticky headers, print repetition.
โ ๏ธ Never use tables for page layout โ use CSS Grid/Flexbox.
๐๏ธ Semantic structure
Element Meaning Rule <header>site/page intro logo, title, tagline <nav>navigation links menus, breadcrumbs <main>primary content one per page <article>self-contained content blog post, product card โ โmakes sense in an email?โ <section>thematic grouping chapter within an article; doesnโt stand alone <aside>tangential content sidebar, related links <footer>closing content copyright, contact, sitemap <div>generic box โ no meaning use only when no semantic element fits; for CSS grouping
โโโโ <header> โโโโโโโโโโโโโโโโโโโโโโโโโโโโโ
โโโโ <nav> โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโค
โโโโ <main> โโโโโโโโโโโโโโโฌโโ <aside> โโโโโค
โ <section> โ sidebar โ
โ <article> โฆ </article>โ โ
โ </section> โ โ
โโโโโโโโโโโโโโโโโโโโโโโโโโโดโโโโโโโโโโโโโโโค
โโโโ <footer> โโโโโโโโโโโโโโโโโโโโโโโโโโโโโ
๐จ CSS โ how to add styles
Method Syntax When External (โ
use this)<link rel="stylesheet" href="styles.css"> in <head>every real project โ one file styles the whole site Internal <style>โฆ</style> in <head>single-page experiments Inline (โ avoid)<p style="color:red;">one-off test only; canโt reuse
๐ฏ Selectors
Selector Syntax Targets Element pall <p> Class .cardall class="card" โ primary styling tool ID #logoone id="logo" โ prefer classes for styling Descendant nav a<a> inside <nav> onlyGroup h1, h2, h3all three โ same rule Element+Class p.introonly <p class="intro"> Attribute input[type="email"]inputs of that type Pseudo-class a:hover ยท input:focus ยท li:first-child ยท li:last-child ยท li:nth-child(2)element state or position
Specificity (who wins when rules conflict): inline style > ID > class/pseudo-class/attribute > element. Equal specificity โ last rule wins. DevTools Styles panel shows crossed-out lines for overridden rules.
๐จ Colors & backgrounds
Format Example Notes Named tomato, navy, teal~140 names; prototyping Hex #2c3e50, #fffmost common; 6-digit (RRGGBB) or 3-digit shorthand RGB rgb(44, 62, 80)decimal equivalent of hex RGBA rgba(0, 0, 0, 0.5)adds transparency (0 = invisible, 1 = solid) background-color#f5f5f5fills the padding area too background-imageurl('img.jpg')background-size: cover fills the box (hero images)
๐ค Typography
Property Job Common values font-familytypeface + fallback chain 'Segoe UI', Tahoma, sans-serif โ always end with genericfont-sizetext size 16px, 1.2rem, 2emfont-weightthickness normal (400), bold (700)line-heightvertical space between lines 1.5โ1.8 for body textcolortext color #333 (dark grey > pure black for readability)text-alignhorizontal alignment left, center, righttext-decorationunderline etc. none (remove link underline), underlineletter-spacingspace between characters -0.5px for tight headings
๐ฆ The Box Model (the single most important CSS concept)
โโโโโโโโโโโโโโโโ MARGIN โโโโโโโโโโโโโโโโโ transparent โ pushes others away
โ โโโโโโโโโโโโ BORDER โโโโโโโโโโโโโโโ โ visible edge
โ โ โโโโโโโโ PADDING โโโโโโโโโโโ โ โ inside the box โ bg color fills it
โ โ โ CONTENT โ โ โ text / image
โ โ โ width ร height โ โ โ
โ โ โโโโโโโโโโโโโโโโโโโโโโโโโโโโ โ โ
โ โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ โ
โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ
Property Micro-syntax Gotcha width / height300px, 90%, autodefault = content width only; border-box makes it total width padding20px (all) ยท 10px 20px (TB, LR) ยท 10px 20px 30px 40px (T R B L โป)inside the box; bg color fills it border1px solid #ddd ยท border-radius: 8pxvisible edge; radius = rounded corners marginsame shorthand as padding ยท 0 auto centers a block with max-width outside the box; transparent box-sizing* { box-sizing: border-box; }always add โ makes width include padding + border
Shorthand order (clockwise from top): Top โ Right โ Bottom โ Left. Same for padding and margin.
Centering a block: max-width: 800px; margin: 0 auto; โ must have a width or max-width set, or auto does nothing.
๐ Units
Unit Meaning Use for pxfixed pixels borders, small spacing, exact sizes %percentage of parent fluid widths (width: 90%) emrelative to elementโs font-size spacing that scales with text remrelative to root (<html>) font-size font sizes โ most predictable vh / vw% of viewport height / width full-screen sections (height: 100vh) frfractional unit (Grid only) divide available space (1fr 1fr 1fr = 3 equal cols)
Practical rule: rem for font sizes, px for borders and fine details, % + max-width for containers, fr for Grid columns.
๐ช Flexbox (1D layout โ row OR column)
.container {
display : flex ; /* activates Flexbox */
flex-direction : row ; /* default: horizontal; column = vertical */
justify-content : center ; /* distribute along MAIN axis */
align-items : center ; /* align along CROSS axis */
flex-wrap : wrap ; /* allow wrapping to next line */
gap : 20 px ; /* space between items */
}
justify-contentVisual (main axis โ) flex-start[A][B][C]ยทยทยทยทยทยทยทยทยทflex-endยทยทยทยทยทยทยทยทยท[A][B][C]centerยทยทยทยท[A][B][C]ยทยทยทยทspace-between[A]ยทยทยทยท[B]ยทยทยทยท[C]space-evenlyยทยทยท[A]ยทยทยท[B]ยทยทยท[C]ยทยทยท
align-itemsEffect (cross axis) stretchitems fill container height (default) centervertically centered flex-start / flex-endtop / bottom
Item property Micro-syntax Job flex-growflex-grow: 1absorb leftover space (default 0 = donโt grow) flex-shrinkflex-shrink: 0prevent shrinking align-selfalign-self: flex-endoverride align-items for one item
Center anything (holy grail):
.center { display : flex ; justify-content : center ; align-items : center ; height : 100 vh ; }
Navbar pattern:
nav { display : flex ; justify-content : space-between ; align-items : center ; }
/* logo pushed left, links pushed right */
๐ฒ CSS Grid (2D layout โ rows AND columns)
.grid {
display : grid ;
grid-template-columns : 1 fr 1 fr 1 fr ; /* 3 equal columns */
grid-template-rows : auto 1 fr auto ; /* header / stretch / footer */
gap : 20 px ; /* row + column gap */
}
Pattern Micro-syntax Result Equal columns grid-template-columns: 1fr 1fr 1fr3 equal-width columns Fixed + flex grid-template-columns: 200px 1frsidebar 200px + fluid content Repeat repeat(3, 1fr)shorthand for 1fr 1fr 1fr Auto-responsive repeat(auto-fit, minmax(250px, 1fr))as many cols as fit, min 250px โ responsive without media queries
Flexbox vs. Grid โ decision rule
Scenario Use Row of items (navbar, toolbar, centering) Flexbox Card grid / image gallery / dashboard Grid Full page layout (header / sidebar / footer) Grid Items that wrap into rows either โ Flex wrap or Grid auto-fit One dimension (row or column)Flexbox Two dimensions (rows AND columns)Grid
Most pages use both : Grid for the page skeleton, Flexbox for component internals.
๐ฑ Responsive Design
Tool Micro-syntax Job Viewport tag <meta name="viewport" content="width=device-width, initial-scale=1.0">required โ without it, mobile renders at 980px and zooms outFluid container width: 90%; max-width: 1000px; margin: 0 auto;adapts to screen, caps at max, centered Fluid images img { max-width: 100%; height: auto; }prevents overflow Auto-fit grid repeat(auto-fit, minmax(280px, 1fr))responsive grid, zero media queries Media query @media (min-width: 768px) { โฆ }apply CSS only above a width
Mobile-first (standard practice): write base styles for the smallest screen โ add complexity with min-width queries:
/* Mobile (default) */
.card-grid { grid-template-columns : 1 fr ; }
nav { flex-direction : column ; }
/* Tablet 768px+ */
@media ( min-width : 768 px ) {
.card-grid { grid-template-columns : 1 fr 1 fr ; }
nav { flex-direction : row ; }
}
/* Desktop 1024px+ */
@media ( min-width : 1024 px ) {
.card-grid { grid-template-columns : 1 fr 1 fr 1 fr ; }
}
Breakpoint Width Devices Mobile < 768px phones Tablet 768px โ 1023px tablets, small laptops Desktop โฅ 1024px laptops, monitors
DevTools responsive testing: F12 โ device toggle icon (Ctrl+Shift+M) โ resize or pick a preset device.
๐งฐ CSS reset / starter (paste at top of every stylesheet)
* {
box-sizing : border-box ;
margin : 0 ;
padding : 0 ;
}
img {
max-width : 100 % ;
height : auto ;
}
body {
font-family : 'Segoe UI' , Tahoma , Geneva, Verdana , sans-serif ;
font-size : 16 px ;
line-height : 1.6 ;
color : #333 ;
}
โ๏ธ Integration Practice
Practice 1: Build a responsive card grid โ 6 cards with a title, image, and description. 1 column on mobile, 2 on tablet, 3 on desktop. Cards have rounded borders, padding, and a subtle shadow. Include viewport meta tag. (uses: semantic HTML + Grid auto-fit or media queries + box model + responsive images)
<! DOCTYPE html >
< html >
< head >
< meta charset = "UTF-8" >
< meta name = "viewport" content = "width=device-width, initial-scale=1.0" >
< title >Card Grid</ title >
< style >
* { box-sizing : border-box ; margin : 0 ; padding : 0 ; }
body { font-family : Arial , sans-serif ; background : #f5f5f5 ; padding : 30 px ; }
.grid {
display : grid ;
grid-template-columns : repeat ( auto-fit , minmax ( 280 px , 1 fr ));
gap : 20 px ; max-width : 1000 px ; margin : 0 auto ;
}
.card {
background : white ; border : 1 px solid #ddd ; border-radius : 8 px ;
padding : 20 px ; box-shadow : 0 2 px 4 px rgba ( 0 , 0 , 0 , 0.08 );
}
.card img { width : 100 % ; border-radius : 4 px ; margin-bottom : 12 px ; }
.card h3 { margin-bottom : 8 px ; color : #2c3e50 ; }
</ style >
</ head >
< body >
< div class = "grid" >
< div class = "card" >
< img src = "https://picsum.photos/seed/1/600/400" alt = "Sample 1" >
< h3 >Card Title</ h3 >< p >Description text here.</ p >
</ div >
<!-- repeat 5 more cards -->
</ div >
</ body >
</ html >
Key move: repeat(auto-fit, minmax(280px, 1fr)) handles all breakpoints in one line โ no media queries needed. box-shadow adds depth without a heavier border.
Practice 2: Build a page with a Flexbox navbar (logo left, links right), a Grid main area (content + 250px sidebar), and a footer. Style the nav links to highlight on hover. Mobile: nav stacks vertically, sidebar disappears. (uses: Flexbox nav + Grid page layout + semantic elements + media query + pseudo-class)
< style >
* { box-sizing : border-box ; margin : 0 ; padding : 0 ; }
body { font-family : sans-serif ; min-height : 100 vh ;
display : grid ; grid-template-rows : auto auto 1 fr auto ; }
header { background : #2c3e50 ; color : white ; padding : 20 px 30 px ; }
nav { display : flex ; flex-direction : column ; gap : 8 px ;
background : #34495e ; padding : 10 px 30 px ; }
nav a { color : #ecf0f1 ; text-decoration : none ; }
nav a :hover { color : white ; text-decoration : underline ; }
.page { display : grid ; grid-template-columns : 1 fr ;
gap : 20 px ; padding : 20 px ; max-width : 1100 px ;
margin : 0 auto ; width : 100 % ; }
aside { background : #ecf0f1 ; padding : 20 px ; border-radius : 8 px ;
display : none ; }
footer { background : #2c3e50 ; color : #bdc3c7 ;
text-align : center ; padding : 15 px ; }
@media ( min-width : 768 px ) {
nav { flex-direction : row ; gap : 20 px ; }
.page { grid-template-columns : 1 fr 250 px ; }
aside { display : block ; }
}
</ style >
< header >< h1 >My Site</ h1 ></ header >
< nav >< a href = "#" >Home</ a >< a href = "#" >Blog</ a >< a href = "#" >About</ a ></ nav >
< div class = "page" >
< main >< h2 >Content</ h2 >< p >Main area here.</ p ></ main >
< aside >< h3 >Sidebar</ h3 >< p >Links, ads, etc.</ p ></ aside >
</ div >
< footer >< p > © 2026</ p ></ footer >
Key move: outer body Grid handles vertical stacking (header/nav/content/footer with 1fr on the content row to push the footer down); inner .page Grid handles the horizontal content + sidebar split. display: none + media query for the sidebar keeps mobile clean.
Practice 3: Build a styled registration form โ name (required), email (required), password (required), age (number, min 13), country (dropdown, 4 options), terms checkbox (required), submit button. Style inputs with consistent width, focus glow, and a coloured button that darkens on hover. Wrap in semantic elements. (uses: form elements + validation attributes + label linking + CSS selectors + pseudo-classes + box model)
< main >
< h1 >Register</ h1 >
< form >
< label for = "name" >Full name</ label >
< input type = "text" id = "name" name = "name" required >
< label for = "email" >Email</ label >
< input type = "email" id = "email" name = "email" required >
< label for = "pass" >Password</ label >
< input type = "password" id = "pass" name = "password" required >
< label for = "age" >Age</ label >
< input type = "number" id = "age" name = "age" min = "13" >
< label for = "country" >Country</ label >
< select id = "country" name = "country" >
< option value = "" >-- Select --</ option >
< option value = "MY" >Malaysia</ option >
< option value = "SG" >Singapore</ option >
< option value = "AU" >Australia</ option >
< option value = "ID" >Indonesia</ option >
</ select >
< div class = "checkbox-row" >
< input type = "checkbox" id = "terms" name = "terms" required >
< label for = "terms" >I agree to the terms</ label >
</ div >
< button type = "submit" >Register</ button >
</ form >
</ main >
form { max-width : 400 px ; background : white ; padding : 32 px ;
border-radius : 8 px ; border : 1 px solid #ddd ; }
label { display : block ; margin-bottom : 4 px ; font-weight : bold ; }
input [ type = "text" ], input [ type = "email" ], input [ type = "password" ],
input [ type = "number" ], select {
width : 100 % ; padding : 10 px ; border : 1 px solid #ccc ;
border-radius : 4 px ; margin-bottom : 16 px ; font-size : 1 rem ;
}
input :focus , select :focus {
border-color : #2980b9 ; outline : none ;
box-shadow : 0 0 0 3 px rgba ( 41 , 128 , 185 , 0.2 );
}
button [ type = "submit" ] {
background : #2980b9 ; color : white ; border : none ;
padding : 12 px 24 px ; border-radius : 4 px ; cursor : pointer ;
}
button [ type = "submit" ] :hover { background : #1f6fa0 ; }
.checkbox-row { display : flex ; align-items : center ; gap : 8 px ;
margin-bottom : 16 px ; }
.checkbox-row label { display : inline ; margin : 0 ; font-weight : normal ; }
Key move: label { display: block } replaces <br> tags; attribute selector input[type="email"] targets specific types; :focus pseudo-class + box-shadow replaces the browserโs default outline with a softer glow.
โ ๏ธ Common Mistakes (top debugging targets)
๐ก Forgot * { box-sizing: border-box; } โ width: 300px + padding: 20px + border: 5px = 350px actual. Boxes overflow everywhere.
๐ก Forgot viewport meta tag โ page looks perfect on laptop, tiny text on phones.
๐ก Styles donโt apply โ no error shown โ check in order: (1) typo in class name, (2) missing <link> to stylesheet, (3) specificity conflict (ID beats class), (4) browser cache (Ctrl+Shift+R to hard refresh).
๐ก margin: 0 auto doesnโt center โ the element has no width or max-width set โ auto needs a constraint.
๐ก Images overflow their container โ add global rule img { max-width: 100%; height: auto; }.
๐ก Headings used for size, not structure โ <h3> after <h1> because you want smaller text โ wrong; use CSS font-size to control appearance, headings define document outline.
๐ก justify-content vs align-items confusion โ justify = main axis, align = cross axis. If flex-direction: column, main axis is vertical (swapped).
๐ก Radio buttons not grouped โ each radio has a different name โ they behave as independent checkboxes.
๐ก Missing <label for="id"> โ clicking the text doesnโt focus the input; screen readers canโt announce the field.
๐ก Desktop-first media queries โ writing max-width queries that undo complexity โ harder to maintain. Write mobile-first with min-width instead.