בניית רכיב הגדרות

סקירה כללית בסיסית של אופן הבנייה של רכיב הגדרות של פסי הזזה ותיבות סימון.

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

הדגמה

אם אתם מעדיפים סרטונים, או אם אתם רוצים תצוגה מקדימה של ממשק המשתמש או של חוויית המשתמש שאנחנו מפתחים, תוכלו להיעזר ב הדרכה מפורטת קצרה ב-YouTube:

סקירה כללית

חילקתי את ההיבטים של הרכיב הזה לקטעים הבאים:

  1. פריסות
  2. צבע
  3. קלט של טווח בהתאמה אישית
  4. קלט של תיבת סימון בהתאמה אישית
  5. שיקולים בנושא נגישות
  6. JavaScript

פריסות

זו ההדגמה הראשונה של אתגר GUI שמיועדת לכל רשת ה-CSS! כאן מופיעות כל הרשתות מודגשים באמצעות כלי הפיתוח ל-Chrome לרשת:

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

רק לצורך פער

הפריסה הנפוצה ביותר:

foo {
  display: grid;
  gap: var(--something);
}

אני קורא לפריסה הזו 'Just for gam' כי היא משתמשת ברשת רק כדי להוסיף רווחים בין הבלוקים.

חמש פריסות משתמשות באסטרטגיה הזו, וכולן מוצגות:

פריסות רשת אנכיות מודגשות בקווי מתאר וממולאות ברווחים

ברכיב fieldset, שמכיל כל קבוצת קלט (.fieldset-item), נעשה שימוש ב-gap: 1px כדי יוצרת את גבולות קו השיער בין אלמנטים. אין פתרון גבול מורכב!

פער שמלא
.grid {
  display: grid;
  gap: 1px;
  background: var(--bg-surface-1);

  & > .fieldset-item {
    background: var(--bg-surface-2);
  }
}
תרגיל גבול
.grid {
  display: grid;

  & > .fieldset-item {
    background: var(--bg-surface-2);

    &:not(:last-child) {
      border-bottom: 1px solid var(--bg-surface-1);
    }
  }
}

גלישת רשת טבעית

הפריסה המורכבת ביותר הייתה פריסת המאקרו, הפריסה הלוגית. בין <main> ל-<form>.

מרכז התוכן של האריזה

גם הרשת וגם ה-Flexbox מספקות יכולות של align-items או align-content, וכשמשתמשים ברכיבי אריזה, הפריסה content ההתאמות יחלקו מקום בין הילדים כקבוצה.

main {
  display: grid;
  gap: var(--space-xl);
  place-content: center;
}

הרכיב הראשי משתמש ביישור place-content: center קיצור שהם ממורכזים אנכית ואופקית בפריסות של עמודה אחת או שתיים.

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

חזרה על התאמה אוטומטית ל-minmax

השדה <form> משתמש בפריסת רשת מותאמת לכל קטע. הפריסה הזו עוברת מעמודה אחת לשתי עמודות על סמך השטח הזמין.

form {
  display: grid;
  gap: var(--space-xl) var(--space-xxl);
  grid-template-columns: repeat(auto-fit, minmax(min(10ch, 100%), 35ch));
  align-items: flex-start;
  max-width: 89vw;
}

לרשת הזו יש ערך שונה עבור row-gap (--space-xl) מאשר column-gap (--space-xxl) כדי להוסיף את הנגיעה המותאמת אישית לפריסה הרספונסיבית. כשהעמודות האלה משולבות, אנחנו רוצים פער גדול, אבל לא גדול כמו במסך רחב.

הנכס grid-template-columns משתמש ב-3 פונקציות CSS: repeat(), minmax() ו min() ל-Una Kravets יש בלוג נהדר לפריסה לפרסם הודעה על זה, לקרוא לזה. RAM.

