แบบฟอร์มที่สอดคล้องกับแบรนด์

ฟีเจอร์บนเว็บ: accent-color

การปรับแต่งองค์ประกอบแบบฟอร์ม HTML มาตรฐาน เช่น ช่องทำเครื่องหมายและปุ่มตัวเลือก เป็นเรื่องที่ทำได้ยากมาโดยตลอด นักพัฒนามักต้องเลือกระหว่างการใช้ค่าเริ่มต้นของเบราว์เซอร์หรือการสร้างคอมโพเนนต์ที่กำหนดเองตั้งแต่ต้น การสร้างตัวควบคุมที่กำหนดเองนั้นใช้เวลานานและอาจทำให้เกิดปัญหาด้านการช่วยเหลือพิเศษหรือสถานะที่ขาดหายไปได้ง่าย (เช่น สถานะไม่แน่นอนสำหรับช่องทำเครื่องหมาย)

พร็อพเพอร์ตี้ CSS accent-color เป็นวิธีง่ายๆ ในการนำสีของแบรนด์มาใช้กับอินพุตแบบฟอร์ม HTML ในตัวด้วย CSS บรรทัดเดียว โดยไม่ลดทอนการช่วยเหลือพิเศษหรือฟีเจอร์เบราว์เซอร์ในตัว

วิธีการนำไปใช้งาน

วิธีใช้สีของแบรนด์กับการควบคุมแบบฟอร์ม

  1. ระบุสีของแบรนด์: เลือกสีที่แสดงถึงแบรนด์ของคุณ
  2. ใช้พร็อพเพอร์ตี้ accent-color: เพิ่ม accent-color ลงในองค์ประกอบหรือองค์ประกอบคอนเทนเนอร์ (เช่น body หรือแบบฟอร์มที่เฉพาะเจาะจง) ใน CSS
  3. รองรับโหมดมืด (ไม่บังคับ แต่แนะนำ): ใช้ color-scheme เพื่อแจ้งให้เบราว์เซอร์ทราบว่าเว็บไซต์ของคุณรองรับโหมดมืด และปรับ accent-color หากจำเป็นเพื่อให้คอนทราสต์ดีขึ้น

โค้ดตัวอย่าง: ตัวควบคุมแบบฟอร์มที่สอดคล้องกับแบรนด์

:root {
  --brand-color: #6200ee;
}

/* Apply accent-color to the body or a specific container */
body {
  accent-color: var(--brand-color);
}

/* Optional: Adjust for dark mode if needed */
@media (prefers-color-scheme: dark) {
  :root {
    --brand-color: #bb86fc; /* A lighter shade for dark mode */
  }
}
<form>
  <!-- Checkbox -->
  <label for="subscribe">
    <input type="checkbox" id="subscribe" checked>
    Subscribe to newsletter
  </label>

  <!-- Radio Buttons -->
  <label for="plan-monthly">
    <input type="radio" id="plan-monthly" name="plan" value="monthly">
    Monthly
  </label>
  <label for="plan-yearly">
    <input type="radio" id="plan-yearly" name="plan" value="yearly" checked>
    Yearly
  </label>

  <!-- Range Slider -->
  <label for="volume">Volume:</label>
  <input type="range" id="volume" min="0" max="100" value="70">

  <!-- Progress Bar -->
  <label for="file">Upload Progress:</label>
  <progress id="file" max="100" value="70">70%</progress>
</form>

