היום למדתי: הסלקטור focus-within

12/03/2022

סלקטור מאוד שימושי ב CSS שגיליתי רק לאחרונה הוא :focus-within. הוא מאפשר לזהות מתי פוקוס נמצא על אלמנט או על אחד הילדים שלו.

ולמה זה טוב? נניח שאנחנו בונים קומפוננטה מורכבת ב HTML/CSS. בואו נגיד שזו תיבת טקסט לבחירת תגיות, שכשלוחצים על התיבה מופיעה רשימה של כל התגיות לבחירה. מבחינת הפוקוס, לחיצה על תיבת הטקסט נותנת לה את הפוקוס, ואחרי זה לחיצה על כל אחד מהפריטים מעבירה את הפוקוס לפריט שנלחץ. אם תיבת הטקסט ורשימת הפריטים נמצאים בתוך אותו div, אז אני יכול להשתמש ב focus-within על הדיב העוטף הראשי כדי להחליט אם להציג או להסתיר את רשימת האפשרויות.

בקוד ה HTML יראה כך:

<div class="multiselect">
  <label>
      Click To Select:
      <input type="text" />
  </label>

  <ul>
    <li><label tabindex="0"><input type="checkbox" />item 1</label></li>
    <li><label tabindex="0"><input type="checkbox" />item 2</label></li>
    <li><label tabindex="0"><input type="checkbox" />item 3</label></li>
    <li><label tabindex="0"><input type="checkbox" />item 4</label></li>
    <li><label tabindex="0"><input type="checkbox" />item 5</label></li>
  </ul>
</div>

<div class="multiselect">
  <label>
      Click To Select:
      <input type="text" />
  </label>

  <ul>
    <li><label tabindex="0"><input type="checkbox" />item 1</label></li>
    <li><label tabindex="0"><input type="checkbox" />item 2</label></li>
    <li><label tabindex="0"><input type="checkbox" />item 3</label></li>
    <li><label tabindex="0"><input type="checkbox" />item 4</label></li>
    <li><label tabindex="0"><input type="checkbox" />item 5</label></li>
  </ul>
</div>

<div class="multiselect">
  <label>
      Click To Select:
      <input type="text" />
  </label>

  <ul>
    <li><label tabindex="0"><input type="checkbox" />item 1</label></li>
    <li><label tabindex="0"><input type="checkbox" />item 2</label></li>
    <li><label tabindex="0"><input type="checkbox" />item 3</label></li>
    <li><label tabindex="0"><input type="checkbox" />item 4</label></li>
    <li><label tabindex="0"><input type="checkbox" />item 5</label></li>
  </ul>
</div>

וה CSS יהיה:

.multiselect:focus-within {
  background: lightblue;
}

.multiselect ul {
  display: none;
}

.multiselect label {
  display: block;
  width: 100%;
}

.multiselect:focus-within ul {
  display: block;
}

והתוצאה live בקודפן היא:

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