CSS Tutorial

CSS Forms

Style labels, inputs, and buttons so a form is readable. Keep :focus visible.

A form is a reading task

People fill a booking form in a hurry, often on a phone. CSS should make the label obvious, the field easy to tap, the button clearly the submit, and the focus ring impossible to miss. Harbor studio’s “book a desk” form does not need a novel look. It needs contrast, spacing, and a visible :focus style.

Browsers ship a default look for input and button. You will override font, size, padding, and border so the fields match the page. You should not remove the focus outline without replacing it.

Labels sit with their fields

A label with a matching for / id pair is already clickable: click the words, the field focuses. CSS then stacks them with a small grid or flex column so the label is above the control, not lost to the left on a narrow screen.

Example

<style>
  body {
    font-family: system-ui, sans-serif;
    color: #0c4a6e;
    background: #f0f9ff;
    margin: 1.25rem;
  }
  form {
    max-width: 22rem;
    display: grid;
    gap: 0.85rem;
  }
  .field {
    display: grid;
    gap: 0.3rem;
  }
  label {
    font-weight: 650;
    font-size: 0.9rem;
  }
  input[type="text"],
  input[type="email"] {
    font: inherit;
    padding: 0.55rem 0.7rem;
    border: 1px solid #7dd3fc;
    border-radius: 0.4rem;
    background: #fff;
    color: #0c4a6e;
  }
</style>
<h1>Harbor studio</h1>
<form action="#" method="get">
  <div class="field">
    <label for="guest">Name</label>
    <input id="guest" name="guest" type="text" autocomplete="name">
  </div>
  <div class="field">
    <label for="mail">Email</label>
    <input id="mail" name="mail" type="email" autocomplete="email">
  </div>
</form>

Inherit the page font on inputs. Some browsers default fields to a system serif or a tiny size.font: inherit plus padding makes the tap target closer to 44px high. Try the form at/css/try.

Keep :focus visible

Keyboard users tab from field to field. If you set outline: none and stop there, they cannot tell where they are. Replace the outline with a ring they can see against both the sky page and the white field — a teal offset, for example.

SelectorWhen it matches
:focusThe field is focused, including mouse click
:focus-visibleFocus the browser thinks should be advertised (usually keyboard)
:focus-withinThe element or a descendant is focused — useful on a field wrapper

Example

<style>
  body {
    font-family: system-ui, sans-serif;
    color: #0c4a6e;
    background: #f0f9ff;
    margin: 1.25rem;
  }
  input[type="text"] {
    font: inherit;
    width: 16rem;
    max-width: 100%;
    padding: 0.55rem 0.7rem;
    border: 1px solid #38bdf8;
    border-radius: 0.4rem;
    background: #fff;
  }
  input[type="text"]:focus {
    outline: 3px solid #0d9488;
    outline-offset: 2px;
    border-color: #0d9488;
  }
  label { display: block; font-weight: 650; margin-bottom: 0.3rem; }
</style>
<form action="#" method="get">
  <label for="desk">Desk name</label>
  <input id="desk" name="desk" type="text" value="Tide">
</form>

Click the field. The teal ring should be obvious. Never rely on a 1px border-color change alone — it is easy to miss next to a sky border. Outline plus offset sits outside the box and does not shift layout.

Buttons that look like buttons

A submit control should contrast with the fields. Full teal background, white text, enough padding, and a hover/focus state. Disabled buttons need lower contrast and cursor: not-allowed, and they still must not be the only way to explain why submit is blocked — put that in text too.

Example