การนำไปใช้เชิงกลยุทธ์และแนวทางปฏิบัติแนะนำ

  • ควรใช้ accent-color เพื่อจัดธีมการควบคุมแบบฟอร์มให้ตรงกับแบรนด์ของคุณได้อย่างง่ายดาย
  • อย่าเชื่อใจเบราว์เซอร์ในการจัดการคอนทราสต์โดยไม่ตรวจสอบ แม้ว่าเบราว์เซอร์ควรจะกำหนดสีคอนทราสต์ที่มีสิทธิ์โดยอัตโนมัติ แต่ข้อบกพร่องที่ทราบในการใช้งาน เช่น Safari (ข้อบกพร่อง WebKit 244233) และ Android Chrome (ข้อบกพร่อง Chromium 343503163) อาจทำให้กลับสีเครื่องหมายถูกไม่สำเร็จ ส่งผลให้ตัวควบคุมมองไม่เห็นหรือมองเห็นได้ยากเมื่อใช้สีที่ไม่มีคอนทราสต์เพียงพอกับพื้นหลัง (เช่น สีอ่อนในโหมดสว่าง หรือสีเข้มในโหมดมืด)
  • ควรรวม accent-color กับ color-scheme: light dark เพื่อให้ตัวควบคุมแบบฟอร์มดูดีทั้งในธีมสว่างและธีมมืด
  • อย่าใช้สีที่ใกล้เคียงกับสีพื้นหลังมากเกินไป แม้ว่าเบราว์เซอร์จะพยายามรับประกันคอนทราสต์ แต่ก็ควรใช้สีที่มีคอนทราสต์พื้นฐานที่ดี
  • อย่าคิดว่า accent-color จะใช้ได้กับองค์ประกอบของแบบฟอร์มทั้งหมด ปัจจุบันฟีเจอร์นี้จะปรับสีเฉพาะองค์ประกอบ checkbox, radio, range และ progress เท่านั้น

กลยุทธ์สำรอง

สำหรับเบราว์เซอร์ที่ไม่รองรับ accent-color ตัวควบคุมแบบฟอร์มจะเปลี่ยนกลับไปเป็นลักษณะที่ปรากฏเริ่มต้นของเบราว์เซอร์ เพื่อให้มั่นใจว่าแบรนด์มีความสอดคล้องกันอย่างสมบูรณ์และมีความน่าเชื่อถือสูงในทุกสภาพแวดล้อม คุณต้องใช้กลยุทธ์สำรองที่กำหนดเองโดยใช้เทคนิค "อินพุตที่ซ่อนอยู่ด้วยภาพ" ที่กำหนดไว้

การเพิ่มประสิทธิภาพแบบต่อเนื่องด้วย @supports not

คุณต้องใช้กฎ @supports not เพื่อใช้รูปแบบสำรองที่กำหนดเองเฉพาะเมื่อระบบไม่รองรับ accent-color วิธีนี้ช่วยให้คุณใช้ประโยชน์จากความเรียบง่ายของ accent-color สำหรับเบราว์เซอร์ที่ทันสมัยได้ ขณะเดียวกันก็รับประกันประสบการณ์การใช้งานที่สอดคล้องกันสำหรับเบราว์เซอร์รุ่นเก่า

1. โครงสร้าง HTML

ตรวจสอบว่าป้ายกำกับรวมข้อความไว้ใน <span> เพื่อให้ใช้ตัวเลือกพี่น้องใน CSS ได้

<label for="subscribe-fallback">
  <input type="checkbox" id="subscribe-fallback" class="visually-hidden" checked>
  <span>Subscribe to newsletter</span>
</label>

2. CSS สำรอง

ใช้รูปแบบที่กำหนดเองภายในบล็อก @supports not ดังนี้

