יש סיבה שפרלקס JavaScript תמיד נראה קצת לא נכון — קצת מנותק, כאילו השכבות שוחות חצי פריים מאחורי הדף. זה לא קוד רשלני. זה בגלל שאירועי גלילה מגיעים ל-JavaScript אחרי שהדפדפן כבר ציייר את הגלילה. הדפדפן פתר את זה פעם אחת, כשהפך כותרות דביקות ל-position: sticky. Scroll-driven animations הוא אותה המהלך, מיושם על כל האפקטים הקשורים לגלילה בבת אחת.
עשר שנים, אנימציה של תמונה ממוזערת לתמונת הירו אמרה טכניקה אחת: מדוד לפני, מדוד אחרי, זייף את ההבדל עם transform ונגן. FLIP. כל ספריית אנימציות עושה זאת, וכל אחת משלמת על כך ב-JavaScript על ה-thread הראשי ברגע הגרוע ביותר האפשרי. View Transitions API מעביר את כל הטריק לדפדפן — ומאז React 19.2 ו-Next.js 16, כל החוזה מורכב מ-prop אחד בשם name.
רשימה של אלף תגובות מתרנדרת לאט, אז אתם פונים ל-react-window – ובתמורה לגלילה חלקה מאבדים את Ctrl+F, הדפסת העמוד וחלק מהניווט של קורא מסך, כי אלמנטים מחוץ לחלון מפסיקים להתקיים פיזית ב-DOM. content-visibility פותר את אותה בעיה אחרת: האלמנטים נשארים ב-DOM, הדפדפן פשוט מדלג עבורם על העבודה היקרה של layout וציור, עד שהם מגיעים קרוב לאזור הנראה – ובאופן מפתיע, יודע לחשוף אותם זמנית כשמחפשים בהם טקסט.
במאמר על נגישות היה מודל עם display:none שבכל זאת המשיך להתקיים בעץ הנגישות – דוגמה לשגיאה שנובעת מבניית מודל מאפס על divים. השאלה האמיתית היא: למה בכלל היה צריך לבנות אותו מאפס? בודק מה מקבלים בחינם מ-<dialog> הטבעי ומהתכונה popover – top layer, מלכודת פוקוס, light dismiss – ואיפה שני המנגנונים האלה שונים מספיק כדי שבלבול ביניהם יוביל ישר לממשק לא נגיש.
מחלקת עזר .mt-4 מפסידה לכלל .card .card__header .card__title, למרות שהיא לכאורה אמורה לנצח, כי היא נוספה מאוחר יותר. זו לא תקלה – זו ספציפיות שעושה בדיוק את מה שהיא תוכננה לעשות. @layer מציג ציר חלוקה חדש לגמרי להכרעת קונפליקטים, שפועל לפני הספציפיות, לא ביחד איתה – ויש לו מלכודת אחת לא אינטואיטיבית עד כדי כך, שאפילו חלק מהתיעוד ברשת טועה בה.
שדה בטופס אמור להאיר באדום כשה-input בפנים לא תקין. דבר פשוט – רק ש-CSS במשך 25 שנה לא ידע לשאול אלמנט מה קורה בתוכו, רק ההפך. בודק איך :has() הופך את הכיוון הזה, במה הוא שונה מקומבינטורים רגילים, והיכן העוצמה החדשה הזו באמת עולה במחיר של ביצועים.