<style>
  body {
    font-family: system-ui, sans-serif;
    color: #0c4a6e;
    background: #f0f9ff;
    margin: 1.25rem;
  }
  form {
    display: grid;
    gap: 0.75rem;
    max-width: 20rem;
  }
  label { font-weight: 650; font-size: 0.9rem; }
  input {
    font: inherit;
    padding: 0.5rem 0.65rem;
    border: 1px solid #7dd3fc;
    border-radius: 0.4rem;
  }
  input:focus {
    outline: 3px solid #0d9488;
    outline-offset: 2px;
  }
  button[type="submit"] {
    font: inherit;
    font-weight: 700;
    padding: 0.6rem 1rem;
    border: 0;
    border-radius: 0.45rem;
    background: #0d9488;
    color: #fff;
    cursor: pointer;
  }
  button[type="submit"]:hover {
    background: #0f766e;
  }
  button[type="submit"]:focus-visible {
    outline: 3px solid #0284c7;
    outline-offset: 2px;
  }
  .field { display: grid; gap: 0.3rem; }
</style>
<h1>Book a desk</h1>
<form action="#" method="get">
  <div class="field">
    <label for="when">Date</label>
    <input id="when" name="when" type="text" placeholder="19 Aug">
  </div>
  <button type="submit">Request slot</button>
</form>

A few practical defaults

  • Set box-sizing: border-box so padding does not overflow a width: 100% field.
  • Use max-width: 100% on inputs so they cannot force a horizontal scroll.
  • Group a checkbox with its label on one line: flex, gap, align-items: center.
  • appearance can strip native styling on some controls; if you do that, restyle focus and disabled yourself.

Placeholder text is not a label. It disappears as the user types and is often paler than body copy. Keep a real label, then use placeholder for an example format only.

Worked examples

The short listings above show one property. These sheets paint documents you would actually ship: a lab dashboard, a clinic form, a marks table, a nav bar.

CSS does not invent meaning. HTML already said what the pieces are. Cascade, specificity, and the box model decide how they look. The numbers are classroom values — current, pH, pulse, 3-4-5 — so the style has something real to sit on.

Preview them in the CSS editor at /css/try. Change one property and watch the page paint. The tags stay the same.

Biology

A field that shows focus

Inputs need padding, a visible border, and :focus outline. Placeholder is not a label. colour contrast on the value matters more than a trendy hairline border.

Buttons should look like buttons. Disabled is a state with opacity or grey — and aria if you script it.

Example

<style>
  input { border: 1px solid #0d9488; padding: 0.4rem 0.6rem; }
  input:focus { outline: 2px solid teal; }
</style>
<label>Email <input type="email" name="email" placeholder="you@clinic.test"></label>

Chemistry

A mass field on a bench laptop

tabular-nums and a decent font-size stop 18.0 looking like 180. min-width on the input helps a gloved user hit the target.

Example

<style>
  input { font-size: 1.1rem; font-variant-numeric: tabular-nums; min-width: 8ch; }
</style>
<label>Mass / g <input type="number" name="g" value="18.0"></label>

FAQ: CSS Forms

Common questions about this page.

What is the StudyGrid CSS tutorial?

The StudyGrid CSS tutorial is a full beginner track: selectors, the box model, text, layout, flex, grid, and responsive design. Each chapter has copy-and-preview examples.

Should I run css forms examples locally for better learning?

Yes. Use the browser editor on StudyGrid for a quick check, then Download the example and run it on your computer. Local runs show real errors and the real toolchain, which is one of the fastest ways to learn css forms in this CSS CSS lesson (CSS Forms).

Is the CSS editor the same as Try HTML?

No. Try CSS is a stylesheet preview at /css/try. Try HTML stays at /html/try. CSS lessons never open the HTML-only editor or the Python editor.

Do I need to install anything to learn CSS?

No. Open a chapter, click Try it in CSS, and the page preview updates in the browser.

Where should I start the CSS tutorial?

Start at CSS Intro, then Syntax, Selectors, and How To. After colors and the box model, continue to flex, grid, and media queries. Use Next at the bottom of each chapter.

Is the CSS tutorial free?

Yes. The CSS studio on StudyGrid (studygrid.in) is free: dashboard, chapters, and the live preview editor.