Skip to main content
⚡ Calmops

Building Your First Static Website: From HTML & CSS Fundamentals to Seamless Deployment on GitHub Pages or Vercel

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 Setup article 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, and vercel.

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 readability
  • alt attribute 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 @media queries 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 {} — targets a inside nav

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)

  1. Create a repository named exactly yourusername.github.io.
  2. Push your files to main branch.
  3. GitHub automatically serves the site at https://yourusername.github.io.

B) Project site (project pages)

  1. Create a repo my-first-site (or any name)
  2. Push code to main branch. In GitHub, go to Settings → Pages and choose “Deploy from a branch” and select main (root). Save.
  3. 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.html must exist at the root (or at the docs/ folder if you choose that option)
  • Custom domain: add CNAME file 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)

  1. Sign up at Vercel and connect your GitHub account.
  2. Click New Project, import your repo, and follow the defaults — for a static HTML site there is usually no build command.
  3. 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.html at root (site won’t show)
  • Using absolute file paths incorrectly (case-sensitive on servers)
  • Forgetting alt on 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 title and meta description
  • Commit early and push to GitHub — small commits make debugging easier
  • Add .gitignore to exclude node_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.md with site setup and deployment instructions so others can reproduce your work.
  • Optimize images: use responsive <img srcset> or picture elements 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.txt and a sitemap.xml if you have multiple pages
  • Use descriptive filenames and alt attributes 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:

  1. HTML & CSS basics → 2. Responsive design → 3. JavaScript basics → 4. Git & deployment → 5. Static site generator or framework

10) Resources & further reading 📚

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

Comments