CSS Tutorial
CSS Project: Styled Form
A contact form with stacked labels, padded inputs, and a focus ring that does not hide the outline.
What you will build
A contact card for Harbor studio: name, email, a short note, and a send button. Labels sit above their fields, not beside them. Inputs have padding you can actually tap. Focus draws a sky ring. The outline is not removed.
This is a styling project. The form does not need a server. Keep real label andfor pairs so the fields stay usable when CSS is late or off.
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 |
|---|---|
display: flex on the form | Stacks fields with a consistent gap |
| input / textarea padding and border | Makes the hit area large and the edge visible |
:focus-visible | A ring that does not replace a missing outline with nothing |
| button background and radius | Matches the Harbor primary control |
width: 100% | Fields fill the card on a phone |
If you set outline: none, you must put a visible ring back. This page keeps the outline and adds a box-shadow so the focus is obvious on sky and on white.
Build in slices
First one labeled field. The label is a block. The input is full width with padding and a navy-tinted border.
Example
<style>
body { font-family: system-ui, sans-serif; background: #e0f2fe; color: #0c4a6e; margin: 1.5rem; }
label { display: block; font-weight: 700; margin-bottom: 0.35rem; }
input {
width: 100%;
font: inherit;
padding: 0.65rem 0.75rem;
border: 1px solid #7dd3fc;
border-radius: 0.5rem;
background: #fff;
color: #0c4a6e;
}
</style>
<label for="name">Name</label>
<input id="name" name="name" type="text" autocomplete="name">Then stack the rest and style focus plus the button. The ring uses the same sky as the rest of the studio.
Example
<style>
form { display: flex; flex-direction: column; gap: 0.9rem; }
input:focus-visible,
textarea:focus-visible,
button:focus-visible {
outline: 3px solid #38bdf8;
outline-offset: 2px;
box-shadow: 0 0 0 4px rgba(2, 132, 199, 0.2);
}
textarea { min-height: 7rem; resize: vertical; }
button {
font: inherit;
font-weight: 700;
padding: 0.7rem 1rem;
border: 0;
border-radius: 0.5rem;
background: #0284c7;
color: #fff;
cursor: pointer;
}
button:hover { background: #0369a1; }
</style>Click into each field at /css/try, then tab. If focus disappears, you hid the outline and forgot the ring.
Complete page
A finished contact card for table notes and print questions. Labels stay stacked. The textarea shares the same padding and radius as the inputs. The button is the last control, full width.
Example
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<title>Harbor studio — write to us</title>
<style>
* { box-sizing: border-box; }
body {
margin: 0;
min-height: 100vh;
display: grid;
place-items: center;
background: #e0f2fe;
font-family: system-ui, sans-serif;
color: #0c4a6e;
padding: 1.5rem;
}
.card {
width: min(26rem, 100%);
background: #fff;
border-radius: 1.1rem;
padding: 1.5rem 1.4rem 1.55rem;
box-shadow: 0 14px 30px rgba(12, 74, 110, 0.12);
}
h1 { margin: 0 0 0.3rem; font-size: 1.45rem; }
.lead { margin: 0 0 1.1rem; color: #075985; }
form { display: flex; flex-direction: column; gap: 0.9rem; }
label { display: block; font-weight: 700; margin-bottom: 0.35rem; }
input,
textarea {
width: 100%;
font: inherit;
padding: 0.65rem 0.75rem;
border: 1px solid #7dd3fc;
border-radius: 0.5rem;
background: #fff;
color: #0c4a6e;
}
textarea { min-height: 7rem; resize: vertical; }
input:focus-visible,
textarea:focus-visible,
button:focus-visible {
outline: 3px solid #38bdf8;
outline-offset: 2px;
box-shadow: 0 0 0 4px rgba(2, 132, 199, 0.2);
}
button {
font: inherit;
font-weight: 700;
padding: 0.7rem 1rem;
border: 0;
border-radius: 0.5rem;
background: #0284c7;
color: #fff;
cursor: pointer;
}
button:hover { background: #0369a1; }
</style>
</head>
<body>
<section class="card">
<h1>Write to Harbor studio</h1>
<p class="lead">Tables, print runs, and workshop questions. We read notes before 16:00.</p>
<form action="#" method="post">
<p>
<label for="name">Name</label>
<input id="name" name="name" type="text" autocomplete="name" required>
</p>
<p>
<label for="email">Email</label>
<input id="email" name="email" type="email" autocomplete="email" required>
</p>
<p>
<label for="note">Note</label>
<textarea id="note" name="note" required></textarea>
</p>
<button type="submit">Send note</button>
</form>
</section>
</body>
</html>Practice tasks
- Add a telephone field with
type="tel"and a stacked label. Match the same padding as email. - Change the focus ring to navy
#0c4a6eand check contrast on the white card. - Disable the button with a
disabledattribute and style that state so it is obviously not clickable. Preview at /css/try.