HTML Fundamentals
Learn the structure and language of every web page on the internet. HTML is the skeleton — everything else builds on top of it.
HTML (HyperText Markup Language) is the standard language for creating web pages. When you type a URL, your browser sends a request to a server, which returns an HTML file. The browser reads that file and renders it visually.
Think of building a web page like building a house: HTML is the structure (walls, floors, rooms), CSS is the interior design (paint, furniture, aesthetics), and JavaScript is the electricity (interactivity, functionality).
Every valid HTML page shares the same foundational skeleton. Here is the complete boilerplate with detailed annotations:
<!-- DOCTYPE tells the browser we're using HTML5 -->
<!DOCTYPE html>
<!-- lang="en" helps screen readers and search engines -->
<html lang="en">
<head>
<!-- Character encoding: always UTF-8 for international support -->
<meta charset="UTF-8">
<!-- Makes the page responsive on mobile devices -->
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<!-- The title appears in browser tabs and search results -->
<title>My First Web Page</title>
<!-- Link to an external CSS file -->
<link rel="stylesheet" href="style.css">
</head>
<body>
<!-- All visible content goes inside <body> -->
<h1>Hello, World!</h1>
<p>My first paragraph.</p>
</body>
</html>
Semantic tags tell browsers, screen readers, and search engines what role each section of content plays. This is one of the most important concepts in modern HTML.
<div class="header">Logo, nav</div>
<div class="nav">Links</div>
<div class="main">
<div class="post">...</div>
</div>
<div class="sidebar">...</div>
<div class="footer">...</div>
<header>Logo, nav</header>
<nav>Links</nav>
<main>
<article>...</article>
</main>
<aside>...</aside>
<footer>...</footer>
<header>
<!-- Sits at the top: logo, site nav, branding -->
<nav>
<ul>
<li><a href="/">Home</a></li>
<li><a href="/about">About</a></li>
</ul>
</nav>
</header>
<main>
<!-- The primary content of the page -->
<section>
<!-- A thematic grouping of related content -->
<h2>Latest Articles</h2>
<article>
<!-- Self-contained content (could stand alone) -->
<h3>How to Learn CSS Fast</h3>
<p>Article content here...</p>
</article>
</section>
</main>
<aside>
<!-- Related but non-essential: ads, links, widgets -->
<h3>Related Posts</h3>
</aside>
<footer>
<!-- Copyright, links, site info -->
<p>© 2025 My Site</p>
</footer>
Forms are how users communicate with websites — from login screens to checkout flows. Every input needs a label for accessibility.
<form action="/submit" method="POST" novalidate>
<!-- Text input with label -->
<div class="form-group">
<label for="name">Full Name <span class="required">*</span></label>
<input
type="text"
id="name"
name="name"
placeholder="e.g. Jane Smith"
required
autocomplete="name"
>
</div>
<!-- Email with built-in validation -->
<div class="form-group">
<label for="email">Email Address</label>
<input type="email" id="email" name="email" required>
</div>
<!-- Select / dropdown -->
<div class="form-group">
<label for="role">Your Role</label>
<select id="role" name="role">
<option value="">Select...</option>
<option value="dev">Developer</option>
<option value="design">Designer</option>
</select>
</div>
<!-- Textarea for longer text -->
<div class="form-group">
<label for="message">Message</label>
<textarea id="message" name="message" rows="5"></textarea>
</div>
<!-- Checkbox -->
<label>
<input type="checkbox" name="newsletter">
Subscribe to newsletter
</label>
<!-- Submit button -->
<button type="submit">Send Message</button>
</form>
Accessibility ensures everyone can use your website — including people who use screen readers, keyboards only, or have visual impairments. It's also legally required in many countries.
<!-- Always add alt text to images -->
<img src="team.jpg" alt="Our engineering team at the 2025 hackathon">
<!-- Decorative images use empty alt="" -->
<img src="divider.png" alt="" role="presentation">
<!-- ARIA role for landmark navigation -->
<nav aria-label="Main navigation">...</nav>
<!-- Buttons must have descriptive text -->
<button aria-label="Close dialog">✕</button>
<!-- Form: use for + id to link labels -->
<label for="email">Email</label>
<input type="email" id="email" aria-required="true">
<!-- Skip link for keyboard users -->
<a href="#main-content" class="skip-link">Skip to main content</a>
<!-- aria-hidden hides decorative elements from screen readers -->
<span aria-hidden="true">→</span>
<!-- Live regions announce dynamic content changes -->
<div aria-live="polite" aria-atomic="true">
Form submitted successfully!
</div>
CSS Fundamentals
CSS gives your HTML structure life — colors, fonts, spacing, and layout. Learn how the styling engine works.
There are three ways to add CSS. Understanding when to use each is important for writing maintainable code.
/* ===========================
1. INLINE (avoid — hard to maintain)
=========================== */
<p style="color: red; font-size: 18px;">...</p>
/* ===========================
2. INTERNAL (okay for single-page demos)
=========================== */
<style>
p { color: blue; }
</style>
/* ===========================
3. EXTERNAL (ALWAYS USE THIS — best practice)
Link in <head>: <link rel="stylesheet" href="style.css">
=========================== */
/* style.css */
p {
color: #333;
font-size: 1rem;
line-height: 1.7;
}
/* 1. Element selector — targets all <p> tags */
p { color: #555; }
/* 2. Class selector — targets class="card" */
.card { border: 1px solid #ddd; }
/* 3. ID selector — targets id="hero" (use sparingly) */
#hero { background: #1a1917; }
/* 4. Descendant — <a> inside .nav */
.nav a { text-decoration: none; }
/* 5. Direct child — only <li> directly in <ul> */
ul > li { margin-bottom: 0.5rem; }
/* 6. Adjacent sibling — <p> immediately after <h2> */
h2 + p { font-size: 1.1rem; }
/* 7. Attribute — inputs with type="email" */
input[type="email"] { border-color: #2a6dd4; }
/* 8. Multiple selectors */
h1, h2, h3 { font-family: 'Syne', sans-serif; }
/* 9. Universal selector — everything */
* { box-sizing: border-box; }
Specificity determines which CSS rule wins when multiple rules target the same element:
| Selector Type | Score | Strength | Example |
|---|---|---|---|
| Inline styles | 1000 | Highest | style="..." |
| ID | 100 | High | #hero |
| Class / Attribute | 10 | Medium | .card, [type] |
| Element | 1 | Low | p, h1, div |
.element {
/* Named color (limited palette, avoid in production) */
color: tomato;
/* Hex: 6-digit #RRGGBB (most common) */
color: #d4522a;
/* Hex with alpha: 8-digit #RRGGBBAA */
background: #d4522a80; /* 50% opacity */
/* RGB */
color: rgb(212, 82, 42);
/* RGBA: with alpha transparency (0=transparent, 1=solid) */
color: rgba(212, 82, 42, 0.5);
/* HSL: Hue(0-360°), Saturation%, Lightness% */
color: hsl(16, 67%, 50%);
}
.element {
/* px — fixed pixels. Exact, but doesn't scale with user settings */
border: 1px solid #ddd;
/* rem — relative to root <html> font-size (default 16px)
1rem = 16px. BEST for font sizes and spacing */
font-size: 1.125rem; /* = 18px */
margin-bottom: 2rem; /* = 32px */
/* em — relative to the PARENT element's font size */
padding: 0.75em; /* useful for buttons: scales with font-size */
/* % — relative to parent container */
width: 50%; /* half of parent width */
/* vw/vh — viewport width/height */
min-height: 100vh; /* full screen height */
width: 80vw; /* 80% of screen width */
}
/* Import Google Fonts in <head> or @import */
@import url('https://fonts.googleapis.com/css2?family=Inter:wght@400;600;700&display=swap');
body {
font-family: 'Inter', sans-serif;
font-size: 1rem; /* 16px base */
line-height: 1.6; /* 1.5–1.8 is comfortable reading */
color: #1a1917;
}
h1 {
font-size: clamp(2rem, 5vw, 4rem); /* responsive size! */
font-weight: 700;
letter-spacing: -0.03em;
line-height: 1.1;
}
p {
max-width: 65ch; /* ch = character width; 60-75ch is ideal line length */
font-size: 1.0625rem;
color: #444;
}
Every element in HTML is a box. The box model defines how space is calculated around content. Misunderstanding this causes most layout bugs.
width × height
/* CRITICAL: Set this globally first — always */
*, *::before, *::after {
box-sizing: border-box;
/* border-box: width INCLUDES padding + border
Without this, adding padding grows the element! */
}
.card {
/* Content dimensions */
width: 320px;
height: auto; /* let content decide height */
/* Padding: inside space (shorthand: top right bottom left) */
padding: 1.5rem; /* all sides */
padding: 1rem 1.5rem; /* top+bottom, left+right */
padding-top: 2rem; /* individual sides */
/* Border */
border: 1px solid #ddd; /* width, style, color */
border-radius: 8px; /* rounded corners */
/* Margin: outside space */
margin: 0 auto; /* horizontal centering trick */
margin-bottom: 2rem;
/* Display: required for margin to work on inline elements */
display: block;
}
* { box-sizing: border-box; } to the top of every CSS file. It prevents countless layout headaches..hero {
/* Solid color */
background-color: #1a1917;
/* Image with fallback color */
background-image: url('hero.jpg');
background-size: cover; /* fill the area */
background-position: center;
background-repeat: no-repeat;
/* Linear gradient */
background: linear-gradient(135deg, #667eea, #764ba2);
/* Gradient overlay ON TOP of image */
background:
linear-gradient(rgba(0,0,0,0.5), rgba(0,0,0,0.5)),
url('hero.jpg') center/cover;
}
.card {
/* Box shadow: x-offset y-offset blur spread color */
box-shadow: 0 4px 24px rgba(0,0,0,0.1);
/* Multiple shadows for depth */
box-shadow:
0 1px 2px rgba(0,0,0,0.06),
0 4px 16px rgba(0,0,0,0.08);
}
Layout Mastery
This is where web development gets powerful. Master Flexbox, Grid, and responsive techniques to build any layout imaginable.
| Value | Behavior | Use For |
|---|---|---|
| block | Full width, new line before/after | div, p, h1, section |
| inline | Flows with text, no width/height | span, a, strong, em |
| inline-block | Flows with text, but accepts width/height | Buttons, navigation items |
| flex | 1D layout container | Nav bars, card rows, centering |
| grid | 2D layout container | Page layouts, card grids |
| none | Removed from layout entirely | Hiding elements (mobile nav) |
/* 1. STATIC (default) — normal document flow */
.box { position: static; }
/* 2. RELATIVE — offset from its own normal position
Creates a stacking context for absolute children */
.parent {
position: relative;
top: 10px; /* moves down by 10px from where it would normally be */
}
/* 3. ABSOLUTE — removed from flow, positioned to nearest
'positioned' ancestor (relative/absolute/fixed/sticky) */
.badge {
position: absolute;
top: -8px;
right: -8px; /* top-right corner of the parent */
}
/* 4. FIXED — relative to the viewport. Stays put on scroll */
.sticky-nav {
position: fixed;
top: 0;
left: 0;
width: 100%;
z-index: 100; /* stays above other content */
}
/* 5. STICKY — relative until scroll threshold, then fixed */
.section-header {
position: sticky;
top: 0; /* sticks to top of viewport when reached */
background: white;
z-index: 10;
}
/* Classic centering trick with absolute */
.centered {
position: absolute;
top: 50%;
left: 50%;
transform: translate(-50%, -50%);
}
Flexbox is your go-to for aligning items in a row or column. It's perfect for navigation, card rows, and centering elements.
/* ===== CONTAINER (parent) properties ===== */
.flex-container {
display: flex; /* activates flexbox */
/* Main axis direction */
flex-direction: row; /* → left to right (default) */
flex-direction: row-reverse; /* ← right to left */
flex-direction: column; /* ↓ top to bottom */
/* Alignment along MAIN axis (justify = main) */
justify-content: flex-start; /* pack to start */
justify-content: center; /* center everything */
justify-content: flex-end; /* pack to end */
justify-content: space-between; /* equal gaps BETWEEN items */
justify-content: space-around; /* equal gaps AROUND items */
/* Alignment along CROSS axis (align = cross) */
align-items: stretch; /* stretch to fill (default) */
align-items: center; /* vertically center */
align-items: flex-start; /* align to top */
align-items: flex-end; /* align to bottom */
/* Gap between items */
gap: 1rem; /* all gaps */
gap: 1rem 1.5rem; /* row-gap column-gap */
/* Allow items to wrap to next line */
flex-wrap: wrap;
}
/* ===== ITEM (child) properties ===== */
.flex-item {
/* flex-grow: how much it GROWS relative to siblings */
flex-grow: 1; /* take all available space */
/* flex-shrink: how much it shrinks if needed */
flex-shrink: 0; /* don't shrink */
/* flex-basis: ideal starting size */
flex-basis: 200px;
/* Shorthand: grow shrink basis */
flex: 1 1 200px;
flex: 1; /* grow + shrink equally */
/* Override align for individual item */
align-self: center;
}
/* ===== Common pattern: perfect centering ===== */
.center {
display: flex;
align-items: center;
justify-content: center;
}
/* ===== Common pattern: nav with logo left, links right ===== */
nav {
display: flex;
justify-content: space-between;
align-items: center;
}
Grid is for two-dimensional layouts — rows AND columns simultaneously. It's the best tool for page layouts and card grids.
.grid-container {
display: grid;
/* Define columns: fixed, fr (fraction), or mixed */
grid-template-columns: 200px 1fr 1fr; /* fixed, flex, flex */
grid-template-columns: repeat(3, 1fr); /* 3 equal columns */
grid-template-columns: repeat(4, minmax(240px, 1fr));
/* Auto-responsive: fill as many columns as fit */
grid-template-columns: repeat(auto-fit, minmax(280px, 1fr));
/* Define rows */
grid-template-rows: auto 1fr auto;
/* Named areas — visual layout map */
grid-template-areas:
"header header header"
"sidebar main main"
"footer footer footer";
gap: 1.5rem;
align-items: start;
}
/* Assign elements to named areas */
header { grid-area: header; }
aside { grid-area: sidebar; }
main { grid-area: main; }
footer { grid-area: footer; }
/* Item spanning multiple columns/rows */
.featured {
grid-column: span 2; /* take 2 columns */
grid-row: span 2; /* take 2 rows */
}
/* Precise placement */
.item {
grid-column: 1 / 3; /* from line 1 to line 3 */
grid-row: 2 / 4;
}
Mobile-first means: write CSS for mobile screens first, then add media queries to enhance the layout for larger screens. This is the industry standard approach.
/* ====================================
MOBILE FIRST: base styles = mobile
==================================== */
.card-grid {
display: grid;
grid-template-columns: 1fr; /* 1 column on mobile */
gap: 1rem;
padding: 1rem;
}
.nav-links {
display: none; /* hidden on mobile */
}
.hamburger {
display: block; /* shown on mobile */
}
/* ====================================
TABLET: 768px and up
==================================== */
@media (min-width: 768px) {
.card-grid {
grid-template-columns: repeat(2, 1fr); /* 2 columns */
padding: 2rem;
}
}
/* ====================================
DESKTOP: 1024px and up
==================================== */
@media (min-width: 1024px) {
.card-grid {
grid-template-columns: repeat(3, 1fr); /* 3 columns */
}
.nav-links { display: flex; }
.hamburger { display: none; }
}
/* ====================================
WIDE: 1440px and up
==================================== */
@media (min-width: 1440px) {
.container {
max-width: 1280px;
margin: 0 auto;
}
}
/* ====================================
OTHER useful queries
==================================== */
@media (max-width: 480px) { /* small phones */ }
@media (prefers-color-scheme: dark) { /* dark mode */ }
@media (prefers-reduced-motion) { /* accessibility */
* { animation: none !important; }
}
Advanced CSS
Level up with animations, CSS custom properties, pseudo-elements, and powerful techniques that make UIs feel alive.
/* ===========================
TRANSITIONS (state changes)
=========================== */
.button {
background: #d4522a;
/* property, duration, easing, delay */
transition: all 0.2s ease;
/* Multiple transitions (more precise) */
transition:
background 0.2s ease,
transform 0.15s ease,
box-shadow 0.2s ease;
}
.button:hover {
background: #b83d20;
transform: translateY(-2px);
box-shadow: 0 8px 24px rgba(212,82,42,0.3);
}
.button:active {
transform: translateY(0); /* snap back on click */
}
/* ===========================
@KEYFRAMES (custom animations)
=========================== */
@keyframes fadeInUp {
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); }
}
/* Applying animations */
.hero-title {
/* animation: name duration easing delay iteration direction fill-mode */
animation: fadeInUp 0.6s ease 0.1s both;
}
.loader {
animation: spin 1s linear infinite;
}
/* Staggered reveal effect */
.card:nth-child(1) { animation-delay: 0.1s; }
.card:nth-child(2) { animation-delay: 0.2s; }
.card:nth-child(3) { animation-delay: 0.3s; }
.element {
/* Translate (move) */
transform: translateX(20px);
transform: translateY(-10px);
transform: translate(-50%, -50%); /* classic centering */
/* Scale (resize) */
transform: scale(1.1); /* 110% size */
transform: scaleX(-1); /* flip horizontally */
/* Rotate */
transform: rotate(45deg);
transform: rotate(-90deg);
/* Skew */
transform: skewX(10deg);
/* Combine multiple transforms */
transform: translateY(-4px) scale(1.02);
/* transform-origin: set pivot point (default is center) */
transform-origin: top left;
transform-origin: 50% 50%; /* center (default) */
}
CSS variables let you define values once and reuse them everywhere. They're the foundation of design systems and theme-switching.
Dark Theme Component
All colors, spacing, and fonts come from CSS custom properties — change one variable and the whole theme updates instantly.
/* Define variables on :root — globally available */
:root {
/* Color palette */
--color-primary: #d4522a;
--color-secondary: #2a6dd4;
--color-text: #1a1917;
--color-muted: #6b6860;
--color-bg: #faf9f7;
--color-bg-2: #f2f0eb;
--color-border: rgba(15,14,13,0.12);
/* Typography */
--font-sans: 'DM Sans', sans-serif;
--font-display: 'Syne', sans-serif;
--font-mono: 'JetBrains Mono', monospace;
--text-base: 1rem;
--text-lg: 1.125rem;
--text-xl: 1.25rem;
/* Spacing scale */
--space-1: 0.25rem;
--space-2: 0.5rem;
--space-4: 1rem;
--space-8: 2rem;
--space-16: 4rem;
/* Borders & effects */
--radius: 6px;
--radius-lg: 12px;
--shadow: 0 4px 16px rgba(0,0,0,0.08);
}
/* Use them anywhere with var() */
.button {
background: var(--color-primary);
font-family: var(--font-sans);
padding: var(--space-2) var(--space-4);
border-radius: var(--radius);
}
/* Dark mode: override variables — all components update! */
@media (prefers-color-scheme: dark) {
:root {
--color-text: #e8e0d0;
--color-bg: #1a1917;
--color-bg-2: #252321;
}
}
/* Component-scoped variables */
.card {
--card-padding: 1.5rem;
padding: var(--card-padding);
}
/* var() with fallback */
p { color: var(--color-body-text, #333); }
/* :hover — mouse over */
.card:hover { transform: translateY(-4px); }
/* :focus — keyboard/click focus */
input:focus {
outline: none;
border-color: #2a6dd4;
box-shadow: 0 0 0 3px rgba(42,109,212,0.2);
}
/* :active — clicking */
.btn:active { transform: scale(0.97); }
/* :nth-child — powerful selection */
li:first-child { border-top: none; }
li:last-child { border-bottom: none; }
tr:nth-child(even) { background: #f9f9f9; } /* zebra rows */
li:nth-child(3n + 1) { /* every 3rd, offset by 1 */ }
/* :not — exclude elements */
.nav a:not(.active) { color: #666; }
/* :is — group selectors cleanly */
:is(h1, h2, h3) { line-height: 1.2; }
/* :has — parent selector (newer, powerful!) */
.form-group:has(input:invalid) { border-color: red; }
/* ::before and ::after insert generated content */
.card::before {
content: ''; /* required, even if empty */
display: block;
width: 40px;
height: 3px;
background: #d4522a;
margin-bottom: 1rem;
}
/* Decorative quote */
blockquote::before {
content: '\201C'; /* " opening quotation mark */
font-size: 4rem;
color: #ddd;
position: absolute;
top: -20px;
left: 0;
}
/* ::first-line and ::first-letter */
p::first-letter {
font-size: 3rem;
float: left;
line-height: 1;
margin-right: 0.1em;
}
/* ::selection — text highlighted by user */
::selection {
background: #d4522a;
color: white;
}
/* ::placeholder — input placeholder text */
input::placeholder { color: #aaa; font-style: italic; }
/* z-index only works on positioned elements (not static)
Higher number = closer to the user */
/* Design a z-index scale for your project */
:root {
--z-below: -1; /* behind everything */
--z-base: 0; /* default content */
--z-raised: 10; /* cards, dropdowns */
--z-sticky: 100; /* sticky headers */
--z-overlay: 200; /* overlays, backdrops */
--z-modal: 300; /* modal dialogs */
--z-toast: 400; /* notifications */
--z-tooltip: 500; /* tooltips (always on top) */
}
.nav { position: sticky; z-index: var(--z-sticky); }
.modal { position: fixed; z-index: var(--z-modal); }
.tooltip { position: absolute; z-index: var(--z-tooltip); }
/* Stacking context: created by transform, opacity, filter, etc.
Children can't escape their parent's stacking context! */
.parent {
transform: translateZ(0); /* creates new stacking context */
/* Children with z-index won't appear above elements
outside this parent, even with z-index: 9999 */
}
Real-World UI Components
Production-ready components built with semantic HTML and polished CSS. Study these, then rebuild them from scratch.
<!-- HTML -->
<header class="site-header">
<nav class="nav" aria-label="Main">
<a href="/" class="nav__brand">Brand</a>
<button class="nav__toggle" aria-label="Toggle menu">☰</button>
<ul class="nav__links">
<li><a href="/" class="nav__link active">Home</a></li>
<li><a href="/work" class="nav__link">Work</a></li>
</ul>
<a href="/contact" class="nav__cta">Get Started</a>
</nav>
</header>
/* CSS (BEM naming convention) */
.site-header {
position: sticky;
top: 0;
z-index: 100;
background: rgba(26,25,23,0.95);
backdrop-filter: blur(10px); /* frosted glass effect */
border-bottom: 1px solid rgba(255,255,255,0.08);
}
.nav {
display: flex;
align-items: center;
justify-content: space-between;
max-width: 1200px;
margin: 0 auto;
padding: 1rem 2rem;
}
.nav__links {
display: flex;
gap: 2rem;
list-style: none;
}
.nav__link {
color: rgba(255,255,255,0.65);
text-decoration: none;
font-size: 0.9rem;
transition: color 0.15s;
}
.nav__link:hover,
.nav__link.active { color: #fff; }
/* Mobile — hide links, show hamburger */
@media (max-width: 768px) {
.nav__links { display: none; }
.nav__links.open {
display: flex;
flex-direction: column;
position: absolute;
inset: auto 0 auto 0;
background: #1a1917;
padding: 1rem 2rem;
}
}
Build Faster.
Ship Better.
The modern developer toolkit for production-ready UIs.
Hands-On Projects
Theory alone won't make you job-ready. Build these projects, put them on GitHub, and link them in your portfolio.
- ✓ Profile photo with rounded styling
- ✓ Bio section with semantic markup
- ✓ Skills list with styled tags
- ✓ Social media links
- ✓ Mobile responsive layout
- ✓ Sticky navigation bar
- ✓ Hero with gradient + CTA
- ✓ Features grid (3 columns)
- ✓ Pricing table
- ✓ Testimonials carousel
- ✓ Contact form + footer
- ✓ Custom CSS scroll animations
- ✓ Dark / light mode toggle
- ✓ CSS-only modal dialogs
- ✓ 100 Lighthouse score
- ✓ Full WCAG 2.1 compliance
- ✓ Open Graph meta tags
Best Practices & Professional Workflow
The difference between a hobbyist and a professional is how they structure and maintain their code.
BEM stands for Block, Element, Modifier. It's a naming system that makes CSS readable, scalable, and collision-free in large projects.
/* Block: standalone component */
.card { }
/* Element: part of the block (double underscore) */
.card__header { }
.card__title { }
.card__body { }
.card__footer { }
.card__image { }
/* Modifier: variation of block or element (double dash) */
.card--featured { } /* highlighted card */
.card--dark { } /* dark themed card */
.card__title--large { } /* larger title */
.card__title--muted { } /* dimmed title */
/* Button BEM example */
.btn { } /* base button styles */
.btn--primary { } /* primary color */
.btn--small { } /* size modifier */
.btn--disabled { } /* state modifier */
.btn__icon { } /* icon inside button */
<!-- HTML usage -->
<div class="card card--featured">
<img class="card__image" src="..." alt="...">
<div class="card__body">
<h3 class="card__title card__title--large">...</h3>
<button class="btn btn--primary">...</button>
</div>
</div>
project/
├── index.html
├── about.html
├── css/
│ ├── main.css ← imports everything below
│ ├── base/
│ │ ├── reset.css ← normalize browser defaults
│ │ ├── variables.css ← all CSS custom properties
│ │ └── typography.css ← font rules
│ ├── layout/
│ │ ├── grid.css
│ │ └── nav.css
│ ├── components/
│ │ ├── buttons.css
│ │ ├── cards.css
│ │ ├── forms.css
│ │ └── modals.css
│ └── pages/
│ ├── home.css
│ └── about.css
└── images/
/* main.css — import in order */
@import 'base/reset.css';
@import 'base/variables.css';
@import 'base/typography.css';
@import 'layout/grid.css';
@import 'components/buttons.css';
/* ... etc */
Performance & SEO Basics
A beautiful site that loads slowly or ranks poorly is incomplete. These fundamentals set your work apart from beginners.
<head>
<!-- Primary meta (60-70 chars for title, 150-160 for description) -->
<title>CSS Grid Layout Guide | Learn Web Design</title>
<meta name="description" content="A complete, practical guide to mastering
CSS Grid for responsive web layouts. Includes examples and projects.">
<!-- Open Graph: controls how link previews look on social media -->
<meta property="og:title" content="CSS Grid Layout Guide">
<meta property="og:description" content="...">
<meta property="og:image" content="https://yoursite.com/og-image.jpg">
<meta property="og:url" content="https://yoursite.com/css-grid">
<!-- Canonical: prevents duplicate content issues -->
<link rel="canonical" href="https://yoursite.com/css-grid">
<!-- Robots: tell search engines what to crawl -->
<meta name="robots" content="index, follow">
<!-- Preconnect: speed up external resources -->
<link rel="preconnect" href="https://fonts.googleapis.com">
</head>
<!-- In body: proper heading hierarchy -->
<h1>CSS Grid Complete Guide</h1> <!-- ONE per page -->
<h2>How Grid Works</h2> <!-- section headings -->
<h3>Grid Lines</h3> <!-- subsections -->
/* 1. Use will-change for animated elements (prep GPU) */
.animated-card { will-change: transform, opacity; }
/* Reset after animation to free memory */
.animated-card.done { will-change: auto; }
/* 2. Prefer transform over top/left for animations
transform is GPU-accelerated, top/left triggers reflow */
.bad { top: 10px; } /* SLOW: layout reflow */
.good { transform: translateY(10px); } /* FAST: GPU */
/* 3. contain: layout tells browser this element is isolated */
.widget { contain: layout style; }
/* 4. Responsive images — serve correct size */
img {
max-width: 100%;
height: auto;
display: block;
}
/* 5. Preload critical fonts */
<link rel="preload" href="font.woff2"
as="font" type="font/woff2" crossorigin>
/* 6. Reduce paint areas with content-visibility */
.below-fold-section {
content-visibility: auto;
contain-intrinsic-size: 0 500px; /* estimated height */
}
Job-Ready Checklist
Before you call yourself a job-ready HTML/CSS developer, run through these items.
- ☑ Write semantic HTML from memory
- ☑ All forms have proper labels + validation
- ☑ All images have descriptive alt text
- ☑ Correct heading hierarchy (h1 → h2 → h3)
- ☑ Page has proper meta tags and title
- ☑ Build any layout with Flexbox + Grid
- ☑ Use CSS variables for design tokens
- ☑ BEM or similar naming convention
- ☑ Smooth transitions on interactive elements
- ☑ Mobile-first responsive design
- ☑ 3 live projects on GitHub + deployed
- ☑ Lighthouse score 90+ on all projects
- ☑ Works on Chrome, Firefox, Safari, Edge
- ☑ Passes WAVE or axe accessibility audit
- ☑ Readable, commented, organized CSS