HTML & CSS Guide
A complete frontend foundation โ semantic HTML, forms, the box model, selectors and specificity, flexbox, grid, responsive design, transitions and dark-mode theming. Every code block has a Copy button.
Copy button on each code block ยท โ Beginner โ Intermediate โ Advanced01 Introduction โ The Frontend Foundation
HTML (HyperText Markup Language) is the structure of a webpage โ headings, paragraphs, images, links, forms. CSS (Cascading Style Sheets) is the presentation โ color, layout, typography, animation, responsiveness. Together they are the two skills every frontend developer uses daily, and they are the foundation of every framework (React, Vue, Svelte all render HTML and style with CSS).
How the browser renders your page
- Parse HTML โ builds the DOM tree (nodes for every element)
- Parse CSS โ builds the CSSOM tree (every rule)
- Render tree โ combines DOM + CSSOM, discarding things like
display:none - Layout (reflow) โ computes the exact position and size of every box
- Paint โ fills pixels on screen
- Composite โ layers transforms/opacity for smooth animation
Why this still matters in 2026
- Frameworks change constantly โ HTML and CSS do not
- Performance, accessibility and SEO are judged on the final DOM and CSS
- Tailwind, Bootstrap and every UI kit still compile down to CSS
- It is the fastest way to become employable โ no build step required
02 Setup & Dev Tools Beginner
Your first file โ no build step needed
<!-- index.html -->
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>My First Page</title>
<link rel="stylesheet" href="style.css">
</head>
<body>
<h1>Hello, World!</h1>
<p>This is my first HTML and CSS page.</p>
</body>
</html>
/* style.css */
body{
font-family: system-ui, sans-serif;
background: #0f172a;
color: #f1f5f9;
padding: 40px;
}
h1{ color: #f97316; }
<link rel="stylesheet" href="style.css"> lives in <head>. A <style> block inside <body> works but blocks rendering and is considered bad practice.Live Server extension
- Install Live Server by Ritwick Dey in VS Code
- Right-click the HTML file โ Open with Live Server
- Your page reloads automatically on every save at
http://127.0.0.1:5500
Browser DevTools โ your superpower
03 Document Structure & Core Tags Beginner
The anatomy of an HTML document
<!DOCTYPE html> <!-- tells the browser to use modern standards mode -->
<html lang="en"> <!-- root element; lang is required for a11y -->
<head> <!-- metadata: not visible on the page -->
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Page Title</title>
<link rel="stylesheet" href="style.css">
<script src="app.js" defer></script>
</head>
<body> <!-- everything the user actually sees -->
<h1>Heading</h1>
<p>Paragraph</p>
</body>
</html>
Elements, tags, attributes, values
<a href="https://developer.mozilla.org" class="link" target="_blank" rel="noopener">MDN</a>
- Tag โ
<a>and</a> - Element โ the tag plus its content:
<a>MDN</a> - Attribute โ
href - Value โ
https://developer.mozilla.org
Void (self-closing) elements
These have no closing tag and no content:
<img><br><hr><input><meta><link><area><base><source><track><wbr>
Comments and entities
<!-- This is an HTML comment -->
<p>5 < 10 && 10 > 5</p> <!-- escape < and > -->
<p>Tom & Jerry <!-- escape the ampersand itself -->
<p>© 2026 — Laksh Guides</p>
The heading hierarchy rule
Headings are the outline of your page, not a way to pick font sizes. There must be exactly one <h1>, and levels must not skip.
<h3>) to change the size of a heading. If it looks small, style it small โ don't change its semantic level. Screen-reader users navigate pages by heading outline.04 Text, Links, Images & Tables Beginner
Lists
<ul> <!-- unordered (bulleted) -->
<li>Flexbox</li>
<li>Grid</li>
</ul>
<ol type="A"> <!-- ordered (numbered); type="A" / "i" / "1" -->
<li>Read HTML</li>
<li>Read CSS</li>
</ol>
<dl> <!-- description list -->
<dt>API</dt> <!-- term -->
<dd>Application Programming Interface</dd>
</dl>
Links โ the essentials
<a href="https://developer.mozilla.org">MDN Web Docs</a>
<a href="page.html">Internal page</a>
<a href="#section">Jump to section</a>
<a href="mailto:hello@example.com">Email me</a>
<a href="tel:+919876543210">Call support</a>
<a href="report.pdf" download>Download the PDF</a>
<a href="https://example.com" target="_blank" rel="noopener noreferrer">Open in new tab</a>
target="_blank" gives the new page access to your window via window.opener. Always pair it with rel="noopener". Never use target="_blank" for internal navigation โ it breaks the back button.Images
<img
src="images/laksh.jpg"
alt="Laksh working at a desk with two monitors"
width="600" <!-- reserve space, prevents layout shift -->
height="400"
loading="lazy" <!-- defer offscreen images -->
decoding="async"
>
alt="Red bicycle leaning on a brick wall"). For purely decorative images use alt="" โ a screen reader then skips it. Never write alt="image" or alt="photo of".Tables โ for tabular data only
<table>
<caption>Browser market share, 2026</caption>
<thead>
<tr><th scope="col">Browser</th><th scope="col">Share</th></tr>
</thead>
<tbody>
<tr><th scope="row">Chrome</th><td>66%</td></tr>
<tr><th scope="row">Safari</th><td>18%</td></tr>
</tbody>
<tfoot>
<tr><td>Total</td><td>100%</td></tr>
</tfoot>
</table>
05 Forms & Inputs Beginner
Forms are how users send data. A good form works even when JavaScript is disabled.
<form action="/signup" method="post">
<label for="name">Full name</label>
<input type="text" id="name" name="name" autocomplete="name" required>
<label for="email">Email address</label>
<input type="email" id="email" name="email" autocomplete="email" required>
<label for="pw">Password</label>
<input type="password" id="pw" name="pw" minlength="8" required>
<label for="age">Age</label>
<input type="number" id="age" name="age" min="18" max="100">
<label for="birth">Date of birth</label>
<input type="date" id="birth" name="birth">
<label for="color">Favourite colour</label>
<input type="color" id="color" name="color" value="#e34f26">
<label>
<input type="checkbox" name="terms" value="yes" required>
I accept the terms and conditions
</label>
<label for="plan">Plan</label>
<select id="plan" name="plan">
<optgroup label="Personal">
<option value="free">Free</option>
<option value="pro" selected>Pro</option>
</optgroup>
<option value="team">Team</option>
</select>
<textarea id="bio" name="bio" rows="4" maxlength="500" placeholder="Tell us about yourself"></textarea>
<button type="submit">Create account</button>
<button type="reset">Reset</button>
</form>
Input types you'll actually use
The label is not optional
for="id"must match the input'sid- Clicking the label focuses the input
- Screen readers announce the label instead of "text field, edit, blank"
- Nesting the input inside the label also works, but
foris clearer
placeholder is not a label โ it disappears on typing and often fails contrast tests. Use autocomplete attributes so browsers and password managers can fill fields. Never log the name of a password field to the server.06 Semantic Layout Intermediate
Semantic elements describe what a piece of content is, not how it looks. They give free SEO, accessibility and correct behaviour, and they make your code readable months later.
<body>
<header> <!-- site banner: logo, nav -->
<nav aria-label="Main navigation">
<ul>
<li><a href="/" aria-current="page">Home</a></li>
<li><a href="/guides">Guides</a></li>
<li><a href="/about">About</a></li>
</ul>
</nav>
</header>
<main> <!-- the unique content of this page -->
<article>
<header>
<h1>Understanding Flexbox</h1>
<p><time datetime="2026-08-14">14 Aug 2026</time></p>
</header>
<section>
<h2>Main axis and cross axis</h2>
<p>...</p>
</section>
<aside>Related links</aside>
<footer>Posted by Laksh</footer>
</article>
</main>
<aside> <!-- complementary: sidebar, ads, TOC -->
<footer> <!-- site-wide footer -->
</body>
Choosing the right element
Take any page you admire, view its source (Ctrl+U), and identify which blocks are <header>, <main> and <footer>. Then guess how they built the layout โ Grid or Flexbox.
07 Accessibility & SEO Basics Intermediate
Accessibility (a11y) means your page works for keyboard users, screen-reader users, and users with low vision, colour blindness or motor impairments. It is a legal requirement for public sites (WCAG 2.2) and it is good engineering.
Keyboard first
- Every interactive element must be reachable and operable with Tab, Enter and Space
- Use native
<button>and<a>instead of<div onclick> - Never remove the focus outline โ style it instead:
:focus-visible{ outline:2px solid #e34f26; outline-offset:2px; } - Modals must trap focus and close with Esc (
<dialog>does this for free)
ARIA โ use sparingly
<!-- Good: a real button needs nothing extra -->
<button>Open menu</button>
<!-- Necessary when you must use a div (e.g. a custom widget) -->
<div role="button" tabindex="0" aria-pressed="false"
aria-label="Toggle navigation menu">โฐ</div>
<!-- Live region for dynamic messages -->
<p role="status" aria-live="polite">Form submitted successfully</p>
<!-- Hide decorative icons from screen readers -->
<span aria-hidden="true">โ
</span>
<span class="visually-hidden">5 out of 5 stars</span>
role="button" you must also implement keyboard handlers yourself.SEO essentials
- One descriptive
<title>per page (unique, ~60 characters) - Meta description (
<meta name="description">) โ 120โ160 chars - Semantic tags give search engines your outline for free
- Meaningful
alttext on images - Open Graph tags for link previews on WhatsApp, Slack, X
- Fast load time and valid HTML โ Lighthouse score is a ranking signal
<meta name="description" content="Learn HTML and CSS from scratch: semantic markup, flexbox, grid, responsive design, and theming with CSS variables.">
<meta property="og:type" content="website">
<meta property="og:title" content="HTML & CSS Guide">
<meta property="og:description" content="From document structure to CSS Grid โ the complete frontend foundation.">
<meta property="og:image" content="https://example.com/og.png">
08 CSS Selectors Beginner
/* Universal + element */
* /* every element */
p /* every <p> */
/* Class and ID */
.card /* any element with class="card" */
#header /* the element with id="header" (unique) */
/* Compound (no space = same element) */
nav ul li.active /* li that has class active, inside ul inside nav */
button.primary
/* Descendant / child / next sibling */
.card p /* p anywhere inside .card */
.card > p /* p that is a DIRECT child of .card */
.card + p /* p immediately after .card */
.card ~ p /* every p AFTER .card */
/* Attribute */
a[href^="https"] /* external links */
input[type="text"]
a[target="_blank"]
[data-id="42"]
/* Pseudo-classes */
a:hover
a:focus-visible
li:nth-child(2) /* 2nd li */
li:nth-child(odd) /* 1st, 3rd, 5th */
li:not(.active) /* except */
input:checked /* checkbox/radio checked */
input:required
input:invalid
p::placeholder
div:has(h2) /* div containing an h2 */
::selection /* highlighted text */
/* Pseudo-elements */
p::before { content: "โ "; }
p::after { content: ""; }
li::marker { color: #e34f26; }
::first-letter{ font-size:3rem; float:left; }
Combinators at a glance
A Bโ descendant (space)A > Bโ direct childA + Bโ adjacent sibling (immediately after)A ~ Bโ general sibling (anywhere after)A, Bโ group (comma = OR)
:has(), nesting (.card{ &:hover{ ... } }), and @layer for managing cascade order. All are supported in current browsers.09 The Cascade, Specificity & Inheritance Intermediate
When two rules target the same element, the browser decides which wins using the cascade. The order is:
- Origin & importance โ user-agent styles < author styles <
!importantauthor < user!important - @layer โ unlayered styles beat layered ones
- Specificity โ a numeric score per selector
- Source order โ if specificity ties, the last rule in the file wins
Specificity scoring (0, a, b, c)
- a โ number of IDs โ
#header= (1,0,0) - b โ number of classes, attributes, pseudo-classes โ
.card= (0,1,0) - c โ number of elements and pseudo-elements โ
p= (0,0,1)
Inheritance
Some properties inherit down the DOM tree by default โ color, font-family, line-height, text-align, visibility. Most others do not โ margin, padding, border, width.
/* Stop inheritance */
.card *{ all: unset; } /* nuclear option โ use with care */
button{ font: inherit; } /* forms don't inherit fonts by default */
!important or adding longer selectors to win usually means your architecture is wrong. Fix the root cause โ restructure the markup or introduce CSS custom properties instead of writing #main .card h3.title./* Modern solution: @layer makes order explicit โ no more specificity wars */
@layer reset, base, components, utilities;
@layer base{
body{ font-family: system-ui, sans-serif; }
}
@layer components{
.card{ padding: 20px; } /* overrides base regardless of file order */
}
@layer utilities{
.card{ padding: 40px; } /* utilities always win */
}
10 The Box Model Beginner
Every element on a page is a rectangular box with four layers: content โ padding โ border โ margin. Margin is outside the border; padding is inside it.
โโโโโโโโโโโโโ margin (transparent, outside) โโโโโโโโโโโโโ
โ โโโโโโโโโ border โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ โ
โ โ โโโโโ padding โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ โ โ
โ โ โ CONTENT (width ร height) โ โ โ
โ โ โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ โ โ
โ โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ โ
โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ
.box{
width: 200px;
height: 100px;
padding: 20px;
border: 5px solid #e34f26;
margin: 30px;
}
/* Default: content-box โ total width = 200 + 40 + 10 + 60 = 310px */
/* The fix almost everyone needs: */
*, *::before, *::after{ box-sizing: border-box; }
content-box (the default), width:200px; padding:20px renders 240px wide. Set box-sizing:border-box globally and width means the total size โ padding and border are subtracted automatically.Margin collapse
Vertical margins of adjacent siblings collapse into one โ the bigger value wins, they do not add. A child's top margin can also collapse through its parent if the parent has no padding or border.
.a{ margin-bottom: 30px; }
.b{ margin-top: 20px; } /* gap between them = 30px, NOT 50px */
- Fix with gap in Flexbox/Grid (never collapses)
- Fix with a flex/grid parent on the container
- Fix with padding or
overflow:hiddenon the parent
Width, min and max
width: 50%โ percentage of the parent's content widthmax-width: 60chโ caps line length for readability (ideal body text is 45โ75 characters)min-widthโ stops flex items shrinking below a usable sizeheight: 100vhโ viewport height;100%only works if the parent has an explicit heightaspect-ratio: 16 / 9โ modern replacement for padding hacks
.container{ max-width: 1000px; margin-inline: auto; }. This only works for block elements โ for flex items use margin-inline: auto with a fixed width, or justify-content: center on the parent.11 Colors, Fonts & Units Beginner
Color formats
hsl() โ change one number (lightness) and you get perfect tints and shades for free: hsl(15 78% 52%), hsl(15 78% 42%), hsl(15 78% 92%).Units
- px โ absolute, predictable. Good for borders, icons, small fixed elements
- rem โ relative to the root font size. Scales with user settings โ use for font sizes and spacing
- em โ relative to the element's own font size. Use for padding that should scale with text
- % โ relative to the parent. Widths, heights, font sizes
- vw / vh โ 1% of viewport width/height
- ch โ width of the "0" glyph. Perfect for
max-widthon text - fr โ fraction of free space. Grid only
Typography that reads well
body{
font-family: 'Inter', system-ui, -apple-system, 'Segoe UI', Roboto, sans-serif;
font-size: 1rem; /* 16px default */
line-height: 1.6; /* 1.5โ1.8 for body text */
color: #475569;
max-width: 70ch; /* readable line length */
margin-inline: auto;
padding-inline: 1.5rem;
}
h1{ font-size: clamp(1.8rem, 1.4rem + 2vw, 2.8rem); line-height: 1.15; letter-spacing: -0.02em; }
h2{ font-size: clamp(1.4rem, 1.2rem + 1vw, 1.8rem); }
.btn{
font: inherit; /* buttons don't inherit fonts by default */
font-weight: 600;
letter-spacing: 0.01em;
}
max-width: 70ch on prose instead of letting text run the full width of a 1920px monitor. Use text-wrap: balance on headings so lines break evenly.Build one paragraph of body text, then experiment: try line-height: 1.0 vs 1.8, and width 40ch vs 120ch. Read both. The difference will click instantly.
12 Flexbox Intermediate
Flexbox lays out items in one direction โ a row or a column. This is the single most-used layout tool on the web: nav bars, button groups, card rows, centering anything.
.container{
display: flex; /* row by default */
flex-direction: row | row-reverse | column | column-reverse;
flex-wrap: wrap | nowrap | wrap-reverse;
justify-content: flex-start | center | flex-end | space-between | space-around | space-evenly;
align-items: stretch | flex-start | center | flex-end | baseline;
align-content: flex-start | center | space-between; /* multi-line only */
gap: 1rem;
}
Main axis vs cross axis
- main axis โ the direction items flow (
flex-direction).justify-contentdistributes along it. - cross axis โ perpendicular to it.
align-itemsaligns along it.
justify-content = main axis, align-items = cross axis. Flip flex-direction: column and the two swap roles โ this confuses everyone once.Properties on the items
.item{
flex-grow: 1; /* share leftover space */
flex-shrink: 1; /* default: allowed to shrink */
flex-basis: 200px; /* starting size before free space */
flex: 1 1 auto; /* grow shrink basis shorthand */
flex: 0 0 200px; /* fixed width, never grow/shrink */
align-self: flex-end; /* override align-items for one item */
order: 2; /* visual order only โ DOM order is unchanged */
min-width: 0; /* CRITICAL: allows shrinking below content size */
}
Pattern 1 โ perfect centring
.center{
display: flex;
justify-content: center; /* horizontal */
align-items: center; /* vertical */
min-height: 100vh;
}
Pattern 2 โ navbar with pushed-right links
.navbar{ display: flex; align-items: center; gap: 1.5rem; }
.navbar .brand{ margin-right: auto; } /* pushes the rest to the right */
.navbar a{ text-decoration: none; color: #f1f5f9; }
.navbar a:hover{ color: #e34f26; }
.navbar a[aria-current="page"]{ color: #e34f26; font-weight: 600; }
Pattern 3 โ wrapping card row
.cards{
display: flex;
flex-wrap: wrap;
gap: 1.25rem;
justify-content: center;
}
.card{
flex: 1 1 260px; /* grow, shrink, basis 260px */
max-width: 380px;
padding: 1.5rem;
border: 1px solid #334155;
border-radius: 16px;
}
min-width:auto, which means they refuse to shrink below their content's width. A long unbroken string overflows its container. Fix: min-width: 0 on the item (and overflow-wrap: anywhere on the text).Take your navbar and set flex-direction: column. Predict what breaks before you change it โ then verify. Doing this for all four direction values teaches the main/cross axis faster than any tutorial.
13 CSS Grid Intermediate
Grid lays items out in two dimensions at once โ rows and columns. Use it for page-level layout and card galleries; use Flexbox for one-dimensional component internals.
.grid{
display: grid;
grid-template-columns: repeat(3, 1fr); /* 3 equal columns */
grid-template-rows: auto 1fr auto;
gap: 1.5rem;
align-items: start;
justify-items: stretch;
}
Track sizing
Line-based placement
.layout{
display: grid;
grid-template-columns: 250px 1fr;
grid-template-rows: auto 1fr auto;
grid-template-areas:
"header header"
"sidebar main"
"footer footer";
}
header { grid-area: header; }
aside { grid-area: sidebar; }
main { grid-area: main; }
footer { grid-area: footer; }
grid-template-areas is the best layout tool: the entire page structure becomes visible in the CSS as an ASCII diagram. Reflowing to mobile is a one-line change instead of a pile of overrides.Spanning and alignment
.hero{
grid-column: 1 / -1; /* span all columns */
grid-row: span 2;
}
.card{ align-self: start; justify-self: center; }
.grid{ place-items: center; } /* align + justify shorthand */
.grid{ place-content: center; } /* for the whole grid */
/* Dense packing โ fills holes left by spans */
.gallery{ grid-auto-flow: row dense; }
Pattern โ responsive gallery with zero media queries
.gallery{
display: grid;
grid-template-columns: repeat(auto-fill, minmax(min(240px, 100%), 1fr));
gap: 1rem;
}
min() wrapper is what stops a 240px minimum from overflowing a 320px phone. Add min(240px, 100%) to every auto-fill grid and it becomes bulletproof.Build a classic dashboard: header, sidebar, main content and footer using grid-template-areas. Then resize the window and confirm nothing breaks. This exact layout is what you will build in every framework tutorial.
14 Positioning Intermediate
Relative + absolute
.card{ position: relative; } /* becomes the containing block */
.badge{
position: absolute;
top: -8px; right: -8px;
background: #e34f26;
color: white;
border-radius: 999px;
padding: 2px 8px;
}
absolute element is positioned relative to its nearest ancestor that has position set to anything other than static (or transform / filter / contain). If it lands in the wrong place, look for an unexpected position:relative up the tree.Centring with absolute positioning
.overlay{
position: absolute;
inset: 0; /* top/right/bottom/left all 0 = fill parent */
display: grid;
place-items: center; /* cleaner than top:50% + translate */
}
Sticky navbar
header{
position: sticky;
top: 0;
z-index: 100;
backdrop-filter: blur(12px);
background: rgba(15, 23, 42, 0.85);
}
Fixed toast notification
.toast{
position: fixed;
bottom: 24px; right: 24px;
z-index: 1000;
padding: 14px 20px;
border-radius: 12px;
background: #10b981;
color: #04140d;
box-shadow: 0 10px 30px rgba(0,0,0,0.4);
}
position: sticky fails if any ancestor has overflow: hidden, auto or scroll. Also, the element needs room to move within its parent โ it cannot leave its parent's box.transform, filter or opacity < 1 creates a new stacking context and can trap children. When z-index "doesn't work", this is why.15 Responsive Design Intermediate
Mobile-first is the default
Write the small-screen layout first, then progressively enhance. Your base CSS targets phones; media queries add complexity only where needed.
/* Base โ mobile (no query needed) */
.cards{ display: grid; gap: 1rem; }
/* Enhance at 640px */
@media (min-width: 40rem){
.cards{ grid-template-columns: repeat(2, 1fr); }
}
/* Enhance at 1024px */
@media (min-width: 64rem){
.cards{ grid-template-columns: repeat(4, 1fr); }
}
Media query features
Fluid typography and spacing
h1{
/* min | preferred | max โ scales smoothly with viewport */
font-size: clamp(1.8rem, 1.2rem + 3vw, 3.5rem);
}
.container{
width: min(100% - 2rem, 1200px); /* fluid with a max */
margin-inline: auto;
}
.grid{ gap: clamp(0.75rem, 2vw, 1.5rem); }
vw for font sizes on mobile โ Chrome zooms text when it exceeds 20px. Use clamp() with a rem minimum instead. Also remember 100vw includes the scrollbar width and causes horizontal overflow; 100% does not.Respecting user preferences
@media (prefers-reduced-motion: reduce){
*, *::before, *::after{
animation-duration: 0.01ms !important;
animation-iteration-count: 1 !important;
transition-duration: 0.01ms !important;
scroll-behavior: auto !important;
}
}
min-height: 44px in touch contexts.16 Transitions, Transforms & Animation Advanced
Transitions โ animate a change
.btn{
background: #e34f26;
transition: background 0.25s ease, transform 0.25s ease, box-shadow 0.25s ease;
}
.btn:hover{
background: #1572b6;
transform: translateY(-2px);
box-shadow: 0 8px 20px rgba(0,0,0,0.3);
}
.btn:active{ transform: translateY(0); }
transform, opacity and filter. Animating width, height, top or margin forces the browser to recompute layout on every frame โ this causes jank.Keyframe animations
@keyframes fade-up{
0% { opacity: 0; transform: translateY(30px); }
100% { opacity: 1; transform: translateY(0); }
}
.card{
opacity: 0;
animation: fade-up 0.7s cubic-bezier(0.16, 1, 0.3, 1) both;
}
.card:nth-child(2){ animation-delay: 0.1s; }
.card:nth-child(3){ animation-delay: 0.2s; }
/* Infinite loading spinner */
@keyframes spin{ to{ transform: rotate(360deg); } }
.spinner{
width: 36px; height: 36px;
border: 3px solid rgba(255,255,255,0.2);
border-top-color: #e34f26;
border-radius: 50%;
animation: spin 0.8s linear infinite;
}
Scroll-triggered reveal with no JavaScript
@supports (animation-timeline: view()){
.card{
animation: fade-up linear both;
animation-timeline: view();
animation-range: entry 0% cover 25%;
}
}
Transforms cheat sheet
translateX(20px)/translateY(-50%)โ movescale(1.05)โ zoom; addtransform-origin: centerto change the anchorrotate(45deg)โ spin;rotateY(180deg)โ card flipskewX(-10deg)โ italic slantperspective(1000px) rotateY(25deg)โ 3D depth
Timing functions
Build a hover card that lifts up, scales slightly and reveals a hidden description โ using only transform and opacity. Then check the Performance panel while hovering to confirm nothing forces reflow.
17 CSS Variables & Theming Advanced
Custom properties (--name) store values on an element and cascade exactly like normal properties. They are the foundation of every design system and the cleanest way to build dark mode.
:root{
/* Brand palette โ the only values you ever change */
--brand: #e34f26;
--brand-dark: #c2410c;
--accent: #1572b6;
/* Semantic tokens */
--bg: #07080e;
--surface: rgba(18, 22, 40, 0.75);
--text: #f1f5f9;
--text-dim: #8892b0;
--border: rgba(227, 79, 38, 0.15);
/* Spacing scale */
--space-1: 0.25rem;
--space-2: 0.5rem;
--space-3: 1rem;
--space-4: 1.5rem;
--radius: 14px;
--shadow: 0 8px 32px rgba(0,0,0,0.5);
}
@media (prefers-color-scheme: light){
:root{
--bg: #f8fafc;
--surface: rgba(255,255,255,0.85);
--text: #0f172a;
--text-dim: #475569;
}
}
body{
background: var(--bg);
color: var(--text);
}
.card{
padding: var(--space-4);
border: 1px solid var(--border);
border-radius: var(--radius);
background: var(--surface);
box-shadow: var(--shadow);
}
JavaScript-free dark mode toggle
<!-- inline in <head> โ prevents white flash on load -->
<script>
const theme = localStorage.getItem('theme')
|| (matchMedia('(prefers-color-scheme: dark)').matches ? 'dark' : 'light');
document.documentElement.dataset.theme = theme;
</script>
:root[data-theme="light"]{
--bg: #f8fafc;
--surface: #ffffff;
--text: #0f172a;
--text-dim: #475569;
}
:root[data-theme="dark"]{
--bg: #07080e;
--surface: #121626;
--text: #f1f5f9;
--text-dim: #8892b0;
}
Runtime variables from JS
// JS reads the computed value
const brand = getComputedStyle(document.documentElement)
.getPropertyValue('--brand').trim(); /* "#e34f26" */
// JS sets a variable (e.g. reading the user's accent preference)
document.documentElement.style.setProperty('--brand', '#1572b6');
var(--brand, #e34f26) to provide a fallback if the variable is ever missing. Note that custom properties are not typed โ --gap: 10 is invalid as a length, you must write --gap: 10px.@property to give them a type and make them animatable โ this is how you animate custom properties without JavaScript.18 Practice Projects Intermediate
Reading is not learning. Build these in order โ each one introduces exactly one new concept.
โถ 1. Personal Profile Card Flexbox
Center a card vertically and horizontally. Add an avatar, name, role and three social links that highlight on hover. Make the avatar circle on hover with transform: scale().
.profile{
display: flex;
flex-direction: column;
align-items: center;
gap: 0.75rem;
padding: 2rem;
border-radius: 20px;
background: var(--surface);
}
.avatar{
width: 120px; height: 120px;
border-radius: 50%;
object-fit: cover;
transition: transform 0.3s ease;
}
.profile:hover .avatar{ transform: scale(1.05) rotate(3deg); }
.links{ display: flex; gap: 1rem; }
โถ 2. Responsive Navbar with Hamburger Media queries
Horizontal nav on desktop; on mobile it collapses into a โฐ button that toggles a vertical menu. Use aria-expanded and aria-label so it stays accessible.
โถ 3. CSS Grid Photo Gallery Grid
Use auto-fill + minmax for automatic columns. Give the first image grid-column: span 2 and grid-row: span 2. Add a lightbox on click using position: fixed.
โถ 4. Dashboard Layout grid-template-areas
Header, 240px sidebar, main area, footer. Below 900px, collapse to a single column with the sidebar hidden behind a toggle. This is the layout behind every admin panel you have ever used.
โถ 5. Landing Page Full project
Hero with gradient text and a CSS-only animated background, a 3-card feature grid, a testimonials grid using auto-fit, an FAQ built with <details>, and a CTA section. Must be responsive, keyboard-navigable and score 95+ in Lighthouse.
โถ 6. Themed Portfolio with Dark Mode CSS variables
Define a full token set in :root, then a toggle button that swaps data-theme on <html>. Persist the choice in localStorage and add a smooth transition: background-color 0.3s to body.
19 Cheat Sheet & Best Practices Beginner
Reset you'll actually use
*, *::before, *::after{ box-sizing: border-box; margin: 0; padding: 0; }
body{ line-height: 1.6; -webkit-font-smoothing: antialiased; }
img, picture, video{ max-width: 100%; height: auto; display: block; }
input, button, textarea, select{ font: inherit; }
ul[class]{ list-style: none; }
:focus-visible{ outline: 2px solid #e34f26; outline-offset: 2px; }
@media (prefers-reduced-motion: reduce){
*, *::before, *::after{ animation-duration: .01ms !important; transition-duration: .01ms !important; }
}
Layout decision tree
- One direction (row or column) โ Flexbox
- Rows and columns, or page layout โ Grid
- Centering anything, known or unknown size โ Grid with
place-items: center - Element must stay in the document flow โ sticky, not
fixed - Columns that depend on available width โ
repeat(auto-fit, minmax(220px, 1fr))
Ten rules to remember
- Semantic HTML first; CSS only for presentation
- One
<h1>per page, never skip heading levels - Always set
box-sizing: border-box - Use
gap, not margin hacks โ no collapse surprises min-width: 0on flex items that contain text- Classes for styling, IDs for anchors and JavaScript hooks
- Units:
remfor type and spacing,%/frfor sizes - Mobile-first with
min-widthqueries - Animate only
transformandopacity - Test with the keyboard and in DevTools โ every time
Resources worth bookmarking
- MDN Web Docs โ the reference, not a tutorial site. Start here.
- CSS-Tricks โ Flexbox and Grid guides by A Complete Beginner
- web.dev Learn โ structured, modern courses from the Chrome team
- Flexbox Froggy / Grid by Example โ learn by playing
- Can I Use โ check browser support before using a feature
- WCAG Quick Reference โ accessibility checklist