יש 3 תוספות מיוחדות לפריסה שלנו, אם תשוו אותה לפריסה של אונה:

  • אנחנו מעבירים פונקציית min() נוספת.
  • אנחנו מציינים את align-items: flex-start.
  • יש סגנון max-width: 89vw.

הפונקציה min() הנוספת מתוארת היטב על ידי אוון מינטו בבלוג שלו פרסום רשת CSS רספונסיבית באופן מובנה עם minmax() ועם min(). אני ממליץ לקרוא אותו. תיקון היישור של flex-start הוא להסיר את אפקט המתיחה שמוגדר כברירת מחדל, כך שהבנים של הפריסה צריכים להיות גבהים זהים, גובה טבעי ופנימי. בסרטון ב-YouTube יש פירוט מהיר של ההתאמה הזו.

הערך של max-width: 89vw הוא פירוט קטן בפוסט הזה. אראה לך את הפריסה עם ובלי הסגנון שהוחל:

מה קורה? אם מציינים את max-width, היא מספקת הקשר, שינוי גודל מפורש או הגדרות ספציפיות מידה עבור auto-fit את האלגוריתם של הפריסה כדי לדעת איך הרבה חזרות שיכולות להתאים למרחב. אומנם מובן מאליו לפי מפרט הרשת של CSS, הרווח הוא "רוחב מלא", גודל מוגדר או גודל מקסימלי חייבים יוצגו. ציינתי גודל מקסימלי.

אז למה דווקא 89vw? כי "זה עבד" לפריסה שלי. אני ועוד כמה אנשים ב-Chrome בודקים למה יש ערך הגיוני יותר, כמו 100vw, לא מספיק, ואם למעשה מדובר בבאג.

ריווח

רוב ההרמוניה של הפריסה הזו היא מלוח צבעים מוגבל, 7 לדיוק.

:root {
  --space-xxs: .25rem;
  --space-xs:  .5rem;
  --space-sm:  1rem;
  --space-md:  1.5rem;
  --space-lg:  2rem;
  --space-xl:  3rem;
  --space-xxl: 6rem;
}

השימוש בדפים האלה עובד יפה עם רשת, CSS @nest ותחביר ברמה 5 של @media. הנה דוגמה, קבוצת הסגנונות המלאה של <main>.

main {
  display: grid;
  gap: var(--space-xl);
  place-content: center;
  padding: var(--space-sm);

  @media (width >= 540px) {
    & {
      padding: var(--space-lg);
    }
  }

  @media (width >= 800px) {
    & {
      padding: var(--space-xl);
    }
  }
}

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

זוכרים את הפריסה הקודמת, "Just for gam"? זוהי גרסה מלאה יותר של איך הם נראים ברכיב הזה:

header {
  display: grid;
  gap: var(--space-xxs);
}

section {
  display: grid;
  gap: var(--space-md);
}

צבע

שימוש מבוקר בצבע עזר לעיצוב הזה לבלוט מינימלי. אני עושה זאת כך:

:root {
  --surface1: lch(10 0 0);
  --surface2: lch(15 0 0);
  --surface3: lch(20 0 0);
  --surface4: lch(25 0 0);

  --text1: lch(95 0 0);
  --text2: lch(75 0 0);
}

אני נותן שם לצבעי השטח ולטקסטים שלי במספרים במקום בשמות כמו surface-dark ו-surface-darker כי בשאילתת מדיה, אני אהפוך ולתאורה לכהה לא תהיה משמעות.

אני הופך אותם בשאילתת מדיה מועדפת, כך:

:root {
  ...

  @media (prefers-color-scheme: light) {
    & {
      --surface1: lch(90 0 0);
      --surface2: lch(100 0 0);
      --surface3: lch(98 0 0);
      --surface4: lch(85 0 0);

      --text1: lch(20 0 0);
      --text2: lch(40 0 0);
    }
  }
}

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

LCH?

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

