Custom styled checkboxes with smooth toggle animations
<!-- Basic Checkbox -->
<label class="animated-checkbox">
<input type="checkbox" class="animated-checkbox-input">
<span class="animated-checkbox-check"></span>
<span class="animated-checkbox-label">Basic Option</span>
</label>
<!-- Pre-checked Checkbox -->
<label class="animated-checkbox">
<input type="checkbox" class="animated-checkbox-input" checked>
<span class="animated-checkbox-check"></span>
<span class="animated-checkbox-label">Selected Option</span>
</label>
<!-- Rounded Style -->
<label class="animated-checkbox animated-checkbox-rounded">
<input type="checkbox" class="animated-checkbox-input">
<span class="animated-checkbox-check"></span>
<span class="animated-checkbox-label">Rounded Style</span>
</label>
<!-- Pill Style -->
<label class="animated-checkbox animated-checkbox-pill">
<input type="checkbox" class="animated-checkbox-input">
<span class="animated-checkbox-check"></span>
<span class="animated-checkbox-label">Pill Style</span>
</label>
/* Base Styles */
.animated-checkbox {
display: flex;
align-items: center;
cursor: pointer;
margin-bottom: 16px;
user-select: none;
}
.animated-checkbox-input {
position: absolute;
opacity: 0;
cursor: pointer;
height: 0;
width: 0;
}
.animated-checkbox-check {
position: relative;
height: 22px;
width: 22px;
background-color: #fff;
border: 2px solid #ddd;
border-radius: 4px;
margin-right: 10px;
display: flex;
align-items: center;
justify-content: center;
flex-shrink: 0;
transition: all 0.2s ease;
}
/* Checkmark icon */
.animated-checkbox-check::after {
content: '';
position: absolute;
display: none;
width: 6px;
height: 12px;
border: solid white;
border-width: 0 2px 2px 0;
transform: rotate(45deg);
transition: all 0.2s ease;
}
/* Hover and Focus states */
.animated-checkbox:hover .animated-checkbox-check {
border-color: #3498db;
box-shadow: 0 0 0 2px rgba(52, 152, 219, 0.2);
}
.animated-checkbox-input:focus ~ .animated-checkbox-check {
box-shadow: 0 0 0 3px rgba(52, 152, 219, 0.2);
}
/* Checked state */
.animated-checkbox-input:checked ~ .animated-checkbox-check {
background-color: #3498db;
border-color: #3498db;
}
.animated-checkbox-input:checked ~ .animated-checkbox-check::after {
display: block;
animation: checkmark 0.2s ease forwards;
}
@keyframes checkmark {
0% {
opacity: 0;
transform: rotate(45deg) scale(0.8);
}
50% {
opacity: 1;
transform: rotate(45deg) scale(1.2);
}
100% {
opacity: 1;
transform: rotate(45deg) scale(1);
}
}
/* Label styling */
.animated-checkbox-label {
font-size: 16px;
line-height: 1.4;
color: #333;
transition: color 0.2s ease;
}
.animated-checkbox:hover .animated-checkbox-label {
color: #3498db;
}
/* Variant: Rounded style */
.animated-checkbox-rounded .animated-checkbox-check {
border-radius: 50%;
}
/* Variant: Pill style */
.animated-checkbox-pill {
background-color: #f8f9fa;
border-radius: 50px;
padding: 8px 16px;
transition: all 0.3s ease;
}
.animated-checkbox-pill:hover {
background-color: #e9ecef;
}
.animated-checkbox-pill .animated-checkbox-check {
width: 18px;
height: 18px;
}
.animated-checkbox-pill .animated-checkbox-check::after {
width: 5px;
height: 10px;
}
/* Dark mode styles */
@media (prefers-color-scheme: dark) {
.animated-checkbox-check {
background-color: #333;
border-color: #555;
}
.animated-checkbox-label {
color: #f5f5f5;
}
.animated-checkbox:hover .animated-checkbox-check {
border-color: #4dabf7;
box-shadow: 0 0 0 2px rgba(77, 171, 247, 0.3);
}
.animated-checkbox-input:focus ~ .animated-checkbox-check {
box-shadow: 0 0 0 3px rgba(77, 171, 247, 0.3);
}
.animated-checkbox-input:checked ~ .animated-checkbox-check {
background-color: #4dabf7;
border-color: #4dabf7;
}
.animated-checkbox:hover .animated-checkbox-label {
color: #4dabf7;
}
.animated-checkbox-pill {
background-color: #2a2a2a;
}
.animated-checkbox-pill:hover {
background-color: #333;
}
}
// Optional JavaScript for enhanced functionality
document.addEventListener('DOMContentLoaded', function() {
// Get all checkbox inputs
const checkboxes = document.querySelectorAll('.animated-checkbox-input');
// Add keyboard support and additional interaction effects
checkboxes.forEach(checkbox => {
// Add keyboard handler for space and enter keys
checkbox.addEventListener('keydown', function(e) {
if (e.code === 'Space' || e.code === 'Enter') {
e.preventDefault();
this.checked = !this.checked;
// Dispatch change event to trigger any listeners
const event = new Event('change', { bubbles: true });
this.dispatchEvent(event);
// Add ripple effect
addRippleEffect(this);
}
});
// Add click animation
checkbox.addEventListener('change', function() {
addRippleEffect(this);
});
});
// Function to add ripple effect to checkbox
function addRippleEffect(checkbox) {
const label = checkbox.closest('.animated-checkbox');
const checkmark = label.querySelector('.animated-checkbox-check');
// Remove any existing ripple
const existingRipple = checkmark.querySelector('.ripple');
if (existingRipple) {
existingRipple.remove();
}
// Create ripple element
const ripple = document.createElement('span');
ripple.classList.add('ripple');
checkmark.appendChild(ripple);
// Calculate ripple size (larger of width or height * 2.5)
const size = Math.max(checkmark.offsetWidth, checkmark.offsetHeight) * 2.5;
ripple.style.width = size + 'px';
ripple.style.height = size + 'px';
// Position ripple in center
ripple.style.left = -(size - checkmark.offsetWidth) / 2 + 'px';
ripple.style.top = -(size - checkmark.offsetHeight) / 2 + 'px';
// Remove ripple after animation
setTimeout(() => {
ripple.remove();
}, 600);
}
// Add custom ripple styles
const style = document.createElement('style');
style.textContent = `
.animated-checkbox-check {
overflow: hidden;
position: relative;
}
.ripple {
position: absolute;
background-color: rgba(52, 152, 219, 0.3);
border-radius: 50%;
transform: scale(0);
animation: ripple 0.6s linear;
pointer-events: none;
}
@keyframes ripple {
to {
transform: scale(1);
opacity: 0;
}
}
@media (prefers-color-scheme: dark) {
.ripple {
background-color: rgba(77, 171, 247, 0.3);
}
}
`;
document.head.appendChild(style);
});