DEV Community

Cover image for Create a simple form and style it with FSCSS
FSCSS tutorial for FSCSS tutorial

Posted on

Create a simple form and style it with FSCSS

A short walkthrough: HTML structure, FSCSS for layout and chrome, then optional polish with tokens and the form module. Everything compiles to plain CSS.


1. Markup first

Keep the form boring and accessible. FSCSS does not replace labels or name attributes.

<form class="contact" action="#" method="post">
  <h1 class="contact__title">Contact</h1>
  <p class="contact__lead">We’ll reply within one business day.</p>

  <label class="field">
    <span class="field__label">Name</span>
    <input class="field__input" type="text" name="name" autocomplete="name" required>
  </label>

  <label class="field">
    <span class="field__label">Email</span>
    <input class="field__input" type="email" name="email" autocomplete="email" required>
  </label>

  <label class="field">
    <span class="field__label">Message</span>
    <textarea class="field__input field__input--area" name="message" rows="4" required></textarea>
  </label>

  <button class="btn" type="submit">Send</button>
</form>
Enter fullscreen mode Exit fullscreen mode

2. Load FSCSS

Prototype (CDN runtime):

<script src="https://cdn.jsdelivr.net/npm/fscss@1.2.6/runtime.min.js" defer></script>
<link type="text/fscss" href="form-page.fscss">
Enter fullscreen mode Exit fullscreen mode

Or compile:

npm install -g fscss@1.2.6
fscss form-page.fscss form-page.css
Enter fullscreen mode Exit fullscreen mode
<link rel="stylesheet" href="form-page.css">
Enter fullscreen mode Exit fullscreen mode

3. Style with layout helpers and tokens

stack, px / py, rounded, and friends (1.2.5+) keep the sheet short. See shorthands.

/* form-page.fscss */
:root {
  --bg: #0b1020;
  --surface: #121a30;
  --border: #22304f;
  --text: #e6edf7;
  --muted: #9fb0d0;
  --accent: #6366f1;
  --radius: 12px;
}

body {
  m: 0;
  min-h: 100vh;
  center: both;
  p: 24px;
  bg: var(--bg);
  color: var(--text);
  ff: system-ui, sans-serif;
}

.contact {
  w: 100%;
  max-w: 400px;
  stack: 16px;
  p: 24px;
  bg: var(--surface);
  border: 1px solid var(--border);
  rounded: 16px;
}

.contact__title {
  m: 0;
  fs: 1.35rem;
}

.contact__lead {
  m: 0;
  color: var(--muted);
  fs: 0.9rem;
}

.field {
  stack: 6px;
}

.field__label {
  fs: 0.8rem;
  color: var(--muted);
}

.field__input {
  w: 100%;
  px: 12px;
  py: 10px;
  rounded: var(--radius);
  border: 1px solid var(--border);
  bg: #0a0f1e;
  color: var(--text);
  font: inherit;
}

.field__input:focus {
  outline: 2px solid var(--accent);
  outline-offset: 2px;
}

.field__input--area {
  resize: vertical;
  min-h: 100px;
}

.btn {
  mt: 4px;
  px: 16px;
  py: 10px;
  border: 0;
  rounded: var(--radius);
  bg: var(--accent);
  color: #fff;
  font: inherit;
  fw: 600;
  cur: pointer;
}

.btn:hover {
  filter: brightness(1.08);
}
Enter fullscreen mode Exit fullscreen mode

What you get after compile: normal flex column + gap, axis padding, radius, and colors—no framework runtime.


4. Optional: reusable button with @define

@define btn(bg: #6366f1){`
  display: inline-flex;
  align-items: center;
  justify-content: center;
  padding: 10px 16px;
  border: 0;
  border-radius: var(--radius, 12px);
  background: @use(bg);
  color: #fff;
  font-weight: 600;
  cursor: pointer;
`}

.btn {
  @btn(var(--accent))
}

.btn-ghost {
  @btn(transparent)
  border: 1px solid var(--border);
  color: var(--text);
}
Enter fullscreen mode Exit fullscreen mode

5. Optional: form.fscss module

When you want float labels and shared field chrome instead of hand-rolled classes:

@import((form-root, form-group, form-input, form-label, form-float, form-btn-primary) from form)

@form-root()
@form-float(.form-group, .form-input, .form-label)
Enter fullscreen mode Exit fullscreen mode

Markup pattern (input before label, placeholder=" " for :placeholder-shown tricks) is documented with the module. Use selective imports so you only pull what the page needs.


6. Optional: semantic styling with pattern() (1.2.4+)

pattern(0.55: "soft dark form card", `
  background: #121a30;
  border: 1px solid #22304f;
  border-radius: 16px;
  padding: 24px;
`)

.contact {
  soft dark form card
  stack: 16px;
  max-w: 400px;
}
Enter fullscreen mode Exit fullscreen mode

Good for role-based phrases; keep critical layout in explicit rules so the form stays predictable.


7. Try it in the IDE

  1. Open fscss.devtem.org/ide
  2. Paste the HTML into an index.html and the FSCSS into form-page.fscss
  3. Ctrl+Enter to compile, preview to check focus states
  4. Export when you’re ready

Checklist

  • Labels associated with controls (wrapping <label> or for / id)
  • :focus styles visible on keyboard
  • Tokens on :root so themes don’t require rewriting fields
  • Production: compiled CSS only, not the runtime

A simple contact form is a good first FSCSS page: one column (stack), a few fields, one button—and the same file can grow into tokens, @define, or a form module without changing the HTML structure.

Top comments (0)