Loading...

CSS Mini Project — Styled Landing Page

The CSS Summary mapped your toolkit. This session uses it. You will assemble one small styled landing page by hand: identity bar, hero with a clear call-to-action, a few feature cards, and a quiet footer. No new exotic property — only joining skills you already practiced (cascade, box model, Flex, Grid, responsive, focus).

Direct answer

1) Sketch sections first: header + nav, hero + CTA, features, footer.
2) Mark them with semantic HTML (header, nav, main, section, footer) inside a max-width container.
3) Put shared colors, spacing, and radius on :root custom properties.
4) Use Flex for the top bar and hero row; use Grid for the feature cards.
5) Add one media-query breakpoint and keep :focus-visible on links and the CTA.
6) Done means the page reads well on a narrow viewport and Tab still shows focus — not that every CSS trick appears once.

Build order for this landing

📊 Landing sections and CSS jobs

Section HTML job CSS job
Header + nav Site name + in-page links Flex row, gap, calm background
Hero Headline, short pitch, primary CTA Flex or stack; strong contrast; clear button
Features Three short cards Grid with even tracks and gap
Footer Contact or legal line Quiet padding; readable muted text
Shared tokens — :root colors, space, radius reused everywhere
Responsive check Viewport meta already in HTML One breakpoint that stacks hero/cards

Wire the structure before decorating. Pretty gradients on a soup of divs are harder to fix than a plain semantic shell with calm CSS.

Step 1 — Semantic shell

Start with landmarks. Classes refine look; elements name regions for readers and assistive tech.

Landing landmarks shell

html
<body>
<header class="site-header">
<div class="container header-inner">
<a class="logo" href="#">BrightDesk</a>
<nav class="site-nav" aria-label="Primary">
<a href="#features">Features</a>
<a href="#contact">Contact</a>
</nav>
</div>
</header>

<main>
<section class="hero">
<div class="container hero-inner">
<div class="hero-copy">
<h1>Ship a calm landing with CSS you already know</h1>
<p class="lede">Flex the bar, Grid the cards, keep focus visible.</p>
<a class="btn" href="#features">See features</a>
</div>
</div>
</section>

<section id="features" class="features">
<div class="container">
<h2>What you practice</h2>
<div class="feature-grid">
<article class="card"><h3>Tokens</h3><p>Shared color and space.</p></article>
<article class="card"><h3>Layout</h3><p>Flex and Grid on purpose.</p></article>
<article class="card"><h3>Polish</h3><p>Breakpoint and focus.</p></article>
</div>
</div>
</section>
</main>

<footer id="contact" class="site-footer">
<div class="container">
<p>Practice page — style by hand before frameworks.</p>
</div>
</footer>
</body>

Keep the English demo copy short. Your own project can use any product name — the structure matters more than the brand story.

Step 2 — Design tokens on :root

Pull repeated values into custom properties so the palette and spacing stay consistent when you tweak the page.

Shared tokens for the landing

css
:root {
--bg: #0b1220;
--surface: #111827;
--text: #f8fafc;
--muted: #cbd5e1;
--accent: #38bdf8;
--accent-ink: #0c4a6e;
--radius: 0.75rem;
--space: 1rem;
--max: 960px;
--focus: #fbbf24;
}

*,
*::before,
*::after {
box-sizing: border-box;
}

body {
margin: 0;
font-family: system-ui, sans-serif;
line-height: 1.5;
background: var(--bg);
color: var(--text);
}

.container {
width: 100%;
max-width: var(--max);
margin: 0 auto;
padding: 0 var(--space);
}

Tokens are not decoration — they stop copy-paste drift. Change --accent once and the CTA, links, and focus cues can stay aligned.

Step 3 — Flex for header and nav

A one-dimensional row is a Flex job: logo on one side, links on the other, consistent gap.

Flex header bar

css
.site-header {
background: var(--surface);
border-bottom: 1px solid #1f2937;
}

.header-inner {
display: flex;
flex-wrap: wrap;
align-items: center;
justify-content: space-between;
gap: var(--space);
padding: 0.75rem 0;
}

.logo {
color: var(--text);
font-weight: 700;
text-decoration: none;
}

.site-nav {
display: flex;
flex-wrap: wrap;
gap: 1rem;
}

.site-nav a {
color: var(--muted);
text-decoration: none;
}

.site-nav a:hover {
color: var(--accent);
}

