← Back to the labs
Project Lesson

Build a Responsive Landing Page

We'll assemble a complete page from scratch — a mobile nav that opens from the right, a hero you can build three ways (image, video, or a slideshow), three styles of card, and a footer — and make every piece responsive. Each step has a live demo you can poke at.

Step 1

The plan: anatomy of a landing page

Almost every landing page is the same four stacked regions. We'll build each one, then stack them. Here's the structure we're aiming for:

nav — logo + hamburger (right)
hero — image / video / slideshow
cardcardcard
footer
Build it top to bottom, mobile-first: get one column looking great on a phone, then add breakpoints so the cards spread out and the nav adapts on bigger screens. We'll do exactly that.
Step 2

The semantic skeleton

Start with meaningful HTML landmarks — <header>, <nav>, <main>, <section>, <footer>. Good structure helps screen readers and keeps your CSS sane.

The HTML

<header>
  <a class="logo">Brand</a>
  <button class="burger" aria-label="Open menu"></button>
  <nav class="drawer"></nav>
</header>

<main>
  <section class="hero"></section>
  <section class="cards"></section>
</main>

<footer></footer>

The base CSS (set once for the whole page)

/* reset every element to a predictable starting point */
*, *::before, *::after { box-sizing: border-box; margin: 0; padding: 0; }

