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

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

מ-Chrome 131, חל שינוי בירושה של ההדגשה ב-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 מותאם אישית נכסים. מאפיינים מותאמים אישית עוברים בירושה דרך עץ הרכיבים, "קבלה בירושה מהורה" עם קטע קוד שנראה כך:

: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>

זו התוצאה כשבוחרים באפשרות הזו גם ב-Chrome 130 וגם ב-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>

התוצאה בגרסה 131 של Chrome נראית כך:

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

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

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

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

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

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

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

רוצה לנסות?

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