flex-wrap keeps the bar honest on narrow screens before your media query stacks larger sections.

Step 4 — Hero band

Give the pitch room, keep contrast strong, and make the CTA look like the primary action.

Hero copy and primary CTA

css
.hero {
padding: 3rem 0 2.5rem;
background:
radial-gradient(circle at top right, #1e3a5f 0%, transparent 45%),
var(--bg);
}

.hero-inner {
display: flex;
flex-direction: column;
gap: 1.25rem;
max-width: 40rem;
}

.hero h1 {
margin: 0;
font-size: clamp(1.75rem, 4vw, 2.5rem);
line-height: 1.15;
}

.lede {
margin: 0;
color: var(--muted);
font-size: 1.05rem;
}

.btn {
display: inline-block;
width: fit-content;
padding: 0.75rem 1.25rem;
border-radius: var(--radius);
background: var(--accent);
color: var(--accent-ink);
font-weight: 700;
text-decoration: none;
}

.btn:hover {
filter: brightness(1.05);
}

clamp on the headline is a small modern touch from earlier lessons — useful, not mandatory. The CTA must stay readable: accent background with darker ink, not pale-on-pale.

Step 5 — Grid for feature cards

Two axes (rows and columns of equal cards) belong to Grid. Keep card padding and border calm.

Feature cards with Grid

css
.features {
padding: 2rem 0 3rem;
}

.features h2 {
margin: 0 0 1rem;
}

.feature-grid {
display: grid;
grid-template-columns: 1fr;
gap: var(--space);
}

.card {
padding: 1.25rem;
border-radius: var(--radius);
background: var(--surface);
border: 1px solid #1f2937;
}

.card h3 {
margin: 0 0 0.5rem;
font-size: 1.1rem;
}

.card p {
margin: 0;
color: var(--muted);
}

.site-footer {
padding: 1.5rem 0 2rem;
border-top: 1px solid #1f2937;
color: var(--muted);
font-size: 0.95rem;
}

On mobile, one column is fine. Widen the grid at a breakpoint — do not invent a third layout system for three cards.

Step 6 — Breakpoint and visible focus

One honest breakpoint plus focus rings finishes the practice page. Keyboard users must still see where they are.

Widen cards and keep focus visible

css
@media (min-width: 640px) {
.feature-grid {
grid-template-columns: repeat(3, 1fr);
}

.hero {
padding-top: 4rem;
}
}

a:focus-visible,
.btn:focus-visible {
outline: 3px solid var(--focus);
outline-offset: 3px;
}

You already studied accessibility styles in depth. Here you only apply the habit: never ship a pretty CTA that loses its focus cue.

Try it yourself

  1. Create index.html + styles.css and paste the landmark shell; link the stylesheet.
  2. Add the :root tokens and body/container rules; confirm the page is centered and readable.
  3. Style the header with Flex and the feature cards with Grid (one column, then three from 640px).
  4. Style the CTA; Tab through logo, nav, and button — focus must stay visible.
  5. Resize to a phone width: no horizontal scroll, stacked cards, usable tap targets.
  6. Optional stretch: add prefers-reduced-motion if you attach a hover transition on .btn.

Common mistakes

  • Opening a component library before you can hand-style this small page
  • Painting every section with position: absolute instead of Flex/Grid flow
  • Skipping max-width on the container so lines stretch edge-to-edge on large screens
  • Removing focus outlines “for design” on the CTA and nav links
  • Adding five breakpoints for three cards instead of one clear widen step
  • Forgetting last lessons: summary mapped skills; accessibility demanded visible focus — both still apply here

Summary

  • This mini project joins course skills into one styled landing page
  • Structure first (landmarks), then tokens, Flex bar, Grid cards, breakpoint, focus
  • Flex for one-dimensional chrome; Grid for the feature matrix
  • Done means readable on mobile and keyboard-safe — not framework-ready scaffolding
  • Next (optional advanced): CSS !important (important) if you want deeper cascade edge cases; otherwise practice more small pages by hand

🧠 Test Your Knowledge

Ready to Start

Test Your Knowledge

Challenge yourself with this interactive quiz and see how well you understand the topic

❓
7
Questions
🎯
70%
To Pass
♾️
∞
Time
🔄
∞
Attempts

📝 Instructions

  • Read each question carefully
  • Select the best answer for each question
  • You can retake the quiz as many times as you want
  • Your progress will be shown at the top