body { font-family: system-ui, -apple-system, sans-serif; color: #1f2433; line-height: 1.6; }

img, video { max-width: 100%; display: block; }            media never overflows

main { max-width: 1100px; margin: 0 auto; padding: 0 20px; }  centered content column
Don't forget the viewport tag in the <head>: <meta name="viewport" content="width=device-width, initial-scale=1.0"> — without it, none of the responsive CSS will work on phones.
Step 4

Hero option A — a background image

The simplest, most common hero: a full-width background image, a dark overlay so text stays readable, and a centered heading + call-to-action button.

Welcome to BrightCo

Beautiful sites, built fast.

Get started

The HTML

<section class="hero">
  <div class="overlay"></div>           dark layer for readable text
  <div class="htext">
    <h1>Welcome to BrightCo</h1>
    <p>Beautiful sites, built fast.</p>
    <a class="cta" href="#">Get started</a>
  </div>
</section>

The CSS

.hero {
  background: url('photo.jpg') center/cover;
  min-height: 60vh; display: grid; place-items: center;
  position: relative; text-align: center;
}
.hero .overlay { position: absolute; inset: 0;
  background: linear-gradient(rgba(15,23,42,.25), rgba(15,23,42,.7)); }
center/cover keeps the image filling the hero without distortion at any screen size. The dark overlay gradient is what guarantees your white text passes contrast over any photo.
Step 5

Hero option B — a background video

Same idea, more motion: a <video> that fills the hero behind the text. It must be muted to autoplay, plus loop and playsinline; a poster shows while it loads.

Motion grabs attention

A looping clip behind your message.

Watch demo
<section class="hero">
  <video class="bg" autoplay muted loop playsinline poster="fallback.jpg">
    <source src="clip.mp4" type="video/mp4">
  </video>
  <div class="overlay"></div>
  <div class="htext"></div>
</section>
.hero video.bg { position: absolute; inset: 0;
  width: 100%; height: 100%; object-fit: cover; }
Be kind to data & battery: keep the clip short and compressed, always set a poster image, and remember some phones won't autoplay — the poster (and your overlay text) must look fine on their own.
Step 6

Hero option C — a slideshow

Show several images (or videos) in rotation. Each slide is stacked in the same spot; only the active one is opaque, and we cross-fade between them. It advances on its own, with dots and arrows to navigate:

Mountains
Waterfall
Forest

The HTML

<div class="slideshow">
  <div class="slide on" style="background-image:url('1.jpg')"><span class="cap">Mountains</span></div>
  <div class="slide"    style="background-image:url('2.jpg')"><span class="cap">Waterfall</span></div>
  <div class="slide"    style="background-image:url('3.jpg')"><span class="cap">Forest</span></div>
  <button class="nav prev"></button>
  <button class="nav next"></button>
  <div class="dots"></div>   dots added by JS
</div>

The CSS

.slide { position: absolute; inset: 0; opacity: 0; transition: opacity .8s; }
.slide.on { opacity: 1; }   JS moves the .on class every few seconds

/* prev / next arrows */
.slideshow .nav { position: absolute; top: 50%; transform: translateY(-50%);
  background: rgba(0,0,0,.4); color: #fff; border: 0; width: 34px; height: 34px; border-radius: 50%; cursor: pointer; }
.slideshow .prev { left: 10px; }   .slideshow .next { right: 10px; }

/* dots */
.slideshow .dots { position: absolute; bottom: 12px; left: 0; right: 0; display: flex; gap: 7px; justify-content: center; }
.slideshow .dots button { width: 10px; height: 10px; border-radius: 50%; border: 0; background: rgba(255,255,255,.5); cursor: pointer; }
.slideshow .dots button.on { background: #fff; }
let i = 0;
const slides = document.querySelectorAll('.slide');
function show(n) {
  slides[i].classList.remove('on');
  i = (n + slides.length) % slides.length;   wrap around
  slides[i].classList.add('on');
}
setInterval(() => show(i + 1), 3500);   auto-advance
A slideshow can mix media — some slides images, one a muted looping video. Keep it to a few slides, always offer manual controls, and don't auto-advance so fast people can't read it.
Step 7

Three cards, three ways

Cards group related content. Here are three common constructions — pick whichever fits your content. They sit in a responsive grid that wraps on small screens:

Image-top card

A photo, then a title, text, and a link. The classic blog/product card.

Read more →

Icon / feature card

An icon, heading, and a line of text. Great for listing features or benefits.

Overlay card

Text laid over the image with a gradient for contrast.

The HTML — three card styles in one grid

<section class="cards">

  <!-- 1 · image-top card -->
  <article class="card c1">
    <div class="pic"></div>
    <div class="body">
      <h4>Image-top card</h4>
      <p>A photo, title, text, and a link.</p>
      <a href="#">Read more →</a>
    </div>
  </article>

  <!-- 2 · icon / feature card -->
  <article class="card c2">
    <div class="ic"><i class="ph ph-rocket-launch"></i></div>
    <h4>Icon / feature card</h4>
    <p>An icon, heading, and a line of text.</p>
  </article>

  <!-- 3 · overlay card (text over the image) -->
  <article class="card c3">
    <div class="body">
      <h4>Overlay card</h4>
      <p>Text laid over the image.</p>
    </div>
  </article>

</section>

The CSS — the responsive grid

.cards { display: grid; gap: 16px;
  grid-template-columns: repeat(auto-fit, minmax(200px, 1fr)); }
.card  { background: #fff; border: 1px solid #e5e7eb; border-radius: 14px; overflow: hidden; }
.card.c3 { position: relative; background: url('photo.jpg') center/cover; display: flex; align-items: flex-end; }
The grid is the responsive trick: grid-template-columns: repeat(auto-fit, minmax(200px, 1fr)) fits as many cards as will comfortably fit and wraps the rest — three across on desktop, one on a phone, no media query needed. Build more variations in the Cards Lab.
Step 9

Tying responsiveness together

Each piece is already fluid; a few deliberate breakpoints make it shine. The pattern across the whole page:

PiecePhoneDesktop
NavHamburger + right drawerInline links (hamburger hidden)
HeroShorter, smaller type (clamp())Tall, large headline
Cards1 column (auto-fit wraps)3 across
FooterColumns stackedMulti-column grid
Two tools do most of it: repeat(auto-fit, minmax(…)) grids that wrap on their own, and a couple of @media (min-width: …) queries for the deliberate changes (showing inline nav, growing the hero). Full depth in the Responsive Design lesson.
Step 10

The whole page, assembled

All four pieces stacked into one responsive page — with the right-side hamburger nav working. Tap the menu, scroll the content, see the hero, cards, and footer in place:

Built in one lesson

Get started
Fast

Loads in a blink.

Responsive

Fits every screen.

Accessible

Works for everyone.

BrightCo© 2026 · Built with the Visual Playground

Landing-page checklist

Where next

The labs & lessons behind each piece