הצצה לתהליך ולכלים ששימשו ליצירת חוויית Designcember בסגנון יומן חגים.
בדצמבר יש הרבה יומנים שאנשים משתמשים בהם כדי לספור לאחור ולחגוג, ולכן רצינו להבליט תוכן באינטרנט מהקהילה ומצוות Chrome. בכל יום הדגשנו פריט אחד של תוכן שקשור לפיתוח ממשק משתמש ולעיצוב, בסך 31 פריטים. בין הפריטים האלה היו 26 אתרי הדגמה, כלים, הודעות, פודקאסטים, סרטונים, מאמרים ומחקרים חדשים.
אפשר לראות את החוויה המלאה בכתובת designcember.com.
סקירה כללית
המטרה שלנו הייתה לספק חוויית אינטרנט נגישה, מודרנית, רספונסיבית וחיננית, בשימוש בפחות בייטים ככל האפשר. רצינו להדגיש ממשקי API חדשים ותואמים למגוון מסכים, כמו שאילתות בקונטיינרים, וגם לכלול דוגמה יפה למצב כהה באתר שמתמקד בעיצוב ובעל הרבה נכסים. כדי לעשות זאת, דחסנו קובצי, הצגנו כמה פורמטים, השתמשנו בכלי build שהותאמו ליצירת אתרים סטטיים, השקנו polyfill חדש ועוד.
התחלה עם דמיון
הרעיון מאחורי האתר של יומן Designcember היה להציג בו את כל העבודות שרצינו להבליט במהלך חודש דצמבר, תוך שימוש בו כאתר הדגמה. החלטנו לבנות בניין דירות רספונסיבי שיכול להיות גבוה וצר או קצר ורחב, עם חלונות שמתארגנים מחדש בתוך המסגרת. כל חלון ייצג יום אחד (ולכן, קטע תוכן אחד). עבדנו עם המאיירת Alice Lee כדי להפוך את החזון שלנו למציאות.
אליס הייתה מעוררת השראה, ושיתפה תהליכים ורישומים שהיו מעניינים גם ברעיונות המוקדמים שלהם. בזמן שהיא עבדה על הגרפיקה, אנחנו עבדנו על הארכיטקטורה. הדיונים המוקדמים התמקדו בפריסה המאקרוסקופית, בבניין ובחלונות שלו. איך החלונות יתאימו לעמודה אחת, שתיים או שלוש ככל שיהיו יותר שטחי תצוגה זמינים? עד כמה הם יכולים להתכווץ או להתמתח? מהו הגודל המקסימלי של הבניין? כמה החלונות יזוזו?
לפניכם תצוגה מקדימה של אב טיפוס רספונסיבי באמצעות grid-auto-flow: dense
, שמראה איך החלונות יכולים להיות ממוקמים באופן אוטומטי על ידי אלגוריתם התצוגה. מהר מאוד הבנו שגם אם רשתות עם יחסי גובה-רוחב מתאימים נהדר להצגת גרפיקה, הן לא מאפשרות לחלונות להתרחב ולהתכווץ במרחב זמין לא אחיד, ולהציג את העוצמה של שאילתות בקונטיינרים.
אחרי שהמרשת הכללית הייתה יציבה יחסית והעבירה תחושה של כיוון לגבי תגובת המבנה והחלונות שלו, הצלחנו להתמקד בחלון אחד. חלק מהחלונות התארכו, התכווצו, התכווצו, התרחבו והתאימו את עצמם מחדש יותר מאחרים בתצוגה.
כל חלון יצטרך להתמודד עם כמות מסוימת של תנודות בגודל. בהמשך מוצג אב טיפוס של חלון שמראה את התגובה שלו לתנודות, ומראה עד כמה אפשר לצפות שכל חלון אינטראקטיבי יתאים את עצמו.
אנימציה של חלונות באמצעות גיליונות פריימים
בחלק מהחלונות יש אנימציות כדי להוסיף אינטראקציה לחוויה. האנימציות נוצרות ביד, פריים אחרי פריים, ב-Photoshop. כל פריים מיוצא, הופך לגיליון פריימים באמצעות הכלי הזה ליצירת גיליונות פריימים, ולאחר מכן עובר אופטימיזציה באמצעות Squoosh. לאחר מכן, אנימציית ה-CSS משתמשת ב-background-position-x
וב-animation-timing-function
, כפי שמוצג בדוגמה הבאה.
.una
background: url("/day1/una_sprite.webp") 0% 0%;
background-size: 400% auto;
}
.day:is(:hover, :focus-within) .una {
animation: una-wave .5s steps(1) alternate infinite;
}
@keyframes una-wave {
0% { background-position-x: 0%; }
25% { background-position-x: 300%; }
50% { background-position-x: 200%; }
75% { background-position-x: 100%; }
}
אנימציות מסוימות, כמו חביתת הכסף של יום שישי, היו אנימציות CSS מבוססות-שלבים.
השגנו את האפקט הזה באמצעות טכניקה דומה, באמצעות steps()
, עם ההבדל שהנקודות העיקריות היו מיקומי טרנספורמציה של CSS במקום מיקומי רקע.
אנונימיזציה של CSS
לחלק מהחלונות היו צורות ייחודיות. השתמשנו במסכות וב-aspect-ratio
כדי ליצור חלון גמיש, בעל צורה ייחודית ומתאים לעיצוב.
כדי ליצור מסכה, כמו זו של חלון שמונה, נדרשו כמה מיומנויות קלאסיות ב-Photoshop, וגם קצת ידע על האופן שבו מסכות פועלות באינטרנט. נבחן את החלון של היום השמיני.
כדי ליצור מסכה, צריך לבודד את הצורה הפנימית בצורת תלתן בעל ארבעה עלים כצורה נפרדת ולמלא אותה בצבע לבן. הצבע הלבן מאפשר ל-CSS לקבוע איזה תוכן יישאר ואיזה תוכן לא יישאר. ב-Photoshop, בחרנו את החלק הפנימי של החלון, הוספנו לו 1px מעוגל (כדי להסיר בעיות של אליאסיינג), מילאנו אותו בלבן וייצאנו אותו באותו גובה ורוחב כמו מסגרת החלון. כך אפשר להציב את המסגרת ואת המסכה בשכבות זו על גבי זו, ולהציג את התוכן הפנימי בתוך המסגרת כצפוי.
בסיום, תוכלו לשנות את תוכן החלון והוא תמיד יופיע בתוך המסגרת בהתאמה אישית. בתמונה הבאה מוצגת גרסת החלון במצב כהה, עם שיפוע רקע שונה ופפילטר CSS של זוהר שהוחל על התאורה.
הוספת מסיכה תומכת גם בחלונות רספונסיביים שמבוססים על שאילתות בקונטיינרים. בחלון התשיעי מופיע דמות שמוסתר מאחורי מסכה עד שהחלון צר יותר. כדי לוודא שהמשתמש לא יוכל לשנות את התמונה כך שהיא תצא מהפריים, עינת השלימה עבורנו את הדמות במלואה. הדמות ממוסתרת בחלון, אבל הצמחים לא, ולכן אחד האתגרים שטיפלנו בהם היה להוסיף שכבות של רכיבים מוסתרים לשכבות ללא מסכה, ולוודא שהכול יתאים יחד.
בתמונה הבאה אפשר לראות איך זה נראה בלי המסכה על החלון והדמות.
דחיפת התמונה
כדי לשמור על איכות האיור ולהבטיח שחוויית המשתמש במסכים ברזולוציה גבוהה לא תהיה מטושטשת, עינת עבדה ביחס פיקסלים של 3x. התכנון היה להשתמש ב-imgix ולהציג תמונות ופורמטים שעברו אופטימיזציה בשרת שלהם, אבל גילינו ששינוי ידני באמצעות הכלי Squoosh יכול לחסוך לנו 50% או יותר.
איור מציב אתגרים ייחודיים לדחיסה, במיוחד בזכות הבריש והסגנון של אליס עם הקצוות השקופים והמחוספסים. בחרנו להשתמש ב-Squoosh כדי לדחוס כל תמונה בפורמט PNG בגודל 3x שיוצאה מ-Photoshop, לתמונות קטנות יותר בפורמטים PNG, WebP ו-AVIF. לכל סוג קובץ יש יכולות דחיסה מיוחדות משלו, ונדרשו לנו יותר מ-50 תמונות כדי למצוא כמה הגדרות אופטימיזציה נפוצות.
Squoosh CLI היה חיוני כשהיה צריך לבצע אופטימיזציה של יותר מ-200 תמונות – ביצוע כל הפעולות האלה באופן ידני היה לוקח ימים. אחרי שהגדרות האופטימיזציה הנפוצות היו ברשותנו, סיפקנו אותן כהוראות בשורת הפקודה וביצענו עיבוד בכמות גדולה של תיקיות שלמות של תמונות PNG לתמונות מקבילות בפורמטים WebP ו-AVIF בדחיסה.
זוהי דוגמה לפקודת squoosh ב-CLI של AVIF:
npx @squoosh/cli --quant '{"enabled":true,"zx":0,"maxNumColors":256,"dither":1}' --avif '{"cqLevel":19,"cqAlphaLevel":17,"subsample":1,"tileColsLog2":0,"tileRowsLog2":0,"speed":6,"chromaDeltaQ":false,"sharpness":5,"denoiseLevel":0,"tune":0}' image-1.png image-2.png image-3.png
אחרי שהוספת הגרפיקה האופטימיזציה למאגר, אפשר להתחיל לטעון אותה מ-HTML:
<picture>
<source srcset="/day1/inner-frame.avif" type="image/avif">
<source srcset="/day1/inner-frame.webp" type="image/webp">
<img alt="" decoding="async" role="presentation" src="/day1/inner-frame.png">
</picture>
כתיבת קוד המקור של התמונות הייתה חזרה על עצמה, לכן יצרנו רכיב Astro להטמעת תמונות באמצעות שורת קוד אחת.
<Pic filename="day1/inner-frame" role="presentation" />
משתמשים בקורא מסך ובמקלדת
חלק גדול מחוויית Designcember מתבסס על האמנות והחלונות האינטראקטיביים. חשוב לנו שמשתמשים עם מקלדת יוכלו להשתמש באתר ולהציץ בחלונות, ושמשתמשים בקורא מסך ייהנו מחוויה נעימה עם קריינות.
לדוגמה, כשהטמענו את התמונות, השתמשנו ב-role="presentation"
כדי לסמן את התמונה כתמונה חזותית עבור קוראי מסך. לדעתנו, חוויית המשתמש תהיה גרועה אם יהיו 5 עד 12 תיאורים מקוטעים של alt
. לכן, סימנו את התמונות כתמונות להצגה וסיפקנו קריינות כללית על החלון. כך, כשעוברים בין החלונות באמצעות קורא מסך, יש תחושה של נרטיב נעים, שבעזרתו אנחנו מקווים להעביר את השובבות והכיף שאנחנו רוצים לשתף באתר.
בסרטון הבא מוצגת הדגמה של חוויית השימוש במקלדת. מקשי Tab, Enter, מקש הרווח ומקש Escape משמשים לתזמור המיקוד אל החלונות הקופצים והחלונות ומהם.
חוויית השימוש עם קורא המסך כוללת מאפייני ARIA מיוחדים שמבהירים את התוכן. לדוגמה, בקישור ליום מסוים כתוב רק 'יום אחד' או 'יום שני', אבל עם הוספת קצת ARIA, הקריינות תהיה 'יום אחד' ו'יום שני'. בנוסף, כל התמונות מסוכמות בתווית אחת, כך שלכל חלון יש תיאור.
Astro, כלי ליצירת אתרים סטטיים מבוססי-רכיבים
Astro עזר לצוות לעבוד יחד בקלות באתר. מודל הרכיבים היה מוכר למפתחי Angular ו-React, ומערכת הסגנונות של שמות הכיתות ברמת ההיקף עזרה לכל מפתח לדעת שהעבודה שלו בחלון לא תהיה בניגוד לעבודה של אף אחד אחר.
ימים כרכיבים
כל יום היה רכיב שאחזר סטטוס ממאגר נתונים של זמן build. כך אנחנו יכולים להריץ את הלוגיקה של התבנית לפני שה-HTML מגיע לדפדפן. הלוגיקה תקבע אם יוצג חלון קופץ עם הסבר על היום או לא, כי בימים לא פעילים אין חלונות קופצים.
הגרסאות הבנויות מופעלות כל שעה, ומאגר הנתונים של זמן ה-build יפתח יום חדש כשהשעה בשרת ה-build תהיה אחרי חצות. המערכות הקטנות האלה מתעדכנות באופן עצמאי ומספקות את כל מה שדרוש כדי שהאתר יהיה מעודכן.
סגנונות מוגדרים-היקף ו-Open Props
ב-Astro הסגנונות שנכתבים בתוך מודל הרכיבים ממופים, כך שקל יותר לחלק את עומס העבודה בין חברי צוות רבים, וגם כיף להשתמש ב-Open Props. הסגנונות של Open Props normalize.css עזרו לנו להתאים את העיצוב (בהיר וכהה) לעיצוב מותאם אישית, וגם לטפל בתוכן כמו פסקאות וכותרות.
כמשתמשים מוקדמים ב-Astro, נתקלנו בכמה בעיות ב-PostCSS. לדוגמה, לא הצלחנו לעדכן לגרסה האחרונה של Astro בגלל יותר מדי בעיות ב-build. אפשר להקדיש זמן נוסף לנושא הזה ולבצע אופטימיזציה של תהליכי העבודה של ה-build והמפתחים.
קונטיינרים גמישים
חלק מהחלונות מתרחבים ומתכווצים, תוך שמירה על יחס גובה-רוחב כדי לשמור על הגרפיקה שלהם. השתמשנו בחלונות נוספים כדי להמחיש את העוצמה של ארכיטקטורה מבוססת-רכיבים עם שאילתות בקונטיינרים. שאילתות בקונטיינרים אפשרו לחלונות להכיל מידע ספציפי לגבי עיצוב רספונסיבי, ולהתאים את עצמם על סמך הגדלים שלהם. חלק מהחלונות עברו מצר לרחבים, ולכן היה צריך לשנות את גודל המדיה שבתוכם ואת המיקום שלה.
ככל שיהיו יותר שטחים פנויים לחלון, נוכל לשנות את הגודל או את רכיבי הצאצאים של החלון כדי להתאים אותו. התברר ששאילתות מאגר הן לא רק דרך מעניינת להציג חלונות מותאמים, אלא הן נדרשות כדי לאפשר תזמור פשוט יותר של פריסות מסוימות.
.day {
container: inline-size;
}
.day > .pane {
min-block-size: 250px;
@container (min-width: 220px) {
min-block-size: 300px;
}
@container (min-width: 260px) {
min-block-size: 310px;
}
@container (min-width: 360px) {
min-block-size: 450px;
}
}
הגישה הזו שונה מהשמירה על יחס גובה-רוחב. הוא מספק יותר שליטה והזדמנויות נוספות. בגיל מסוים, הרבה ילדים זזים כדי להתאים את עצמם לפריסה חדשה.
שאילתות של קונטיינרים גם אפשרו לנו לתמוך בתוכן בכיוון חסימה (אנכי), כך שככל שהחלון התארך, יכולנו לשנות את הסגנונות שלו כך שיתאימו. ניתן לראות זאת בשאילתות שמבוססות על גובה, שבהן השתמשנו בנפרד, ובנוסף לשאילתות שמבוססות על רוחב:
.person {
place-self: flex-end;
margin-block: 25% 50%;
margin-inline-start: -15%;
z-index: var(--layer-1);
@container (max-height: 350px) and (max-width: 425px) {
place-self: center flex-end;
inline-size: 50%;
inset-block-end: -15%;
margin-block-start: -2%;
margin-block-end: -25%;
z-index: var(--layer-2);
}
}
השתמשנו גם בשאילתות מאגר כדי להציג ולהסתיר פרטים, כי התמונות נעשות צפופות יותר בגדלים קטנים יותר ורקות יותר בגדלים רחבים יותר. חלון תשע הוא דוגמה מצוינת לכך:
תמיכה בדפדפנים שונים
כדי ליצור חוויה מודרנית נהדרת בדפדפנים שונים, במיוחד לממשקי API ניסיוניים כמו שאילתות בקונטיינרים, אנחנו צריכים polyfill מצוין. שלחנו קריאה לצוות שלנו, וסורמה הובילה את פיתוח ה-build של polyfill חדש לשאילתות בקונטיינרים. הפוליפיל מבוסס על ResizeObserver, MutationObserver ועל הפונקציה :is() ב-CSS. לכן, כל הדפדפנים המודרניים תומכים ב-polyfill, במיוחד Chrome ו-Edge מגרסה 88, Firefox מגרסה 78 ו-Safari מגרסה 14. השימוש ב-polyfill מאפשר להשתמש בכל אחד מהתחבירים הבאים:
/* These are all equivalent */
@container (min-width: 200px) {
/* ... */
}
@container (width >= 200px) {
/* ... */
}
@container size(width >= 200px) {
/* ... */
}
מצב כהה
עוד טאצ' אחרון שהיה חיוני לאתר של Designcember היה עיצוב כהה יפהפה. רצינו להראות איך אפשר להשתמש באמנות עצמה כדי להיות שותפים פעילים ביצירת חוויה מעולה במצב כהה. לשם כך, שינינו את סגנונות הרקע של כל חלון באופן פרוגרמטי, והשתמשנו ב-CSS כמה שאפשר כשיצאנו את הגרפיקה של החלון. רוב הרקעים היו פסילות CSS, כדי שיהיה קל יותר לשנות את ערכי הצבעים שלהם. לאחר מכן הנחנו את הגרפיקה מעליהם.
ביצי הפתעה נוספות
נגיעות אישיות
הוספנו כמה נגיעות אישיות לדף כדי להוסיף לאתר יותר אישיות. החלק הראשון היה צוות הדמויות, שנוצר בהשראת הצוות שלנו. הוספנו גם סמן בסגנון רטרו בימים שבהם לא הייתה פעילות, וניסינו כמה סגנונות של סמל דף הבית.
נגיעות פונקציונליות
אחת מהתכונות הפונקציונליות הנוספות היא 'מעבר ל'היום', עם ציפור שפטרוסה על גג הבניין. לחיצה על הציפור או הקשה על מקש Enter תעביר אתכם למטה בדף אל היום הנוכחי בחודש, כדי שתוכלו להגיע במהירות להשקות האחרונות.
באתר Designcember.com יש גם גיליון מיוחד של סגנונות עיצוב להדפסה, שבו אנחנו למעשה מציגים תמונה ספציפית שמתאימה במיוחד לנייר בגודל 21.6 x 27.9 ס"מ, כדי שתוכלו להדפיס את היומן בעצמכם ולשמור על האווירה החגיגית כל השנה.
בסך הכול, השקענו המון עבודה כדי ליצור חוויית שימוש מודרנית, מהנה וחיננית באתר, כדי לחגוג את פיתוח ממשק המשתמש במשך כל חודש דצמבר. אנחנו מקווים שנהניתם!