צילום מסך של דף האינטרנט pod.link/csspodcast, עם צבע 2: פרק תפיסה למעלה
מידע נוסף על הצבע התפיסתי (ועוד!) בפודקאסט של שירותי CSS

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

:root {
  --surface1: lch(10 0 0);
  --text1:    lch(95 0 0);

  @media (prefers-color-scheme: light) {
    & {
      --surface1: lch(90 0 0);
      --text1:    lch(40 0 0);
    }
  }
}

--surface1: lch(10 0 0) מתורגמת ל: 10% בהירות, 0 Chroma ו-0 גוון: a אפור כהה מאוד חסר צבע. לאחר מכן, בשאילתת המדיה למצב בהיר, הבהירות הפך ל-90% עם --surface1: lch(90 0 0);. וזהו עיקרון את האסטרטגיה שלנו. בתור התחלה, פשוט משנים את הקלילות בין שני הנושאים, ושומרים על ביחסי הניגודיות שנדרשת מהעיצוב, או למה שיכול לשמור על נגישות.

הבונוס עם lch() הוא שהקלילות מופנית כלפי בני אדם, ואנחנו יכולים להרגיש טוב שהשינוי של % בו, שהוא יופיע באופן עקבי ועקבי שונה ב-%. לדוגמה, hsl() אינו כ- מהימנים.

יש עוד תוכן ללמוד על מרחבי צבעים ו-lch() אם רוצים. בקרוב!

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

לאה וורו

פקדי צורה מותאמים עם ערכת צבעים

דפדפנים רבים שולחים אמצעי בקרה של עיצוב כהה, נכון לעכשיו Safari ו-Chromium, אבל לציין ב-CSS או ב-HTML שהעיצוב שלכם משתמש בהם.

הדוגמה שלמעלה ממחישה את ההשפעה של הנכס מחלונית הסגנונות של כלי פיתוח. ההדגמה משתמשת בתג HTML, שלדעתי הוא בדרך כלל מיקום טוב יותר:

<meta name="color-scheme" content="dark light">

מידע נוסף בכל הנושאים זמין בcolor-scheme מאמר מאת תומס סטיינר. יש עוד הרבה להרוויח מאשר קלט של תיבת סימון כהה!

שירות CSS: accent-color

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

input[type="checkbox"] {
  accent-color: var(--brand);
}

צילום מסך מ-Chromium ב-Linux של תיבות סימון ורודות

הבלטת צבעים עם הדרגתי קבוע והתמקדות בפנים

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

הסרטון שלמעלה כולל שכבות רבות של משוב ואינטראקציה מממשק המשתמש, והן עוזרות להעניק לאינטראקציה אישית יותר על ידי:

  • הדגשת הקשר
  • שליחת משוב בממשק המשתמש לגבי "כמה מלא" הערך נמצא בטווח.
  • שליחת משוב בממשק המשתמש על כך ששדה מסוים מקבל קלט.

כדי לספק משוב על אינטראקציה עם אלמנט, שירות ה-CSS משתמש :focus-within כדי לשנות את המראה של יסודות שונים, .fieldset-item, זה ממש מעניין:

.fieldset-item {
  ...

  &:focus-within {
    background: var(--surface2);

    & svg {
      fill: white;
    }

    & picture {
      clip-path: circle(50%);
      background: var(--brand-bg-gradient) fixed;
    }
  }
}

כשהמיקוד הוא בתוך אחד מהצאצאים של הרכיב הזה:

  1. לרקע .fieldset-item הוקצה צבע משטח בניגודיות גבוהה יותר.
  2. השדה svg שמקונן מלא בלבן לניגודיות גבוהה יותר.
  3. השדה <picture> clip-path שהוצב בו מתרחב למעגל מלא, הרקע מלא בהדרגתיות של צבע קבוע בגוונים בהירים.

טווח מותאם אישית

בהינתן רכיב הקלט הבא ב-HTML, אראה לכם איך התאמתי אישית את מראה:

<input type="range">

יש 3 חלקים ברכיב הזה שעלינו להתאים אישית:

  1. רכיב טווח / מאגר
  2. מעקב
  3. אגודל

סגנונות של רכיבי טווח

input[type="range"] {
  /* style setting variables */
  --track-height: .5ex;
  --track-fill: 0%;
  --thumb-size: 3ex;
  --thumb-offset: -1.25ex;
  --thumb-highlight-size: 0px;

  appearance: none;         /* clear styles, make way for mine */
  display: block;
  inline-size: 100%;        /* fill container */
  margin: 1ex 0;            /* ensure thumb isn't colliding with sibling content */
  background: transparent;  /* bg is in the track */
  outline-offset: 5px;      /* focus styles have space */
}

השורות הראשונות של CSS הן החלקים המותאמים אישית של הסגנונות, ואני מקווה לתייג אותם בבירור זה עוזר. שאר הסגנונות בדרך כלל מתאפסים, לספק בסיס עקבי לבניית החלקים המורכבים של הרכיב.

סגנונות מסלול

input[type="range"]::-webkit-slider-runnable-track {
  appearance: none; /* clear styles, make way for mine */
  block-size: var(--track-height);
  border-radius: 5ex;
  background:
    /* hard stop gradient:
        - half transparent (where colorful fill we be)
        - half dark track fill
        - 1st background image is on top
    */
    linear-gradient(
      to right,
      transparent var(--track-fill),
      var(--surface1) 0%
    ),
    /* colorful fill effect, behind track surface fill */
    var(--brand-bg-gradient) fixed;
}

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

סגנון המילוי של הטראק

העיצוב שלי נדרש JavaScript כדי לשמור על סגנון המילוי. יש הן אסטרטגיות של CSS בלבד, אבל הן דורשות שרכיב האב יהיה באותו גובה בתור הטראק, ולא הצלחתי למצוא הרמוניה בגבולות האלה.

/* grab sliders on page */
const sliders = document.querySelectorAll('input[type="range"]')

/* take a slider element, return a percentage string for use in CSS */
const rangeToPercent = slider => {
  const max = slider.getAttribute('max') || 10;
  const percent = slider.value / max * 100;

  return `${parseInt(percent)}%`;
};

/* on page load, set the fill amount */
sliders.forEach(slider => {
  slider.style.setProperty('--track-fill', rangeToPercent(slider));

  /* when a slider changes, update the fill prop */
  slider.addEventListener('input', e => {
    e.target.style.setProperty('--track-fill', rangeToPercent(e.target));
  })
})

לדעתי, זה שדרוג חזותי נחמד. פס ההזזה עובד מעולה בלי JavaScript, ההצעה --track-fill לא נדרשת, פשוט לא תהיה לה סגנון מילוי, אם הוא לא קיים. אם JavaScript זמין, מאכלסים את השדה בהתאמה אישית נכס וגם תצפו בשינויים במשתמשים, ותסנכרנו את הנכס המותאם אישית עם בערך.

יש לנו רעיון מעולה פרסום ב- טריקים לשירותי CSS מאת אנה טיודור, שמדגים פתרון של שירות CSS בלבד מילוי הטראק. גם מצאתי את זה אלמנט range מעורר השראה.

סגנונות של אגודל

input[type="range"]::-webkit-slider-thumb {
  appearance: none; /* clear styles, make way for mine */
  cursor: ew-resize; /* cursor style to support drag direction */
  border: 3px solid var(--surface3);
  block-size: var(--thumb-size);
  inline-size: var(--thumb-size);
  margin-top: var(--thumb-offset);
  border-radius: 50%;
  background: var(--brand-bg-gradient) fixed;
}

