Computer >> บทช่วยสอนคอมพิวเตอร์ >  >> การเขียนโปรแกรม >> CSS

สร้าง Custom Checkbox ด้วย CSS appearance Property

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

CharUnicodeชื่อ
✓\2713Check Mark
✔\2714Heavy Check Mark
☑\2611Ballot Box With Check
✅\2705White 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)
  • name attribute สำหรับ Form Submission
  • value attribute สำหรับค่าที่ส่งไป Server
  • :focus-visible สำหรับ Keyboard Users
  • disabled attribute + 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;
}