Welcome! This guide is for absolute beginners — no experience required. By the end you’ll have a small, beautiful static website running on the web (and deployed to either GitHub Pages or Vercel), plus the foundational skills to keep improving.
Why static sites? They’re simple, fast, secure, and excellent for personal pages, portfolios, documentation, or small projects where you don’t need a database or server-side logic.
Table of Contents
- Quick overview and prerequisites
- Core HTML structure and common tags
- CSS fundamentals: selectors, properties, and linking stylesheets
- Practical example: build a tiny website (step-by-step)
- Deploying to GitHub Pages (step-by-step)
- Deploying to Vercel (step-by-step)
- Common pitfalls, best practices, and SEO tips
- Next steps & resources
Quick overview & prerequisites ✅
What you’ll need:
- A code editor (VS Code is excellent; see our
Code Editor Setuparticle for tips) - A GitHub account (for GitHub Pages) — free at GitHub
- (Optional) A Vercel account for instant deployments: Vercel
- Basic familiarity with saving files and running a terminal (we’ll guide you)
Definitions (quick):
- Static site = collection of files (HTML, CSS, images) served as-is by a web server.
- HTML = the structure/contents of your pages (headings, paragraphs, images).
- CSS = the visual style (colors, layout, fonts).
Key terms & abbreviations (quick reference)
- HTML — HyperText Markup Language: used to structure content on the web.
- CSS — Cascading Style Sheets: rules that define how HTML content is presented.
- HTTP — Hypertext Transfer Protocol: the protocol browsers use to request resources from servers.
- HTTPS/TLS — Secure HTTP; TLS ensures traffic between browser and server is encrypted.
- CDN — Content Delivery Network: edge servers that cache and serve static assets close to users for speed.
- SSG — Static Site Generator: tools (Hugo, Jekyll, Eleventy) that turn content into static files.
- SSR — Server-Side Rendering: server builds pages on request (Next.js supports both SSG and SSR).
- SEO — Search Engine Optimization: practices that help search engines discover and rank pages.
- CLI — Command-Line Interface: terminal tools like
git,npm, andvercel.
These terms will appear throughout this guide — you’ll see them again when we deploy and when you explore next steps.
1) HTML fundamentals — building the page structure 🧩
HTML is the skeleton of your website. Let’s create a minimal index.html file.
Example: index.html
<!doctype html>
<html lang="en">
<head>
<meta charset="utf-8" />
<meta name="viewport" content="width=device-width,initial-scale=1" />
<title>My First Static Site</title>
<meta name="description" content="A friendly intro to static sites" />
<link rel="stylesheet" href="styles.css" />
</head>
<body>
<header>
<h1>Welcome to My Site</h1>
<nav>
<a href="#">Home</a>
<a href="#about">About</a>
</nav>
</header>
<main>
<section id="about">
<h2>About</h2>
<p>This is a tiny site built for learning.</p>
</section>
</main>
<footer>
<p>Made with ❤️ by you</p>
</footer>
</body>
</html>
### HTML: useful examples & semantics (quick)
- Image with alt and responsive sizes:
```html
<img src="/images/puppy.jpg" alt="Small brown puppy sitting in the grass" width="600" loading="lazy" />
- Accessible link that opens in a new tab (use with rel=“noopener”):
<a href="https://example.com" target="_blank" rel="noopener noreferrer">Learn more</a>
- Simple contact form (using Formspree example — no server required):
<form action="https://formspree.io/f/YOUR_FORM_ID" method="POST">
<label for="email">Email</label>
<input id="email" name="email" type="email" required />
<label for="message">Message</label>
<textarea id="message" name="message" rows="4"></textarea>
<button type="submit">Send</button>
</form>
Explanation: Use semantic tags (<form>, <label>, <input>) for accessibility and validation; third-party form endpoints like Formspree let you collect submissions without your own server.
Important HTML tags to remember:
<!doctype html>— tells browsers this is HTML5<html lang="en">— sets the page language (accessibility/SEO)<head>— contains metadata (title, meta, links)<title>— page title shown on the browser tab<meta name="description">— short description used by search engines<link rel="stylesheet">— connects CSS stylesheets<header>,<main>,<section>,<footer>— semantic tags; improve accessibility and readabilityaltattribute on<img>for accessibility:<img src="photo.jpg" alt="A description" />
Tip: Keep headings in logical order (H1 → H2 → H3) — search engines and screen readers use this.
2) CSS essentials — making it look nice 🎨
CSS (Cascading Style Sheets) controls how HTML looks. Create styles.css and link it from your HTML (we did above).
Example: styles.css
:root {
--bg: #ffffff;
--text: #222;
--accent: #0ea5e9;
}
* { box-sizing: border-box; }
body {
margin: 0;
font-family: system-ui, -apple-system, 'Segoe UI', Roboto, 'Helvetica Neue', Arial;
background: var(--bg);
color: var(--text);
line-height: 1.5;
padding: 1rem;
}
header {
display: flex;
justify-content: space-between;
align-items: center;
margin-bottom: 1rem;
}
h1 { margin: 0; }
a { color: var(--accent); text-decoration: none; }
Core CSS ideas:
- Selectors: target elements to style (e.g.,
p,.class,#id,header nav a) - Properties: the aspect you change (e.g.,
color,background,margin) - Values: the value for that property (e.g.,
#fff,10px,bold) - Variables: using
--name(e.g.,--accent) helps keep colors consistent - Box model: padding, border, margin — learn and test with Developer Tools
Accessibility & responsive basics:
- Add
meta viewport(we did) for mobile-friendly pages - Use readable font sizes and sufficient contrast
- Use
@mediaqueries to adapt layout for smaller screens
Small responsive example (add to styles.css):
@media (max-width: 600px) {
body { padding: 0.5rem; }
header { flex-direction: column; align-items: flex-start; }
}
CSS selectors & a Flexbox example
Selectors let you choose which elements to style. Examples:
- Element selector:
p {}— targets all paragraph tags - Class selector:
.button {}— targets elements with class=“button” - ID selector:
#signup {}— targets the element with id=“signup” - Descendant selector:
nav a {}— targetsainsidenav
Small Flexbox layout example:
.grid { display: flex; gap: 1rem; }
.card { flex: 1 1 200px; padding: 1rem; border-radius: 6px; background:#fafafa }
And a Grid example for two-column layout:
.container { display: grid; grid-template-columns: 1fr 300px; gap: 1rem }
@media (max-width: 700px) { .container { grid-template-columns: 1fr; } }
Learn more on MDN: CSS selectors
3) Step-by-step: Set up a simple project (practical) ✅
Create a folder for your site and three files: index.html, styles.css, and README.md.
Terminal commands (Linux/macOS/Windows with Git Bash):
mkdir my-first-site
cd my-first-site
# create files (use your editor instead of echo for multi-line content)
# For example, open VS Code: code .
If you want to use Git (recommended):
git init
git add .
git commit -m "Initial commit: first static site"
# Create a GitHub repo, then add remote and push:
# git remote add origin [email protected]:yourusername/my-first-site.git
# git push -u origin main
Now open index.html in your browser by double-clicking the file (it will open as a file:// URL) — great for local testing. To see changes quickly, use VS Code Live Server extension (right-click > “Open with Live Server”).
4) Deploy to GitHub Pages (free & simple) 📦
Good for: personal sites, documentation, project pages
A) User/organization site (username.github.io)
- Create a repository named exactly
yourusername.github.io. - Push your files to
mainbranch. - GitHub automatically serves the site at
https://yourusername.github.io.
B) Project site (project pages)
- Create a repo
my-first-site(or any name) - Push code to
mainbranch. In GitHub, go to Settings → Pages and choose “Deploy from a branch” and select main (root). Save. - After a minute or two, the site is available at
https://yourusername.github.io/my-first-site.
Alternate approach: Use a gh-pages branch or the gh-pages npm package to publish build output.
Common things to check:
index.htmlmust exist at the root (or at thedocs/folder if you choose that option)- Custom domain: add
CNAMEfile and set DNS appropriately
Docs: GitHub Pages docs (link in Resources)
Deployment architecture (text graph)
Simple development-to-production flow:
local editor (VS Code) -> git commit -> push to GitHub -> GitHub Pages deploy / CI -> public site (CDN)
Typical runtime architecture for a static site with a backend API:
browser -> CDN -> web server (static files) -> backend API -> database
Tip: When you add client-side JavaScript that fetches APIs, keep CORS and secure API keys in mind. Serverless functions on Vercel or Netlify are useful when you need protected endpoints.
5) Deploy to Vercel (fast CI/CD + preview deployments) ⚡️
Good for: developers who want instant deployments, preview URLs, or serverless features later.
Steps (GUI method)
- Sign up at Vercel and connect your GitHub account.
- Click New Project, import your repo, and follow the defaults — for a static HTML site there is usually no build command.
- Vercel will create automatic deployments for every push — you get a preview link for each PR and a production URL.
CLI method (alternate)
npm i -g vercel
vercel login
cd my-first-site
vercel # follow interactive prompts
Vercel supports custom domains, HTTPS, environment variables, and serverless functions. Great for when you want to grow beyond static content.
Docs: Vercel docs
6) Quick deployment comparison — GitHub Pages vs Vercel
| Feature | GitHub Pages | Vercel |
|---|---|---|
| Cost | Free | Free tier; paid plans for team/scale |
| Easy setup | Very easy (good for simple static files) | Very easy; automatic on push; previews |
| Preview deploys | No built-in previews | Yes, preview deployments per PR |
| Serverless / functions | No | Yes (serverless & edge functions) |
| Custom domain | Yes | Yes |
Pros/Cons of static hosting vs dynamic hosting (short)
-
Pros of static hosting:
- Simpler to set up (no server runtime)
- Very fast when served via CDN
- Lower attack surface — fewer server vulnerabilities
- Usually lower cost or free for small sites
-
Cons of static hosting:
- Not ideal for apps requiring server-side rendering or complex dynamic personalization
- You may need serverless functions or APIs for interactive features (serverless adds complexity)
Alternatives and complements:
- Use an SSG (Static Site Generator) like Hugo, Jekyll, or Eleventy when you want templating, taxonomies, and better authoring workflows.
- Use frameworks like Next.js or Astro for hybrid SSG/SSR and incremental features.
Choose GitHub Pages if you want a super-simple free host for static sites. Choose Vercel if you want previews, easier scaling, or plan to add serverless functionality.
7) Common Pitfalls & Best Practices ⚠️✅
Pitfalls:
- Missing
index.htmlat root (site won’t show) - Using absolute file paths incorrectly (case-sensitive on servers)
- Forgetting
alton images (bad for accessibility) - Not testing on mobile sizes (use responsive checks)
- Adding secrets or credentials to the repo
Best practices:
- Use semantic HTML and meaningful
titleandmeta description - Commit early and push to GitHub — small commits make debugging easier
- Add
.gitignoreto excludenode_modules, etc. - Keep images optimized for web (use appropriate sizes, WebP when possible)
- Use HTTPS and check custom domain DNS settings after adding domain
Extra best practices (expanded)
- Version your content: include a
README.mdwith site setup and deployment instructions so others can reproduce your work. - Optimize images: use responsive
<img srcset>orpictureelements to serve appropriately sized images for different screens. - Automate with CI: use GitHub Actions or Vercel previews to catch build or lint problems early.
- Accessibility: use semantic headings,
aria-*attributes where needed, test with screen readers and Lighthouse. - Performance: minimize CSS/JS and use
link rel="preload"for critical assets when needed.
8) SEO basics for static sites (quick wins) 🔎
- Add a descriptive
<title>and<meta name="description">on each page - Include structured data if relevant (JSON-LD) and Open Graph tags for social previews
- Add a
robots.txtand asitemap.xmlif you have multiple pages - Use descriptive filenames and
altattributes for images - Use semantic headings (H1, H2, etc.) and proper link text
Example minimal SEO head snippet:
<meta name="description" content="A beginner-friendly static site." />
<meta property="og:title" content="My First Site" />
<meta property="og:description" content="A beginner-friendly static site." />
<link rel="canonical" href="https://example.com/" />
9) Next steps — where to go from here 🧭
- Learn JavaScript: add interactivity (buttons, animations, fetching API data)
- Learn responsive design deeply (Flexbox, Grid)
- Learn a static site generator (Hugo, Jekyll, Eleventy) or frameworks (Next.js)
- Add forms (Formspree, Netlify Forms, or serverless functions)
- Measure performance and accessibility using Lighthouse
Recommended learning path:
- HTML & CSS basics → 2. Responsive design → 3. JavaScript basics → 4. Git & deployment → 5. Static site generator or framework
10) Resources & further reading 📚
- MDN Web Docs (HTML)
- MDN Web Docs (CSS)
- GitHub Pages docs
- Vercel docs
- freeCodeCamp
- Lighthouse (performance & accessibility)
Books & courses
- “HTML & CSS: Design and Build Websites” — Jon Duckett (visual, friendly introduction)
- “Learning Web Design” — Jennifer Niederst Robbins (comprehensive beginner book)
- freeCodeCamp (interactive exercises and certification): freeCodeCamp
Useful tools
- Lighthouse (Chrome DevTools audit) — Lighthouse docs
- Image optimization: Squoosh.app and
sharp(npm) - Form handling without server: Formspree
Comments