A star rating feedback form is a popular, intuitive way to collect user opinions, commonly seen on e-commerce platforms, review sites, and service-oriented websites. This comprehensive guide will walk you through creating a modern, interactive star rating feedback form using HTML, CSS, and JavaScript. The form will feature a visually appealing star rating system, a text input for comments, and submission functionality, all designed to be responsive and accessible. We’ll also explore free AI tools to enhance development and provide a complete code example to get you started.
Star rating forms are effective because they:
Unlike complex survey forms, star rating systems are concise yet powerful, making them ideal for websites aiming to gather quick user feedback.
Our feedback form will include:
The form consists of a star rating component, a text area for comments, and a submit button, all wrapped in a <form>
element for semantic correctness.
<form id="feedback-form">
<div class="star-rating">
<span class="star" data-value="1">★</span>
<span class="star" data-value="2">★</span>
<span class="star" data-value="3">★</span>
<span class="star" data-value="4">★</span>
<span class="star" data-value="5">★</span>
</div>
<textarea id="comment" placeholder="Enter your feedback (optional)"></textarea>
<button type="submit">Submit Feedback</button>
</form>
<div id="submission-message" style="display: none;"></div>
The CSS creates a visually appealing star rating system with hover effects, a responsive layout, and high-contrast elements for accessibility.
.star-rating {
display: flex;
justify-content: center;
font-size: 30px;
cursor: pointer;
}
.star {
color: #ccc;
transition: color 0.2s;
}
.star:hover, .star:hover ~ .star, .star.active {
color: #ffd700;
}
textarea {
width: 100%;
max-width: 500px;
height: 100px;
margin: 10px 0;
}
button {
background-color: #007bff;
color: white;
padding: 10px 20px;
border: none;
border-radius: 5px;
cursor: pointer;
}
button:hover {
background-color: #0056b3;
}
#submission-message {
color: green;
margin-top: 10px;
}
@media (max-width: 600px) {
.star-rating {
font-size: 24px;
}
textarea {
max-width: 100%;
}
}
JavaScript handles star selection, hover effects, form submission, and accessibility. The form submission is simulated with a success message for demonstration purposes.
const stars = document.querySelectorAll('.star');
const form = document.getElementById('feedback-form');
let selectedRating = 0;
stars.forEach(star => {
star.addEventListener('click', () => {
selectedRating = star.dataset.value;
stars.forEach(s => s.classList.remove('active'));
for (let i = 0; i < selectedRating; i++) {
stars[i].classList.add('active');
}
});
star.addEventListener('mouseover', () => {
stars.forEach(s => s.classList.remove('hover'));
for (let i = 0; i < star.dataset.value; i++) {
stars[i].classList.add('hover');
}
});
star.addEventListener('mouseout', () => {
stars.forEach(s => s.classList.remove('hover'));
});
});
form.addEventListener('submit', (e) => {
e.preventDefault();
const comment = document.getElementById('comment').value;
const message = document.getElementById('submission-message');
message.textContent = `Thank you! You rated ${selectedRating} stars. Comment: ${comment || 'None'}`;
message.style.display = 'block';
form.reset();
stars.forEach(s => s.classList.remove('active'));
selectedRating = 0;
});
To ensure accessibility:
role="radiogroup"
and aria-checked
for the star rating.
const starContainer = document.querySelector('.star-rating');
starContainer.setAttribute('role', 'radiogroup');
stars.forEach((star, index) => {
star.setAttribute('role', 'radio');
star.setAttribute('aria-checked', 'false');
star.setAttribute('tabindex', index === 0 ? '0' : '-1');
});
starContainer.addEventListener('keydown', (e) => {
if (e.key === 'ArrowRight' || e.key === 'ArrowUp') {
e.preventDefault();
selectedRating = Math.min(selectedRating + 1, 5);
updateStars();
} else if (e.key === 'ArrowLeft' || e.key === 'ArrowDown') {
e.preventDefault();
selectedRating = Math.max(selectedRating - 1, 1);
updateStars();
}
});
function updateStars() {
stars.forEach(s => {
s.classList.remove('active');
s.setAttribute('aria-checked', 'false');
s.setAttribute('tabindex', '-1');
});
for (let i = 0; i < selectedRating; i++) {
stars[i].classList.add('active');
stars[i].setAttribute('aria-checked', 'true');
}
stars[selectedRating - 1].setAttribute('tabindex', '0');
stars[selectedRating - 1].focus();
}
For mobile users, ensure the form is touch-friendly:
To streamline development, consider these free AI tools:
Below is the complete code for the star rating feedback form, incorporating all features discussed.
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Star Rating Feedback Form</title>
<style>
body {
font-family: Arial, sans-serif;
margin: 0;
padding: 20px;
background-color: #f0f0f0;
display: flex;
justify-content: center;
align-items: center;
min-height: 100vh;
}
.feedback-container {
background: white;
padding: 20px;
border-radius: 10px;
box-shadow: 0 0 10px rgba(0, 0, 0, 0.1);
max-width: 600px;
width: 100%;
text-align: center;
}
.star-rating {
display: flex;
justify-content: center;
font-size: 30px;
cursor: pointer;
margin-bottom: 20px;
}
.star {
color: #ccc;
transition: color 0.2s;
}
.star:hover, .star.active, .star.hover {
color: #ffd700;
}
textarea {
width: 100%;
max-width: 500px;
height: 100px;
margin: 10px 0;
border: 1px solid #ccc;
border-radius: 5px;
padding: 10px;
}
button {
background-color: #007bff;
color: white;
padding: 10px 20px;
border: none;
border-radius: 5px;
cursor: pointer;
font-size: 16px;
}
button:hover {
background-color: #0056b3;
}
#submission-message {
color: green;
margin-top: 10px;
font-size: 16px;
}
@media (max-width: 600px) {
.star-rating {
font-size: 24px;
}
textarea {
max-width: 100%;
}
.feedback-container {
padding: 15px;
}
}
</style>
</head>
<body>
<div class="feedback-container">
<h2>Share Your Feedback</h2>
<form id="feedback-form">
<div class="star-rating" role="radiogroup" aria-label="Star rating">
<span class="star" data-value="1" role="radio" aria-checked="false" tabindex="0">★</span>
<span class="star" data-value="2" role="radio" aria-checked="false" tabindex="-1">★</span>
<span class="star" data-value="3" role="radio" aria-checked="false" tabindex="-1">★</span>
<span class="star" data-value="4" role="radio" aria-checked="false" tabindex="-1">★</span>
<span class="star" data-value="5" role="radio" aria-checked="false" tabindex="-1">★</span>
</div>
<textarea id="comment" placeholder="Enter your feedback (optional)" aria-label="Feedback comments"></textarea>
<button type="submit">Submit Feedback</button>
</form>
<div id="submission-message" style="display: none;"></div>
</div>
<script>
const stars = document.querySelectorAll('.star');
const form = document.getElementById('feedback-form');
const starContainer = document.querySelector('.star-rating');
let selectedRating = 0;
stars.forEach(star => {
star.addEventListener('click', () => {
selectedRating = parseInt(star.dataset.value);
updateStars();
});
star.addEventListener('mouseover', () => {
stars.forEach(s => s.classList.remove('hover'));
for (let i = 0; i < star.dataset.value; i++) {
stars[i].classList.add('hover');
}
});
star.addEventListener('mouseout', () => {
stars.forEach(s => s.classList.remove('hover'));
});
});
starContainer.addEventListener('keydown', (e) => {
if (e.key === 'ArrowRight' || e.key === 'ArrowUp') {
e.preventDefault();
selectedRating = Math.min(selectedRating + 1, 5);
updateStars();
} else if (e.key === 'ArrowLeft' || e.key === 'ArrowDown') {
e.preventDefault();
selectedRating = Math.max(selectedRating - 1, 1);
updateStars();
}
});
function updateStars() {
stars.forEach(s => {
s.classList.remove('active');
s.setAttribute('aria-checked', 'false');
s.setAttribute('tabindex', '-1');
});
for (let i = 0; i < selectedRating; i++) {
stars[i].classList.add('active');
stars[i].setAttribute('aria-checked', 'true');
}
if (selectedRating > 0) {
stars[selectedRating - 1].setAttribute('tabindex', '0');
stars[selectedRating - 1].focus();
}
}
form.addEventListener('submit', (e) => {
e.preventDefault();
const comment = document.getElementById('comment').value;
const message = document.getElementById('submission-message');
if (selectedRating === 0) {
message.textContent = 'Please select a star rating.';
message.style.color = 'red';
message.style.display = 'block';
return;
}
message.textContent = `Thank you! You rated ${selectedRating} star${selectedRating > 1 ? 's' : ''}. Comment: ${comment || 'None'}`;
message.style.color = 'green';
message.style.display = 'block';
form.reset();
stars.forEach(s => {
s.classList.remove('active');
s.setAttribute('aria-checked', 'false');
s.setAttribute('tabindex', '-1');
});
stars[0].setAttribute('tabindex', '0');
selectedRating = 0;
});
</script>
</body>
</html>
Creating a star rating feedback form is a practical way to enhance user engagement and collect valuable insights. With vanilla JavaScript, you can build a lightweight, accessible, and responsive form without relying on external libraries. Free AI tools like Grok and platforms like CodePen can accelerate development and testing. Implement the code above, customize it to match your website’s style, and start gathering user feedback today.