CSS Tutorial
CSS Project: Landing Hero
A full-width hero with a headline, a short lead, two buttons, and a soft gradient background.
What you will build
The opening band of the Harbor studio site. It is full width. A headline, one lead sentence, and two buttons sit in a column on the left of a tall sky-to-navy gradient. Type scales withclamp so the title stays large on a desk and readable on a phone.
A hero is a layout, not a photograph. You can add an image later. This page proves the band, the type, and the two actions first.
Open an example with Try it in CSS. That loads /css/try — a live page preview.
Properties you will use
| Property | Job on this page |
|---|---|
linear-gradient | Paints the full-width band from sky to navy |
display: flex | Stacks the copy and lines up the two buttons |
clamp() | Scales the headline between a floor and a ceiling |
min-height | Gives the hero vertical presence |
gap | Spaces headline, lead, and the button row |
White type on the navy end of the gradient needs a strong weight. Ghost buttons use a white border so they still read as controls.
Build in slices
First the band and the type. No buttons yet. Check that the gradient covers the hero and that the headline uses clamp, not a single fixed size.
Example
<style>
body { margin: 0; font-family: Georgia, serif; }
.hero {
min-height: 70vh;
display: flex;
flex-direction: column;
justify-content: center;
padding: 3rem 1.5rem;
background: linear-gradient(160deg, #0284c7 0%, #0c4a6e 72%);
color: #e0f2fe;
}
h1 {
margin: 0;
font-size: clamp(2rem, 5vw, 3.4rem);
line-height: 1.15;
max-width: 14ch;
}
.lead {
margin: 0.85rem 0 0;
max-width: 36ch;
font-size: clamp(1rem, 2vw, 1.2rem);
color: #e0f2fe;
}
</style>
<section class="hero">
<h1>Print by the water. Coffee at eight.</h1>
<p class="lead">Harbor studio opens with the cafe. Bring a file or a loaf.</p>
</section>Then add the two actions as a flex row. Primary is solid white. Ghost is outlined. Both keep a visible focus ring on the dark band.
Example
<style>
.actions { display: flex; flex-wrap: wrap; gap: 0.7rem; margin-top: 1.4rem; }
.btn {
font: inherit;
font-weight: 700;
padding: 0.7rem 1.15rem;
border-radius: 0.55rem;
text-decoration: none;
border: 2px solid #fff;
}
.btn-solid { background: #fff; color: #0c4a6e; }
.btn-ghost { background: transparent; color: #fff; }
.btn:focus-visible { outline: 3px solid #7dd3fc; outline-offset: 3px; }
</style>
<div class="actions">
<a class="btn btn-solid" href="#book">Book a table</a>
<a class="btn btn-ghost" href="#menu">See the board</a>
</div>Stretch the preview at /css/try. The headline should grow, then stop. If it never changes, clamp is missing or the min and max are the same.
Complete page
Full document: gradient hero, clamp type, two buttons, and two short sections so the hash targets exist. The rest of the page sits on pale sky so you can see where the hero ends.
Example
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<title>Harbor studio — open by the pier</title>
<style>
* { box-sizing: border-box; }
body {
margin: 0;
font-family: Georgia, "Times New Roman", serif;
background: #e0f2fe;
color: #0c4a6e;
}
.hero {
min-height: 78vh;
display: flex;
flex-direction: column;
justify-content: center;
padding: clamp(2rem, 6vw, 4.5rem) clamp(1.25rem, 5vw, 3.5rem);
background: linear-gradient(160deg, #38bdf8 0%, #0284c7 42%, #0c4a6e 100%);
color: #e0f2fe;
}
h1 {
margin: 0;
font-size: clamp(2rem, 5.4vw, 3.5rem);
line-height: 1.12;
max-width: 14ch;
color: #fff;
}
.lead {
margin: 0.9rem 0 0;
max-width: 38ch;
font-size: clamp(1.05rem, 2vw, 1.25rem);
line-height: 1.45;
}
.actions {
display: flex;
flex-wrap: wrap;
gap: 0.7rem;
margin-top: 1.5rem;
}
.btn {
font-family: system-ui, sans-serif;
font-weight: 700;
padding: 0.7rem 1.2rem;
border-radius: 0.55rem;
text-decoration: none;
border: 2px solid #fff;
}
.btn-solid { background: #fff; color: #0c4a6e; }
.btn-ghost { background: transparent; color: #fff; }
.btn:hover { filter: brightness(0.96); }
.btn:focus-visible { outline: 3px solid #7dd3fc; outline-offset: 3px; }
main { max-width: 40rem; margin: 0 auto; padding: 1.75rem 1.25rem 2.4rem; }
h2 { margin: 0 0 0.4rem; }
</style>
</head>
<body>
<section class="hero">
<h1>Print by the water. Coffee at eight.</h1>
<p class="lead">Harbor studio opens with the cafe. Bring a file, a loaf, or a question about the press.</p>
<div class="actions">
<a class="btn btn-solid" href="#book">Book a table</a>
<a class="btn btn-ghost" href="#menu">See the board</a>
</div>
</section>
<main>
<h2 id="book">Book a table</h2>
<p>Window seats face the pier. We hold the 8:30 sitting for people who need the quiet hour.</p>
<h2 id="menu">See the board</h2>
<p>Sourdough, tomato, olive oil. Espresso until the last print dries.</p>
</main>
</body>
</html>Practice tasks
- Reverse the gradient so navy is at the top. Check that the white headline still has contrast.
- Change the clamp ceiling to
2.4remand decide if the hero still feels like a landing band. - Add a third ghost button named Workshops. Confirm the flex row wraps at /css/try.