הדור הבא של עיצוב באינטרנט

תוכלו להתעדכן בכמה מהתכונות המעניינות של שירות ה-CSS המודרני.

ב-CSS קורים הרבה דברים מלהיבים עכשיו, ורבים מהם כבר נתמכים בדפדפנים של היום. ההרצאה שלנו ב-CDS 2019, שבה אפשר לצפות בהמשך, עוסקת בכמה פיצ'רים חדשים ועתידיים שחשבנו שכדאי להכיר.

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

תוכן עניינים

הצמדת גלילה

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

הקוד לדוגמה הזה מגדיר גלילה אופקית ברכיב <section> עם נקודות הצמדה שצמודות לצד השמאלי של רכיבי הצאצא של <picture>:

section {
  overflow-x: auto;
  overscroll-behavior-x: contain;
  scroll-snap-type: x mandatory;
}

section > picture {
  scroll-snap-align: start;
}

ככה זה עובד:

  • ברכיב <section> ההורה,
    • הערך של overflow-x מוגדר ל-auto כדי לאפשר גלילה אופקית.
    • overscroll-behavior-x מוגדר לערך contain כדי למנוע גלילה של רכיבי הורה כשהמשתמש מגיע לגבולות אזור הגלילה של הרכיב <section>. (זה לא הכרחי רק לצילום תמונות, אבל זה בדרך כלל רעיון טוב).
    • scroll-snap-type מוגדר לערך x - להצמדה אופקית - ו-mandatory - כדי להבטיח שאזור התצוגה ייצמד תמיד לנקודת ההצמדה הקרובה ביותר.
  • ברכיבי הצאצא <picture>, scroll-snap-align מוגדר להתחיל, מה שמגדיר את נקודות ההצמדה בצד שמאל של כל תמונה (בהנחה שהערך של direction מוגדר ל-ltr).

והנה הדגמה חיה:

אפשר גם לצפות בהדגמות של הצמדת גלילה אנכית והצמדה לגלילה של מטריצה.

:focus-within

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

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

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

.menu:focus-within {
  display: block;
  opacity: 1;
  visibility: visible;
}

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

אפשר להקיש על Tab כדי לעבור בין האלמנטים שניתן להתמקד בהם בהדגמה שלמטה. תוכלו לראות שהתפריטים עדיין מוצגים כשאתם מתמקדים בפריטים בתפריט:

רמה 5 של שאילתות מדיה

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

תרשים של שאילתות מדיה שמפרקות את העדפות המשתמש ברמת המערכת.

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

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

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

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

תכונות לוגיות

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

דיאגרמה שמציגה מאפיינים מסורתיים של פריסת CSS.

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

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

  • המאפיין בלוק מאונך לזרימת הטקסט בשורה. (באנגלית, block-size זהה ל-height).
  • המאפיין מוטבע מקביל לזרימת הטקסט בשורה. (באנגלית, inline-size זהה ל-width).

שמות המאפיינים האלה חלים על כל נכסי הפריסה הלוגית. כך, למשל, באנגלית, block-start זהה ל-top, ו-inline-end זהה ל-right.

דיאגרמה שמוצגים בה מאפייני פריסה לוגית חדשים של CSS.

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

בהדגמה שלמטה אפשר לראות איך מאפיינים לוגיים פועלים. כדי לעשות את זה, מגדירים את המאפיין writing-mode ברכיב <body> לערכים שונים:

position: sticky

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

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

Sticky Stack

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

שקף דביק

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

סטיקי דספראדו

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

backdrop-filter

המאפיין backdrop-filter מאפשר להחיל אפקטים גרפיים על האזור שמאחור הרכיב, ולא על הרכיב עצמו. הכלי יוצר הרבה אפקטים מגניבים שבעבר ניתן היה להשיג רק באמצעות פריצות CSS ו-JavaScript מורכבות, שניתן היה לבצע באמצעות שורה אחת של CSS.

לדוגמה, בהדגמה הזו נעשה שימוש ב-backdrop-filter כדי להשיג טשטוש בסגנון מערכת ההפעלה:

כבר יש לנו פוסט נהדר על backdrop-filter, אז כדאי להיכנס אליו כדי לקבל מידע נוסף.

:is()

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

הנה דוגמה מהירה:

button.focus,
button:focus {
  …
}

article > h1,
article > h2,
article > h3,
article > h4,
article > h5,
article > h6 {
  …
}

/* selects the same elements as the code above */
button:is(.focus, :focus) {
  …
}

article > :is(h1,h2,h3,h4,h5,h6) {
  …
}

gap

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

איור שמראה איך מאפיין הפער מונעת ריווח לא מכוון בין קצוות של רכיב קונטיינר.

חדשות טובות יותר: gap מגיע/ה ל-Flexbox, עם כל אותן הטבות ריווח כמו:

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

בסרטון הבא מוצגים היתרונות של השימוש בנכס gap אחד עם שני אלמנטים – אחד עם פריסת רשת והשני עם פריסה גמישה:

כרגע, רק FireFox תומך ב-gap בפריסות גמישות, אבל אפשר להתנסות בהדגמה הזו כדי לראות איך זה עובד:

שירות CSS הודי

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

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

איור שמראה איך Houdini פועל לעומת polyfills של JavaScript המסורתי.

Houdini הוא שם כללי לכמה ממשקי API. כדי לקבל מידע נוסף עליהם ועל הסטטוס הנוכחי שלהם, קראו את המאמר האם Houdini מוכן עדיין? בשיחתנו דיברנו על המאפיינים וה-API של המאפיינים, ממשק ה-API של Paint ו-Worklet של האנימציה, כי הם הסוגים הנתמכים ביותר כרגע. יכולנו להקדיש בקלות פרסום מלא לכל אחד מממשקי ה-API המלהיבים האלה, אבל בינתיים, מומלץ לעיין בהרצאה כדי לקבל סקירה כללית והדגמות מגניבות שיתחילו לתת לכם מושג לגבי מה אפשר לעשות עם ממשקי ה-API.

אפשרויות נוספות

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

  • size: מאפיין שיאפשר לכם להגדיר גובה ורוחב בו-זמנית
  • aspect-ratio: נכס שמגדיר יחס גובה-רוחב לרכיבים שאין להם יחס כזה באופן מהותי
  • min(), max() ו-clamp(): פונקציות שיאפשרו לכם להגדיר אילוצים מספריים בכל מאפיין CSS, ולא רק רוחב וגובה
  • list-style-type נכס קיים, אבל בקרוב הוא יתמוך במגוון רחב יותר של ערכים, כולל אמוג'י וקובצי SVG
  • display: outer inner: הנכס display יקבל בקרוב שני פרמטרים, שיאפשרו לך לציין באופן מפורש את הפריסה החיצונית והפנימית שלו, במקום להשתמש במילות מפתח מורכבות כמו inline-flex.
  • אזורי CSS: מאפשרים למלא אזור לא מלבני מוגדר שהתוכן יכול לזרום אליו וממנו
  • מודולי CSS: JavaScript יוכל לבקש מודול CSS ולקבל חזרה אובייקט עשיר שקל לבצע בו פעולות