/* Fallback for older browsers without accent-color */
@supports not (accent-color: var(--brand-color)) {
  /* Visually hide the native input using the canonical accessible recipe */
  form input[type="checkbox"].visually-hidden {
    position: absolute !important;
    clip-path: inset(50%) !important;
    overflow: hidden !important;
    width: 1px !important;
    height: 1px !important;
    margin: -1px !important;
    padding: 0 !important;
    border: 0 !important;
    white-space: nowrap !important;
  }

  /* Style the wrapper label */
  label {
    position: relative;
    padding-left: 2rem;
    cursor: pointer;
    display: inline-flex;
    align-items: center;
  }

  /* Custom box for checkbox */
  input[type="checkbox"] + span::before {
    content: "";
    position: absolute;
    left: 0;
    top: 50%;
    transform: translateY(-50%);
    width: 1.2rem;
    height: 1.2rem;
    border: 2px solid #ccc;
    background: white;
    border-radius: 4px;
    box-sizing: border-box;
    transition: all 0.2s ease;
  }

  /* Ensure custom checkbox shows focus for keyboard users */
  input[type="checkbox"]:focus-visible + span::before {
    outline: 2px solid #000;
    outline-offset: 2px;
  }

  /* Checked State */
  input[type="checkbox"]:checked + span::before {
    background-color: var(--brand-color, #6200ee);
    border-color: var(--brand-color, #6200ee);
  }

  /* Checkmark (Unicode) */
  input[type="checkbox"]:checked + span::after {
    content: "✓";
    position: absolute;
    left: 0.25rem;
    top: 50%;
    transform: translateY(-50%);
    color: white;
    font-weight: bold;
    font-size: 0.9rem;
  }

  /* Fallback for Range Slider */
  input[type="range"] {
    -webkit-appearance: none;
    appearance: none;
    background: transparent;
  }

  /* Webkit (Chrome, Safari, Edge) */
  input[type="range"]::-webkit-slider-runnable-track {
    width: 100%;
    height: 8px;
    /* Use gradient to show progress for a static value (e.g., 70%) or update with JS */
    background: linear-gradient(to right, var(--brand-color, #6200ee) 70%, #ccc 70%);
    border-radius: 4px;
  }

  input[type="range"]::-webkit-slider-thumb {
    -webkit-appearance: none;
    appearance: none;
    height: 16px;
    width: 16px;
    border-radius: 50%;
    background: var(--brand-color, #6200ee);
    cursor: pointer;
    margin-top: -4px; /* Center vertically */
  }

  /* Firefox */
  input[type="range"]::-moz-range-track {
    width: 100%;
    height: 8px;
    background: #ccc;
    border-radius: 4px;
  }

  input[type="range"]::-moz-range-thumb {
    height: 16px;
    width: 16px;
    border-radius: 50%;
    background: var(--brand-color, #6200ee);
    cursor: pointer;
  }

  /* Firefox specific progress bar */
  input[type="range"]::-moz-range-progress {
    background-color: var(--brand-color, #6200ee);
    height: 8px;
    border-radius: 4px;
  }

  /* Fallback for Progress Bar */
  progress {
    -webkit-appearance: none;
    -moz-appearance: none;
    appearance: none;
    border: none;
    background: #ccc;
    height: 8px;
    border-radius: 4px;
  }

  progress::-webkit-progress-bar {
    background-color: #ccc;
    border-radius: 4px;
  }

  progress::-webkit-progress-value {
    background-color: var(--brand-color, #6200ee);
    border-radius: 4px;
  }

  progress::-moz-progress-bar {
    background-color: var(--brand-color, #6200ee);
    border-radius: 4px;
  }
}

ความคืบหน้าของช่วงไดนามิกใน Webkit Fallback

หากต้องการให้แถบความคืบหน้าเคลื่อนที่ไปพร้อมกับปุ่มบนแถบเลื่อนช่วงในเบราว์เซอร์ Webkit (โดยไม่มี accent-color) คุณสามารถใช้ตัวแปร CSS และ JavaScript จำนวนเล็กน้อยได้

  1. อัปเดต CSS: ใช้ตัวแปร CSS สำหรับจุดหยุดการไล่ระดับสี

    input[type="range"]::-webkit-slider-runnable-track {
      background: linear-gradient(to right, var(--brand-color) var(--progress, 0%), #ccc var(--progress, 0%));
    }
    
  2. เพิ่ม JavaScript: อัปเดตตัวแปรในเหตุการณ์ input ดังนี้

if (!CSS.supports('accent-color')) {
  const slider = document.getElementById('volume');
  slider.addEventListener('input', (e) => {
    e.target.style.setProperty('--progress', `${e.target.value}%`);
  });
}