רוב הסגנונות האלה הם ליצירת מעגל נחמד. שוב רואים שם את הדרגתיות של הרקע הקבוע, שמאחדת את צבעים דינמיים של האגודלים, הטראקים ורכיבי ה-SVG שמשויכים אליהם. הפרדתי את הסגנונות של האינטראקציות כדי לבודד את box-shadow שמשמשת להדגשה של העכבר:

@custom-media --motionOK (prefers-reduced-motion: no-preference);

::-webkit-slider-thumb {
  

  /* shadow spread is initally 0 */
  box-shadow: 0 0 0 var(--thumb-highlight-size) var(--thumb-highlight-color);

  /* if motion is OK, transition the box-shadow change */
  @media (--motionOK) {
    & {
      transition: box-shadow .1s ease;
    }
  }

  /* on hover/active state of parent, increase size prop */
  @nest input[type="range"]:is(:hover,:active) & {
    --thumb-highlight-size: 10px;
  }
}

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

אם רק אפקט ההדגשה היה כל כך קל בתיבות הסימון...

בוררים בדפדפנים שונים

מצאתי שאני צריך את הסלקטורים האלה ב--webkit- וב--moz- כדי להשתמש בבוררים בדפדפנים שונים עקביות:

input[type="range"] {
  &::-webkit-slider-runnable-track {}
  &::-moz-range-track {}
  &::-webkit-slider-thumb {}
  &::-moz-range-thumb {}
}

תיבת סימון בהתאמה אישית

בהינתן רכיב הקלט הבא ב-HTML, אראה לכם איך התאמתי אישית את מראה:

<input type="checkbox">

יש 3 חלקים ברכיב הזה שעלינו להתאים אישית:

  1. רכיב תיבת סימון
  2. תוויות משויכות
  3. הדגשת האפקט

רכיב של תיבת סימון

input[type="checkbox"] {
  inline-size: var(--space-sm);   /* increase width */
  block-size: var(--space-sm);    /* increase height */
  outline-offset: 5px;            /* focus style enhancement */
  accent-color: var(--brand);     /* tint the input */
  position: relative;             /* prepare for an absolute pseudo element */
  transform-style: preserve-3d;   /* create a 3d z-space stacking context */
  margin: 0;
  cursor: pointer;
}

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

תוויות של תיבת סימון

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

קלט
<input
  type="checkbox"
  id="text-notifications"
  name="text-notifications"
>
תווית
<label for="text-notifications">
  <h3>Text Messages</h3>
  <small>Get notified about all text messages sent to your device</small>
</label>

בתווית, מציבים מאפיין for שמצביע לתיבת סימון לפי המזהה: <label for="text-notifications">. בתיבת הסימון, מכפילים את השם וגם את המזהה כדי כדאי לוודא שהוא יאותר בכלים ובטכנולוגיות שונות, כמו עכבר או קורא מסך: <input type="checkbox" id="text-notifications" name="text-notifications"> :hover, :active ועוד מגיעים בחינם עם החיבור, וכך מגדילים את הדרכים שבהן ניתן לקיים אינטראקציה עם הטופס.

הדגשה של תיבת הסימון

אני רוצה לשמור על עקביות בממשקים, ולרכיב המחוון יש הדגשה של תמונה ממוזערת שבה אני רוצה להשתמש עם תיבת הסימון. התמונה הממוזערת הייתה אפשר להשתמש ב-box-shadow ובמאפיין spread כדי להציג צללית למטה. עם זאת, האפקט הזה לא עובד כאן מכיוון שתיבות הסימון שלנו, וצריכות be, ריבוע.

הצלחתי להשיג את אותו אפקט חזותי עם פסאודו אלמנט, לצערנו כמות האפקטים של CSS:

@custom-media --motionOK (prefers-reduced-motion: no-preference);

