למאפיין lang יכולה להיות שפה אחת בלבד. כלומר, למאפיין <html>
יכולה להיות רק שפה אחת, גם אם יש כמה שפות בדף. מגדירים את lang
כשפה הראשית של הדף.
<html lang="ar,en,fr,pt">...</html>
<html lang="ar">...</html>
קישורים
בדומה ללחצנים, השם הנגיש של קישורים נגזר בעיקר מתוכן הטקסט שלהם. טיפ נחמד ליצירת קישור הוא להוסיף לקישור עצמו את קטע הטקסט המשמעותי ביותר, במקום להשתמש במילים ריקות כמו 'כאן' או 'מידע נוסף'.
Check out our guide to web performance <a href="/guide">here</a>.
Check out <a href="/guide">our guide to web performance</a>.
בדיקה אם אנימציה מפעילה פריסה
אנימציה שמזיזה רכיב באמצעות משהו אחר מ-transform
צפויה להיות איטית.
בדוגמה הבאה, השגתי את אותו תוצאה חזותית באמצעות אנימציה של top
ו-left
ושימוש ב-transform
.
.box { position: absolute; top: 10px; left: 10px; animation: move 3s ease infinite; } @keyframes move { 50% { top: calc(90vh - 160px); left: calc(90vw - 200px); } }
.box { position: absolute; top: 10px; left: 10px; animation: move 3s ease infinite; } @keyframes move { 50% { transform: translate(calc(90vw - 200px), calc(90vh - 160px)); } }
אפשר לבדוק את זה בשתי הדוגמאות הבאות ב-Glitch, ולבחון את הביצועים באמצעות DevTools.
באמצעות אותו סימון, אפשר להחליף את padding-top: 56.25%
ב-aspect-ratio: 16 / 9
ולהגדיר את aspect-ratio
ליחס מסוים של width
/ height
.
.container { width: 100%; padding-top: 56.25%; }
.container { width: 100%; aspect-ratio: 16 / 9; }
השימוש ב-aspect-ratio
במקום ב-padding-top
ברור הרבה יותר, ולא מחייב שינוי יסודי של מאפיין המילוי כדי לבצע פעולה מחוץ להיקף הרגיל שלו.
כן, זה נכון, אני משתמש ב-reduce
כדי לשרשר רצף של הבטחות. אני כל כך חכם. אבל זו קצת קוד חכם מדי, עדיף להימנע ממנו.
עם זאת, כשממירים את הקוד שלמעלה לפונקציה אסינכררונית, קל ליפול לסדר כרונולוגי מוגזם:
async function logInOrder(urls) { for (const url of urls) { const response = await fetch(url); console.log(await response.text()); } }
function markHandled(...promises) { Promise.allSettled(promises); } async function logInOrder(urls) { // fetch all the URLs in parallel const textPromises = urls.map(async (url) => { const response = await fetch(url); return response.text(); }); markHandled(...textPromises); // log them in sequence for (const textPromise of textPromises) { console.log(await textPromise); } }
reduce
"החכם" מוחלף בלולאת for רגילה, משעממת וקריאה.
כתיבת מאפיינים מותאמים אישית ב-Houdini
הנה דוגמה להגדרת מאפיין מותאם אישית (למשל: משתנה CSS), אבל עכשיו עם תחביר (סוג), ערך ראשוני (חלופה) וערכו של בוליאני בירושה (האם הוא יקבל בירושה את הערך מההורה או לא?). הדרך הנוכחית לעשות זאת היא באמצעות CSS.registerProperty()
ב-JavaScript, אבל ב-Chromium 85 ואילך תהיה תמיכה בתחביר @property
בקובצי ה-CSS:
CSS.registerProperty({ name: '--colorPrimary', syntax: '' , initialValue: 'magenta', inherits: false });
@property --colorPrimary { syntax: '' ; initial-value: magenta; inherits: false; }
עכשיו אפשר לגשת ל---colorPrimary
כמו לכל מאפיין CSS מותאם אישית אחר, דרך var(--colorPrimary)
. עם זאת, ההבדל הוא ש---colorPrimary
לא נקרא רק כמחרוזת. יש בו נתונים!
ב-CSS backdrop-filter
חל אפקט אחד או יותר על רכיב שקוף או שקוף למחצה. כדי להבין את זה, כדאי לעיין בתמונות הבאות.

.frosty-glass-pane { backdrop-filter: blur(2px); }

.frosty-glass-pane { opacity: .9; backdrop-filter: blur(2px); }
בתמונה שבצד ימין מוצגת עיבוד של רכיבים חופפים אם לא נעשה שימוש ב-backdrop-filter
או אם הוא לא נתמך. בתמונה שבצד ימין הוחל אפקט טשטוש באמצעות backdrop-filter
. שימו לב שהקוד משתמש ב-opacity
בנוסף ל-backdrop-filter
. בלי opacity
, לא יהיה על מה להחיל טשטוש. מובן מאליו שאם opacity
מוגדר כ-1
(אטום לחלוטין), לא תהיה השפעה על הרקע.
עם זאת, בניגוד לאירוע unload
, יש שימושים לגיטימיים באירוע beforeunload
. לדוגמה, כשרוצים להזהיר את המשתמש שיש לו שינויים שלא נשמרו, והם יאבדו אם הוא ייצא מהדף. במקרה כזה, מומלץ להוסיף מאזינים ל-beforeunload
רק כשיש למשתמש שינויים שלא נשמרו, ואז להסיר אותם מיד אחרי שמירת השינויים שלא נשמרו.
window.addEventListener('beforeunload', (event) => { if (pageHasUnsavedChanges()) { event.preventDefault(); return event.returnValue = 'Are you sure you want to exit?'; } });
beforeunload
ללא תנאים.
function beforeUnloadListener(event) { event.preventDefault(); return event.returnValue = 'Are you sure you want to exit?'; }; // A function that invokes a callback when the page has unsaved changes. onPageHasUnsavedChanges(() => { window.addEventListener('beforeunload', beforeUnloadListener); }); // A function that invokes a callback when the page's unsaved changes are resolved. onAllChangesSaved(() => { window.removeEventListener('beforeunload', beforeUnloadListener); });
beforeunload
רק כשצריך (ומסיר אותו כשלא צריך).
צמצום השימוש ב-Cache-Control: no-store
Cache-Control: no-store
היא כותרת HTTP ששרתי אינטרנט יכולים להגדיר בתגובות, ומורה לדפדפן לא לאחסן את התגובה במטמון HTTP כלשהו. צריך להשתמש באפשרות הזו במשאבים שמכילים מידע רגיש של משתמשים, למשל דפים שמוגנים באמצעות התחברות.
הרכיב fieldset
, שמכיל כל קבוצת קלט (.fieldset-item
), משתמש ב-gap: 1px
כדי ליצור את הקווים הדקים בין הרכיבים. אין פתרון מסובך לגבי גבולות!
.grid { display: grid; gap: 1px; background: var(--bg-surface-1); & > .fieldset-item { background: var(--bg-surface-2); } }
.grid { display: grid; & > .fieldset-item { background: var(--bg-surface-2); &:not(:last-child) { border-bottom: 1px solid var(--bg-surface-1); } } }
עיטוף טבעי של רשת
הפריסה המורכבת ביותר הייתה הפריסה ברמת המאקרו, מערכת הפריסה הלוגית בין <main>
ל-<form>
.
<input type="checkbox" id="text-notifications" name="text-notifications" >
<label for="text-notifications"> <h3>Text Messages</h3> <small>Get notified about all text messages sent to your device</small> </label>
הרכיב fieldset
, שמכיל כל קבוצת קלט (.fieldset-item
), משתמש ב-gap: 1px
כדי ליצור את גבולות הקו הדק בין הרכיבים. אין פתרון מסובך לשוליים!
.grid { display: grid; gap: 1px; background: var(--bg-surface-1); & > .fieldset-item { background: var(--bg-surface-2); } }
.grid { display: grid; & > .fieldset-item { background: var(--bg-surface-2); &:not(:last-child) { border-bottom: 1px solid var(--bg-surface-1); } } }
פריסת הכרטיסיות <header>
הפריסה הבאה דומה מאוד: אני משתמש ב-flex כדי ליצור סדר אנכי.
<snap-tabs> <header> <nav></nav> <span class="snap-indicator"></span> </header> <section></section> </snap-tabs>
header { display: flex; flex-direction: column; }
ה-.snap-indicator
צריך לנוע אופקית עם קבוצת הקישורים, וסידור הכותרת הזה עוזר ליצור את התרחיש הזה. אין כאן אלמנטים במיקום מוחלט!
אסטרטגיית Gentle Flex היא אסטרטגיה שמתמקדת רק במרכז המסך. התהליך רך ועדין, כי בניגוד ל-place-content: center
, גודל התיבות של הצאצאים לא משתנה במהלך ההצמדה למרכז. כל הפריטים נערמים, מתמקדים ומרווחים בצורה עדינה ככל האפשר.
.gentle-flex {
display: flex;
flex-direction: column;
align-items: center;
justify-content: center;
gap: 1ch;
}
- מטפל רק בהתאמה, בכיוון ובהפצה
- עריכה ותחזוקה במקום אחד
- Gap מבטיח מרחקים שווים בין n צאצאים
- מספר שורות הקוד הגדול ביותר
מתאימות גם לפריסות מאקרו וגם לפריסות מיקרו.
שימוש
אפשר להשתמש ב-gap
כערך של כל אורך או אחוז ב-CSS.
.gap-example {
display: grid;
gap: 10px;
gap: 2ch;
gap: 5%;
gap: 1em;
gap: 3vmax;
}
אפשר להעביר למאפיין Gap אורך של 1, והוא ישמש גם לשורה וגם לעמודה.
.grid { display: grid; gap: 10px; }
.grid { display: grid; row-gap: 10px; column-gap: 10px; }
אפשר להעביר ל-Gap 2 אורכי מחרוזות, שישמשו לשורה ולעמודה.
.grid { display: grid; gap: 10px 5%; }
.grid { display: grid; row-gap: 10px; column-gap: 5%; }