טפסים שתואמים למותג

תכונות אינטרנט: accent-color

בעבר היה קשה להתאים אישית רכיבים סטנדרטיים של טופסי HTML, כמו תיבות סימון וכפתורי בחירה. מפתחים נאלצו לעיתים קרובות לבחור בין שימוש בברירות המחדל של הדפדפן לבין פיתוח רכיבים בהתאמה אישית מאפס. יצירת פקדים בהתאמה אישית דורשת זמן רב ויכולה בקלות להוביל לבעיות נגישות או למצבים חסרים (כמו המצב הלא מוגדר של תיבות סימון).

המאפיין accent-color ב-CSS מאפשר להוסיף את צבע המותג לשדות קלט מובנים בטופסי 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 (באג 244233 ב-WebKit) ו-Chrome ל-Android (באג 343503163 ב-Chromium) עלולים לגרום לכך שצבעי סימני הווי לא יתהפכו. כתוצאה מכך, פקדים מסוימים לא יהיו גלויים או שיהיה קשה לראות אותם כשמשתמשים בצבעים שאין להם מספיק ניגודיות ביחס לרקע (למשל, צבעים בהירים במצב בהיר או צבעים כהים במצב כהה).
  • מומלץ לשלב את accent-color עם color-scheme: light dark כדי לוודא שפקדי הטופס נראים טוב גם בעיצובים בהירים וגם בעיצובים כהים.
  • אל תשתמשו בצבע שקרוב מדי לצבע הרקע. למרות שהדפדפנים מנסים להבטיח ניגודיות, מומלץ לספק צבע עם ניגודיות בסיסית טובה.
  • אל תניחו ש-accent-color פועל בכל רכיבי הטופס. כרגע, רק הרכיבים checkbox,‏ radio,‏ range ו-progress נצבעים.

אסטרטגיית גיבוי

בדפדפנים שלא תומכים ב-accent-color, פקדי הטופס חוזרים למראה ברירת המחדל של הדפדפן. כדי להבטיח עקביות מלאה של המותג ואמינות גבוהה בכל הסביבות, אתם חייבים להטמיע אסטרטגיית חלופה מותאמת אישית באמצעות השיטה המבוססת של "קלט מוסתר מבחינה חזותית".

שיפור הדרגתי (progressive enhancement) באמצעות @supports not

חובה להשתמש בכלל @supports not כדי להחיל סגנונות חלופיים בהתאמה אישית רק כשאין תמיכה ב-accent-color. כך תוכלו ליהנות מהפשטות של accent-color בדפדפנים מודרניים, וגם להבטיח חוויה עקבית של המותג בדפדפנים ישנים יותר.

1. מבנה HTML

כדי לאפשר סלקטורים אחים ב-CSS, צריך לוודא שהתוויות עוטפות את הטקסט ב-<span>:

<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}%`);
  });
}