input[type="checkbox"]::before {
  --thumb-scale: .01;                        /* initial scale of highlight */
  --thumb-highlight-size: var(--space-xl);

  content: "";
  inline-size: var(--thumb-highlight-size);
  block-size: var(--thumb-highlight-size);
  clip-path: circle(50%);                     /* circle shape */
  position: absolute;                         /* this is why position relative on parent */
  top: 50%;                                   /* pop and plop technique (https://web.dev/centering-in-css#5-pop-and-plop) */
  left: 50%;
  background: var(--thumb-highlight-color);
  transform-origin: center center;            /* goal is a centered scaling circle */
  transform:                                  /* order here matters!! */
    translateX(-50%)                          /* counter balances left: 50% */
    translateY(-50%)                          /* counter balances top: 50% */
    translateZ(-1px)                          /* PUTS IT BEHIND THE CHECKBOX */
    scale(var(--thumb-scale))                 /* value we toggle for animation */
  ;
  will-change: transform;

  @media (--motionOK) {                       /* transition only if motion is OK */
    & {
      transition: transform .2s ease;
    }
  }
}

/* on hover, set scale custom property to "in" state */
input[type="checkbox"]:hover::before {
  --thumb-scale: 1;
}

קל ליצור רכיב מדומה של מעגל, אבל לא צריך לדאוג מאחורי האלמנט שאליו הוא מצורף היה קשה יותר. הנה לפני ו- אחרי שתיקנתי את זה:

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

נגישות

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

בחירות רכיבי HTML

<form>
<header>
<fieldset>
<picture>
<label>
<input>

כל אחת מהאפשרויות האלה כוללת רמזים וטיפים לכלי הגלישה של המשתמש. רכיבים מסוימים לספק רמזים לאינטראקציה, חלק מהאינטראקציות של המשתמשים, והם יכולים לעזור לעצב עץ נגישות שקורא מסך מנווט בו.

מאפייני HTML

אנחנו יכולים להסתיר אלמנטים שלא נחוצים לקוראי מסך, במקרה הזה, הסמל שליד פס ההזזה:

<picture aria-hidden="true">

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

פורמט SVG הוא קצת מתמטיקה. נוסיף רכיב <title> כדי להעביר בקלות את העכבר מעל התמונה כותרת והערה קריאה אנושית על מה שהמתמטיקה יוצרת:

<svg viewBox="0 0 24 24">
  <title>A note icon</title>
  <path d="M12 3v10.55c-.59-.34-1.27-.55-2-.55-2.21 0-4 1.79-4 4s1.79 4 4 4 4-1.79 4-4V7h4V3h-6z"/>
</svg>

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

JavaScript

כבר קראתי איך מנהלים את צבע המילוי של הטראק מ-JavaScript, אז נסתכל עכשיו על קוד ה-JavaScript הקשור ל-<form>:

const form = document.querySelector('form');

form.addEventListener('input', event => {
  const formData = Object.fromEntries(new FormData(form));
  console.table(formData);
})

בכל פעם שיש אינטראקציה עם הטופס ועריכת שינויים, המסוף רושם את הטופס כ אובייקט בטבלה לבדיקה קלה לפני שליחתו לשרת.

צילום מסך של התוצאות console.table() , שבו נתוני הטופס מוצגים בטבלה

סיכום

עכשיו אתה יודע איך עשיתי את זה, איך היית?! זה כיף גדול ארכיטקטורת רכיבים. מי יקבל את הגרסה הראשונה עם מיקומי מודעות מסגרת אהובה? 🙂

בואו לגוון את הגישות שלנו ונלמד את כל הדרכים לבניית אתרים באינטרנט. אפשר ליצור הדגמה, לשלוח לי קישורים של שלחו לי ציוץ ואני אוסיף אותם לקטע רמיקסים מהקהילה שבהמשך.

רמיקסים קהילתיים

  • @tomayac עם הסגנון שלהם אזור להעברת העכבר מעל לתוויות של תיבות הסימון! בגרסה הזו אין מרווח של העברת העכבר בין רכיבים: demo ו source.