On this page
Feedback forms tell you what customers love, what confuses them and what's broken. The best ones are short, quick to answer and ask the right questions. In this tutorial you'll build one with a star rating, a 0–10 score and a comment box — using only HTML and CSS.
Decide what you want to learn
Before building, write down the one decision this feedback will help you make. That keeps the form short. Common goals:
- Satisfaction — "How was your experience?" (star rating)
- Loyalty — "How likely are you to recommend us?" (0–10 score)
- Insight — "What's one thing we could improve?" (open text)
Three questions is plenty. Ask anything optional after the important ones.
The HTML
<form class="feedback" action="https://api.formclick.io/submit" method="POST">
<input type="hidden" name="access_key" value="YOUR_ACCESS_KEY">
<input type="hidden" name="subject" value="New feedback">
<input type="hidden" name="page" value="checkout">
<input type="checkbox" name="botcheck" class="hp" tabindex="-1" autocomplete="off">
<h2>How did we do?</h2>
<fieldset class="stars">
<legend>Rate your experience</legend>
<input type="radio" id="s5" name="rating" value="5" required>
<label for="s5" title="5 stars">★<span class="sr">5 stars</span></label>
<input type="radio" id="s4" name="rating" value="4">
<label for="s4" title="4 stars">★<span class="sr">4 stars</span></label>
<input type="radio" id="s3" name="rating" value="3">
<label for="s3" title="3 stars">★<span class="sr">3 stars</span></label>
<input type="radio" id="s2" name="rating" value="2">
<label for="s2" title="2 stars">★<span class="sr">2 stars</span></label>
<input type="radio" id="s1" name="rating" value="1">
<label for="s1" title="1 star">★<span class="sr">1 star</span></label>
</fieldset>
<fieldset class="nps">
<legend>How likely are you to recommend us to a friend?</legend>
<div class="scale">
<label><input type="radio" name="recommend" value="0"><span>0</span></label>
<label><input type="radio" name="recommend" value="1"><span>1</span></label>
<label><input type="radio" name="recommend" value="2"><span>2</span></label>
<label><input type="radio" name="recommend" value="3"><span>3</span></label>
<label><input type="radio" name="recommend" value="4"><span>4</span></label>
<label><input type="radio" name="recommend" value="5"><span>5</span></label>
<label><input type="radio" name="recommend" value="6"><span>6</span></label>
<label><input type="radio" name="recommend" value="7"><span>7</span></label>
<label><input type="radio" name="recommend" value="8"><span>8</span></label>
<label><input type="radio" name="recommend" value="9"><span>9</span></label>
<label><input type="radio" name="recommend" value="10"><span>10</span></label>
</div>
<div class="ends"><span>Not likely</span><span>Very likely</span></div>
</fieldset>
<div class="field">
<label for="comments">What's one thing we could do better?</label>
<textarea id="comments" name="comments" rows="4"></textarea>
</div>
<div class="field">
<label for="email">Email <span class="opt">(optional — if you'd like a reply)</span></label>
<input id="email" name="email" type="email" autocomplete="email">
</div>
<button type="submit">Send feedback</button>
</form>
<script src="https://cdn.formclick.io/formclick.min.js"></script>
Note the hidden page field — it records where the feedback came from, so you can tell checkout feedback from homepage feedback without asking.
The CSS (including a CSS-only star rating)
.feedback {
max-width: 520px;
margin: 40px auto;
padding: 32px;
background: #fff;
border: 1px solid #e6e6f0;
border-radius: 20px;
font-family: system-ui, sans-serif;
}
.feedback h2 { margin: 0 0 20px; }
fieldset { border: 0; padding: 0; margin: 0 0 24px; }
legend { font-weight: 600; margin-bottom: 10px; }
/* Stars: inputs are in reverse order (5 → 1) so the ~ selector
can colour every star "below" the hovered or checked one. */
.stars { display: flex; flex-direction: row-reverse; justify-content: flex-end; gap: 4px; }
.stars legend { width: 100%; }
.stars input { position: absolute; opacity: 0; }
.stars label {
font-size: 34px;
line-height: 1;
color: #d4d4e0;
cursor: pointer;
transition: color .1s, transform .1s;
}
.stars label:hover,
.stars label:hover ~ label,
.stars input:checked ~ label { color: #f5b301; }
.stars label:hover { transform: scale(1.1); }
.stars input:focus-visible + label { outline: 2px solid #645cec; border-radius: 4px; }
/* 0–10 scale */
.scale { display: grid; grid-template-columns: repeat(11, 1fr); gap: 4px; }
.scale input { position: absolute; opacity: 0; }
.scale span {
display: block;
padding: 10px 0;
text-align: center;
font-weight: 600;
border: 1px solid #d4d4e0;
border-radius: 8px;
cursor: pointer;
}
.scale input:checked + span { background: #645cec; border-color: #645cec; color: #fff; }
.scale input:focus-visible + span { outline: 2px solid #645cec; outline-offset: 2px; }
.ends { display: flex; justify-content: space-between; margin-top: 6px; font-size: 13px; color: #64748b; }
.field { margin-bottom: 18px; }
.field label { display: block; font-weight: 600; margin-bottom: 6px; }
.opt { font-weight: 400; color: #64748b; }
.field input, .field textarea {
width: 100%;
padding: 12px 14px;
font: inherit;
border: 1px solid #d4d4e0;
border-radius: 10px;
}
button {
width: 100%;
padding: 14px;
font: inherit;
font-weight: 700;
color: #fff;
background: #645cec;
border: 0;
border-radius: 10px;
cursor: pointer;
}
.sr { position: absolute; width: 1px; height: 1px; overflow: hidden; clip: rect(0 0 0 0); }
.hp { display: none; }
@media (max-width: 480px) {
.scale { grid-template-columns: repeat(6, 1fr); }
}
The star rating is still a set of real radio buttons, so it works with the keyboard (arrow keys move between stars) and screen readers announce "5 stars", "4 stars" and so on via the visually hidden text.
Turning responses into insight
Once the form is connected to Formclick, every response is emailed to you and stored in your dashboard. From there you can:
- Download a CSV and calculate your average rating or NPS (percentage of 9–10 scores minus percentage of 0–6 scores).
- Send responses to Google Sheets automatically (Pro plan) and chart them over time.
- Get notified in Discord, or route responses to Slack and other tools through n8n or a webhook, so someone can follow up the same day. See all integrations.
Tips for getting more (and better) feedback
- Ask at the right moment — right after a purchase, a support chat or finishing onboarding.
- Lead with the easiest question. A single tap on a star gets people started.
- Make text optional. Many people will rate but not write — that's still useful.
- Close the loop. If someone leaves an email, reply. It turns critics into fans.
- Keep it anonymous by default for more honest answers.
Want something ready-made? Try our feedback form template, the NPS survey or the website feedback form.



