Checkbox เริ่มต้นของ Browser จำกัดการจัดสไตล์ ใช้ appearance: none ปิด Native UI แล้วสร้าง Checkbox เองด้วย CSS Pseudo-elements ตัวอย่างนี้แสดง 2 รูปแบบ: Checkbox กลม และ Checkbox กำลังสี่มุมโค้ง
Syntax
selector {
appearance: none;
-webkit-appearance: none;
-moz-appearance: none;
/* Custom Styles */
}
ตัวอย่างที่ 1: Checkbox กลม (Circle) พร้อมข้อความ Checked
<!DOCTYPE html>
<html>
<style>
input[type=checkbox] {
appearance: none;
-webkit-appearance: none;
-moz-appearance: none;
width: 24px;
height: 24px;
padding: 12px;
background-color: cyan;
box-shadow: inset 0 3px 3px 5px lightgreen;
border-radius: 50%;
}
input[type=checkbox]:checked {
background-color: coral;
border: 6px solid cornflowerblue;
box-shadow: 0 1px 2px lightorange;
}
input[type=checkbox]:checked:after {
content: "Checked";
}
</style>
<body>
<input type="checkbox"> Custom Checkbox Example
</body>
</html>
หมายเหตุ
:checked:afterแสดงข้อความ "Checked" แต่ Position ไม่ได้ระบุ (อาจทับเนื้อหา)- Border 6px + Box-shadow สร้างเอฟเฟกต์ Ring รอบนอก
- ควรใช้
width/heightแทนpaddingเพื่อควบคุมขนาดแม่นยำ
ตัวอย่างที่ 2: Checkbox กำลังสี่ + Checkmark Unicode
<!DOCTYPE html>
<html>
<style>
input[type=checkbox] {
appearance: none;
-webkit-appearance: none;
-moz-appearance: none;
width: 20px;
height: 20px;
padding: 10px;
background-color: cyan;
border-radius: 5%;
}
input[type=checkbox]:checked {
background-color: magenta;
}
input[type=checkbox]:checked:before {
content: "\2713"; /* Unicode Checkmark ✓ */
color: white;
padding: initial;
font-weight: bold;
display: flex;
align-items: center;
justify-content: center;
width: 100%;
height: 100%;
}
</style>
<body>
<input type="checkbox"> Another Custom Checkbox Example
</body>
</html>
Unicode Checkmarks
| Char | Unicode | ชื่อ |
|---|---|---|
| ✓ | \2713 | Check Mark |
| ✔ | \2714 | Heavy Check Mark |
| ☑ | \2611 | Ballot Box With Check |
| ✅ | \2705 | White Heavy Check Mark (Emoji) |
Custom Checkbox แบบสมบูรณ์ (Production Ready)
.checkbox-wrapper {
display: inline-flex;
align-items: flex-start;
gap: 0.75rem;
cursor: pointer;
font-size: 1rem;
line-height: 1.5;
}
.checkbox-wrapper input[type="checkbox"] {
appearance: none;
-webkit-appearance: none;
width: 20px;
height: 20px;
flex-shrink: 0;
margin-top: 0.25em; /* Align with text */
border: 2px solid #999;
border-radius: 4px;
background: white;
transition: border-color 0.2s, background 0.2s, box-shadow 0.2s;
position: relative;
}
.checkbox-wrapper:hover input[type="checkbox"] {
border-color: #4285f4;
}
.checkbox-wrapper input[type="checkbox"]:checked {
border-color: #4285f4;
background: #4285f4;
}
.checkbox-wrapper input[type="checkbox"]::after {
content: "";
position: absolute;
top: 50%; left: 50%;
width: 5px; height: 10px;
border: solid white;
border-width: 0 2px 2px 0;
transform: translate(-50%, -60%) rotate(45deg) scale(0);
transition: transform 0.15s cubic-bezier(0.4, 0, 0.2, 1);
}
.checkbox-wrapper input[type="checkbox"]:checked::after {
transform: translate(-50%, -60%) rotate(45deg) scale(1);
}
.checkbox-wrapper input[type="checkbox"]:focus-visible {
outline: none;
box-shadow: 0 0 0 3px rgba(66,133,244,0.3);
}
.checkbox-wrapper input[type="checkbox"]:disabled {
opacity: 0.5;
cursor: not-allowed;
}
.checkbox-wrapper input[type="checkbox"]:indeterminate::after {
content: "";
width: 10px; height: 2px;
background: white;
transform: translate(-50%, -50%) rotate(0) scale(1);
border: none;
}
HTML Usage
<label class="checkbox-wrapper"> <input type="checkbox" name="agree" value="1"> <span>I agree to the Terms of Service</span> </label> <label class="checkbox-wrapper"> <input type="checkbox" name="newsletter" checked> <span>Subscribe to newsletter</span> </label> <label class="checkbox-wrapper"> <input type="checkbox" disabled> <span>Disabled option</span> </label>
Indeterminate State (สำหรับ "Select All")
// JavaScript
const selectAll = document.getElementById('select-all');
const items = document.querySelectorAll('.item-checkbox');
selectAll.addEventListener('change', () => {
items.forEach(cb => cb.checked = selectAll.checked);
});
items.forEach(cb => {
cb.addEventListener('change', () => {
const checked = document.querySelectorAll('.item-checkbox:checked').length;
selectAll.checked = checked === items.length;
selectAll.indeterminate = checked > 0 && checked < items.length;
});
});
Accessibility Checklist
- ใช้
<label>ครอบ Input (Implicit Label) หรือ for/id (Explicit Label) nameattribute สำหรับ Form Submissionvalueattribute สำหรับค่าที่ส่งไป Server:focus-visibleสำหรับ Keyboard Usersdisabledattribute +opacityสำหรับ Disabled State- Indeterminate State สำหรับ Select All Pattern
- Color Contrast: Border/Background/Checkmark ต้องผ่าน WCAG AA
Animation Enhancement
.checkbox-wrapper input[type="checkbox"]::after {
/* ... */
transition: transform 0.2s cubic-bezier(0.175, 0.885, 0.32, 1.275); /* Bounce */
}
.checkbox-wrapper input[type="checkbox"]:checked::after {
transform: translate(-50%, -60%) rotate(45deg) scale(1);
}
/* Ripple Effect */
.checkbox-wrapper input[type="checkbox"]::before {
content: "";
position: absolute;
inset: -4px;
border-radius: 6px;
opacity: 0;
transition: opacity 0.2s, transform 0.2s;
}
.checkbox-wrapper input[type="checkbox"]:active::before {
opacity: 0.1;
transform: scale(1.2);
background: currentColor;
transition: transform 0s, opacity 0s;
}