<html><head><base href="https://tip-calculator.example.com#about">
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Enhanced Star Rating Component</title>
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.5.1/css/all.min.css" integrity="sha512-DTOQO9RWCH3ppGqcWaEA1BIZOC6xxalwEsw9c2QQeAIftl+Vegovlnee1c9QX4TctnWMn13TZye+giMm8e2LwA==" crossorigin="anonymous" referrerpolicy="no-referrer">
<style>
* {
margin: 0;
padding: 0;
box-sizing: border-box;
font-family: 'Arial', sans-serif;
}
body {
background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
min-height: 100vh;
display: flex;
justify-content: center;
align-items: center;
text-align: center;
color: #ffffff;
}
.container {
background: rgba(255, 255, 255, 0.1);
backdrop-filter: blur(10px);
border-radius: 20px;
padding: 40px;
box-shadow: 0 8px 32px 0 rgba(31, 38, 135, 0.37);
}
h1 {
margin-bottom: 30px;
font-size: 2.5em;
text-shadow: 2px 2px 4px rgba(0,0,0,0.1);
}
.star-rating-container {
display: flex;
justify-content: center;
align-items: center;
margin: 30px 0;
}
.fa-star-o::before,
.fa-star::before {
font-size: 50px;
transition: all 0.3s ease;
}
.fa-star-o::before {
content: '\f006';
color: rgba(255, 255, 255, 0.5);
}
.fa-star::before {
content: '\f005';
color: #ffd700;
}
.fa-star:hover {
cursor: pointer;
transform: scale(1.2);
}
.selected-rating-container {
display: flex;
gap: 10px;
justify-content: center;
align-items: center;
font-size: 20px;
font-weight: bold;
}
.selected-rating-value {
background: rgba(255, 255, 255, 0.2);
border-radius: 50%;
width: 40px;
height: 40px;
display: flex;
justify-content: center;
align-items: center;
font-size: 24px;
}
@keyframes pulse {
0% {
transform: scale(1);
}
50% {
transform: scale(1.1);
}
100% {
transform: scale(1);
}
}
.pulse {
animation: pulse 0.5s ease-in-out;
}
</style>
</head>
<body>
<div class="container">
<h1>Enhanced Star Rating</h1>
<div class="star-rating-container">
<i class="fa fa-star-o" data-rating="1"></i>
<i class="fa fa-star-o" data-rating="2"></i>
<i class="fa fa-star-o" data-rating="3"></i>
<i class="fa fa-star-o" data-rating="4"></i>
<i class="fa fa-star-o" data-rating="5"></i>
</div>
<div class="selected-rating-container">
<p>Your rating:</p>
<p class="selected-rating-value">0</p>
</div>
</div>
<script>
const stars = document.querySelectorAll(".fa-star-o, .fa-star");
const selectedRatingValueText = document.querySelector(".selected-rating-value");
let currentTotalSelectedStars = 0;
stars.forEach((starItem, index) => {
starItem.addEventListener("mouseover", handleMouseOver);
starItem.addEventListener("click", handleOnClick);
starItem.addEventListener("mouseleave", handleMouseLeave);
});
function handleMouseOver(event) {
const currentRatingValue = event.target.dataset.rating;
handleUpdateRatingState(currentRatingValue);
}
function handleUpdateRatingState(getCurrentRatingValue) {
stars.forEach((star, index) => {
if (index < getCurrentRatingValue) {
star.classList.replace("fa-star-o", "fa-star");
} else {
star.classList.replace("fa-star", "fa-star-o");
}
});
}
function handleOnClick(event) {
const currentRatingValue = event.target.dataset.rating;
currentTotalSelectedStars = currentRatingValue;
handleUpdateRatingState(currentTotalSelectedStars);
selectedRatingValueText.textContent = currentTotalSelectedStars;
// Add pulse animation
selectedRatingValueText.classList.add('pulse');
setTimeout(() => {
selectedRatingValueText.classList.remove('pulse');
}, 500);
}
function handleMouseLeave() {
handleUpdateRatingState(currentTotalSelectedStars);
}
// Hover effect
stars.forEach(star => {
star.addEventListener('mouseenter', () => {
star.style.transform = 'scale(1.2)';
});
star.addEventListener('mouseleave', () => {
star.style.transform = 'scale(1)';
});
});
// Keyboard accessibility
stars.forEach((star, index) => {
star.setAttribute('tabindex', '0');
star.addEventListener('keydown', (e) => {
if (e.key === 'Enter' || e.key === ' ') {
handleOnClick({ target: star });
}
});
});
</script>
</body>
</html>