שינויי ירושה של עיצוב בחירת CSS

תאריך פרסום: 8 באוקטובר 2024

החל מגרסה 131 של Chrome, יש שינוי בירושה של הדגשת CSS עבור פסאודו-הקלאסות ::selection ו-::target-text. המטרה היא ליצור מודל אינטואיטיבי יותר לירושה, שתואמת לסוגי השכבות ::highlight,‏ ::spelling-error ו-::grammar-error שנוספו לאחרונה. בפוסט הזה נסביר על השינוי, שאמור לא להשפיע באופן משמעותי על רוב האתרים.

סגנון בחירה

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

ב-CSS יש תמיכה בעיצוב של בחירת טקסט באמצעות פסאודו-הרכיב ::selection, אחד מקבוצת פסאודו-רכיבים שנקראים פסאודו-רכיבי הדגשה. אלה רכיבים פסאודו-אלמנטליים ששולטים באופן שבו הטקסט מופיע במסגרת פעולות שונות שמבוססות על משתמשים, דפדפנים או סקריפטים. בנוסף לבחירה, אפשר להוסיף סגנון לשגיאות איות (::spelling-error), לשגיאות דקדוק (::grammar-error), ליעד טקסט שמוטמע בו כתובת URL (::target-text) ולקטעים מודגשים שנוצרו על ידי סקריפט (::highlight).

כמו בכל אוסף של מאפייני CSS, התנהגות הירושה היא שיקול חשוב בתכנון אתר. באופן כללי, מפתחים מצפים שמאפייני CSS יועברו בירושה דרך עץ הרכיבים של DOM (לדוגמה, font), או שלא יועברו בירושה בכלל (לדוגמה, background).

שינויים בהתנהגות הבחירה ב-Chrome 131

נבחן את קטע המסמך הזה:

p {
  color: red;
}

.blue::selection {
  color: blue;
}
<p class="blue">Some <em>emphasized</em> text that one would expect to be blue</p>

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

טקסט שציפיתם שיהיה כחול הוא אדום.

כשבוחרים באפשרות הזו ב-Chrome 131, התוצאה משתנה כך:

הטקסט מודגש עכשיו בכחול.

מה השתנה? בעבר, התנהגות הירושה של מאפייני הבחירה יושמה באמצעות ירושה מהרכיב המקור, שבה הבחירה משתמשת במאפיינים מ-::selection שתואם לרכיב שנבחר. ב-Chrome בגרסה 130 ואילך נעשה שימוש במודל הזה, שבו לטקסט המודגש אין ::selection תואם כי ה-.blue::selection תואם רק לרכיבים עם הכיתה "blue", ורכיב ה-<em> חסר את הכיתה הזו.

ב-Chrome 131 מופעלת התנהגות חדשה שבה רכיבים יורשים את התנהגות הבחירה מהרכיב ההורה שלהם. בדוגמה הקודמת, לרכיב <em> אין ::selection שתואם לו, ולכן הוא יורש את צבעי הבחירה של רכיב <p>. התכונה הזו נקראת ירושה של הדגשה ב-CSS, וניתן לנסות אותה בגרסאות קודמות של Chrome על ידי הפעלת תכונות ניסיוניות של פלטפורמת האינטרנט בדף chrome://flags.

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

מאפייני CSS מותאמים אישית לבחירה עדיין פועלים

אתרים רבים מדמים את ירושת ההדגשה ב-CSS באמצעות שימוש במאפיינים מותאמים אישית של CSS. מאפיינים מותאמים אישית עוברים בירושה דרך עץ הרכיבים, וכך מקבלים את התוצאה 'inherit from parent' (ירושה מהורה) באמצעות קטע קוד כזה:

:root {
   --selection-color: lightgreen;
}

::selection {
  color: var(--selection-color);
}

.blue {
  --selection-color: blue;
}
<p>Some <em>emphasized</em> text</p>
<p class="blue">Some <em>emphasized</em> text that is blue</p>

זו התוצאה שתיבחר גם בגרסה 130 וגם ב-Chrome 131:

השורה הראשונה ירוקה, והשנייה כחולה.

כאן כל רכיב יורש ערך מסוים מהמאפיין --selection-color דרך עץ הרכיבים, והצבע הזה משמש לבחירת טקסט. רכיבים עם המחלקה .blue והצאצאים שלהם נבחרים בכחול, ורכיבים אחרים הם בצבע ירוק בהיר. הרבה אתרים משתמשים בטכניקה הזו, וזו השיטה המומלצת ב-Stack Overflow.

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

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

בוררים אוניברסליים ל-::selection משביתים את ירושת ההדגשה

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

::selection /* = *::selection (universal) */ {
  color: lightgreen;
}

.blue::selection {
  color: blue;
}
<p>Some <em>emphasized</em> text</p>
<p class="blue">Some <em>emphasized</em> text</p>

זו התוצאה כשבוחרים גם ב-Chrome 130 (ודגמים קודמים) וגם ב-Chrome 131 (ומעלה):

שורת הטקסט הראשונה ירוקה. השנייה היא כחולה אבל המילה המודגשת היא ירוקה.

ירושה של הדגשה ב-CSS לא גורמת לטקסט המודגש השני לעבור בירושה בצבע כחול מההורה שלו, כי הבורר האוניברסלי תואם לרכיב <em> ומחיל את צבע ההדגשה האוניברסלי, ירוק בהיר.

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

:root::selection {
  color: lightgreen;
}

.blue::selection {
  color: blue;
}
<p>Some <em>emphasized</em> text</p>
<p class="blue">Some <em>emphasized</em> text</p>

התוצאה ב-Chrome 131 נראית כך:

שורת הטקסט הראשונה ירוקה. השורה השנייה כחולה.

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

גם הסגנון של ::target-text משתנה

כל ההתנהגויות והשינויים המתוארים כאן חלים על רכיב הסימון המשנה ::target-text כמו שהם חלים על ::selection. באתר אחד יש תרחישים לדוגמה של יותר מסגנון יעד אחד של טקסט יעד, והתכונה די חדשה, כך שלא סביר שהאתר שלכם ישתנה בהתנהגות של ::target-text.

מה הסיבה לשינוי?

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

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

רוצה לנסות?

ה-CodePen הבא מדגים את השינויים. אפשר לנסות את התכונה ב-Chrome 131.