הרכיב <picture>
לא מבצע רינדור באופן עצמאי, אלא משמש כמנוע החלטות עבור רכיב <img>
פנימי
שאומר לו מה להציג. הפונקציה <picture>
פועלת לפי תקדים שכבר הוגדר על ידי הרכיבים <audio>
ו-<video>
: רכיב wrapper
שמכיל רכיבי <source>
בודדים.
<picture>
<source …>
<source …>
<img …>
</picture …>
<img>
הפנימי הזה מספק לך גם דפוס חלופי מהימן לדפדפנים ישנים יותר ללא תמיכה בתמונות רספונסיביות:
אם הדפדפן של המשתמש לא מזהה את הרכיב <picture>
, המערכת תתעלם ממנו. לאחר מכן המערכת מוחקת גם את הרכיבים <source>
,
כי הדפדפן לא יזהה אותן בכלל, או שלא יהיה לו הקשר משמעותי בשבילם בלי הורה <video>
או <audio>
.
עם זאת, כל דפדפן יזהה את רכיב <img>
הפנימי, והמקור שצוין ב-src
שלו יעובד כמצופה.
'תוכן אומנותי' תמונות עם <picture>
שינוי בתוכן או ביחס הגובה-רוחב של תמונה על סמך גודל התמונה בדף, בדרך כלל נקרא 'תוכן שנוצר בפורמט אומנותי'
לתמונות רספונסיביות. srcset
ו-sizes
תוכננו לפעול באופן בלתי נראה, ומחליפים מקורות בצורה חלקה בהתאם לפקודות הדפדפן של המשתמש.
עם זאת, לפעמים תרצו לשנות מקורות בנקודות עצירה שונות כדי להדגיש את התוכן בצורה טובה יותר, באותו אופן שבו אתם מתאימים את פריסות הדף.
לדוגמה: תמונת כותרת ברוחב מלא עם מיקוד קטן במרכז עשויה להתאים לאזור תצוגה גדול:
עם זאת, כשמגדילים את התצוגה כדי להתאים לאזורי תצוגה קטנים, המיקוד המרכזי של התמונה עלול להיאבד:
הנושא של מקורות התמונות האלה זהה, אבל כדי להתמקד טוב יותר בנושא הזה מבחינה חזותית, מומלץ יחסים של מקור התמונה שישתנו בין נקודות עצירה (breakpoint). לדוגמה, זום קצר יותר במרכז התמונה, וכן חלק מהפרטים בשוליים נחתכו:
סוג של "חיתוך" שניתן להשיג באמצעות שירות CSS, אבל המשתמש יצטרך לבקש את כל הנתונים שמהם מורכבת התמונה הזו, למרות שהם אולי אף פעם לא יראו אותו.
לכל רכיב source
יש מאפיינים שמגדירים את התנאים לבחירה של הנכס source
: media
, שמקבל
ו-type
, שמקבל סוג מדיה (לשעבר "סוג MIME"). <source>
הראשון במקור
כדי להתאים להקשר הגלישה הנוכחי של המשתמש נבחר, והתוכן של המאפיין srcset
באותו source
ישמשו לקביעת המועמדים המתאימים לאותו הקשר. בדוגמה הזו, הערך הראשון של source
עם המאפיין media
שתואם לגודל אזור התצוגה של המשתמש, הערך שייבחר יהיה:
<picture>
<source media="(min-width: 1200px)" srcset="wide-crop.jpg">
<img src="close-crop.jpg" alt="…">
</picture>
יש לציין תמיד את img
הפנימי האחרון לפי הסדר – אם אף אחד מהאלמנטים של source
לא תואם לרכיב media
או type
שלהם
קריטריונים מסוימים, התמונה תשמש כ"ברירת מחדל" מקור. אם משתמשים ב-min-width
שאילתות מדיה, מומלץ להשתמש בכמות הגדולה ביותר
קודם, כפי שאפשר לראות בקוד הקודם. כשמשתמשים בשאילתות מדיה עם max-width
, צריך לציין קודם את המקור הקטן ביותר.
<picture>
<source media="(max-width: 400px)" srcset="mid-bp.jpg">
<source media="(max-width: 800px)" srcset="high-bp.jpg">
<img src="highest-bp.jpg" alt="…">
</picture>
כשמקור נבחר על סמך הקריטריונים שציינתם, המאפיין srcset
ב-source
מועבר אל
<img>
, כאילו שהיא הוגדרה ב-<img>
עצמה – כלומר, אפשר להשתמש ב-sizes
כדי לבצע אופטימיזציה של תמונה שמיועדת לגרפיקה
גם במקורות שונים.
<picture>
<source media="(min-width: 800px)" srcset="high-bp-1600.jpg 1600w, high-bp-1000.jpg 1000w">
<source srcset="lower-bp-1200.jpg 1200w, lower-bp-800.jpg 800w">
<img src="fallback.jpg" alt="…" sizes="calc(100vw - 2em)">
</picture>
כמובן שתמונה עם פרופורציות שיכולות להשתנות בהתאם לרכיב <source>
שנבחר יוצרת בעיה בביצועים:
ב-<img>
יש תמיכה רק במאפיינים width
ו-height
בודדים, אבל השמטת המאפיינים האלה עלולה לפגוע בחוויית המשתמש.
כדי להביא בחשבון את התופעה הזו, מדובר בלאחרונה –
תמיכה טובה – תוספת ל-HTML
המפרט מאפשר להשתמש במאפיינים height
ו-width
ברכיבי <source>
. הפעולות האלה נועדו לצמצם את השינויים בפריסה
כמו שהם עושים ב-<img>
, עם השטח המתאים ששמור בפריסה לכל רכיב של <source>
שנבחר.
<picture>
<source
media="(min-width: 800px)"
srcset="high-bp-1600.jpg 1600w, high-bp-1000.jpg 1000w"
width="1600"
height="800">
<img src="fallback.jpg"
srcset="lower-bp-1200.jpg 1200w, lower-bp-800.jpg 800w"
sizes="calc(100vw - 2em)"
width="1200"
height="750"
alt="…">
</picture>
חשוב לציין שאפשר להסתמך על כיוון הגרפיקה של המסך לקבלת החלטות שמבוססות על גודל אזור התצוגה, ולא ניתן לשנות את הכיוון של הטקסט,
ברוב המקרים האלה אפשר לטפל בצורה יעילה יותר באמצעות srcset
מתוך sizes
. לדוגמה, בחירה טובה יותר של מקור התמונה
שמותאמת לערכת הצבעים שנקבעה על ידי העדפת המשתמש:
<picture>
<source media="(prefers-color-scheme: dark)" srcset="hero-dark.jpg">
<img srcset="hero-light.jpg">
</picture>
המאפיין type
המאפיין type
מאפשר לך להשתמש במנוע קבלת ההחלטות, הבקשה אחת בלבד של הרכיב <picture>
כדי להציג רק פורמטים של תמונות
לדפדפנים שתומכים בהם.
כפי שלמדתם בקטע פורמטים של תמונות ודחיסה, קידוד שהדפדפן לא יכול לנתח אפילו לא יהיה מזוהה בתור של נתוני תמונה.
לפני ההשקה של האלמנט <picture>
, היה צורך בפתרונות הקצה הקדמיים השימושיים ביותר להצגת פורמטים חדשים של תמונות.
לדפדפן לבקש ולנסות לנתח קובץ תמונה לפני ההחלטה אם להשליך אותו או לטעון חלופה. א'
דוגמה נפוצה הייתה סקריפט שמנוסח בשורות הבאות:
<img src="image.webp"
data-fallback="image.jpg"
onerror="this.src=this.getAttribute('data-fallback'); this.onerror=null;"
alt="...">
עם קו ביטול הנעילה הזה, עדיין תתבצע בקשה עבור image.webp
בכל דפדפן – כלומר העברה לא מנוצלת של דפדפנים
ללא תמיכה ב-WebP. דפדפנים שלא היו יכולים לנתח את הקידוד של WebP יזינו אירוע onerror
ויחליפו
את הערך data-fallback
ב-src
. זה היה פתרון בזבזני, אבל שוב, גישות כמו זו הייתה האפשרות היחידה
יהיו זמינות בקצה הקדמי. זכרו שהדפדפן מתחיל לשלוח בקשות לתמונות לפני שסקריפט מותאם אישית כלשהו
להפעיל את הכלי - או אפילו לנתח אותו - כך שלא יכולנו למנוע את התהליך הזה.
הרכיב <picture>
מתוכנן באופן מפורש למנוע את הבקשות המיותרות האלה. עדיין אין דרך להשתמש בדפדפן
כדי לזהות פורמט שהוא לא תומך בו בלי לבקש אותו, המאפיין type
מזהיר את הדפדפן לגבי המקור
מראש, כדי שהיא תוכל להחליט אם לשלוח בקשה.
במאפיין type
, מציינים את סוג המדיה (סוג MIME לשעבר)
של מקור התמונה שצוין במאפיין srcset
של כל <source>
. כך הדפדפן מקבל את כל המידע
צריך לקבוע באופן מיידי אם אפשר לפענח את התמונה הפוטנציאלית שסופקה על ידי source
, בלי לבצע שום פעולה חיצונית
בקשות — אם סוג המדיה לא מזוהה, המערכת מתעלמת מהשדה <source>
ומכל המועמדים שלו, והדפדפן ממשיך הלאה.
<picture>
<source type="image/webp" srcset="pic.webp">
<img src="pic.jpg" alt="...">
</picture>
כאן, כל דפדפן שתומך בקידוד WebP יזהה את סוג המדיה image/webp
שצוין במאפיין type
של הרכיב <source>
, צריך לבחור את המימד <source>
, ובגלל שסיפקנו רק מועמד אחד ב-srcset
<img>
כדי לבקש, להעביר ולעבד את pic.webp
. כל דפדפן שאין לו תמיכה ב-WebP יתעלם מהsource
, וגם
בהיעדר הוראות מנוגדות, <img>
יציג את התוכן של src
כפי שנעשה מאז 1992.
כמובן שאין צורך לציין כאן רכיב <source>
שני עם type="image/jpeg"
— אפשר להניח שיש תמיכה אוניברסלית ב-JPEG.
ללא קשר להקשר הגלישה של המשתמש, כל זה מתבצע באמצעות העברת קובץ יחידה, ללא שימוש ברוחב פס מיותר
מקורות של תמונות שלא ניתן לעבד. זאת גם מחשבה קדימה: בהמשך נוסיף פורמטים חדשים ויעילים יותר של קבצים.
עם סוגי מדיה משל עצמם, ונוכל לנצל אותם בזכות picture
— ללא JavaScript וללא צד השרת
ואת כל המהירות של <img>
.
העתיד של תמונות רספונסיביות
כל דפוסי תגי העיצוב שהוזכרו כאן היו עלייה משמעותית במונחים של תקן: שינוי הפונקציונליות של
משהו שכבר מובן ומרכזי את האינטרנט, כמו <img>
אתגר לא פשוט, ואוסף הבעיות שהעלו השינויים
היו מקיפות יותר, או במילים אחרות, הצעות לפתרון. אם גיליתם שיש הרבה מקום לשיפור,
לתבניות תגי עיצוב, נכון מאוד. מלכתחילה, מטרתם של סטנדרטים אלה הייתה לספק בסיס לעתיד
שעליה אפשר להתבסס.
כל הפתרונות האלה תלויים בהכרח בתגי עיצוב, כדי להיכלל במטען הייעודי (payload) הראשוני מהשרת,
ולהגיע בזמן לדפדפן לבקש מקורות של תמונות – מגבלה שהובילה למאפיין sizes
המורכב לכאורה.
עם זאת, מאז שהתכונות האלה נוספו לפלטפורמת האינטרנט, הושקה שיטה מקורית לדחיית בקשות תמונה.
<img>
רכיבים עם המאפיין loading="lazy"
לא יישלחו עד שפריסת הדף ידועה, כדי לדחות את הבקשה
בקשות לתמונות מחוץ לאזור התצוגה הראשוני של המשתמש עד למועד מאוחר יותר בתהליך עיבוד הדף, דבר שעלול למנוע
בקשות מיותרות. מאחר שהדפדפן מבין באופן מלא את פריסת הדף בזמן שמתבצעות הבקשות האלה,
הוצע המאפיין sizes="auto"
כתוספת למפרט ה-HTML
כדי להימנע מהטרחה של מאפייני sizes
שנכתבו באופן ידני במקרים כאלה.
יש גם תוספות לרכיב <picture>
באופק, כדי להתאים לכמה שינויים מרגשים במיוחד
ועד לאופן שבו אנחנו מעצבים פריסות דפים. המידע על אזור התצוגה הוא בסיס טוב להחלטות פריסה כלליות, אבל
מונעת מאיתנו לנקוט גישה לפיתוח ברמת הרכיבים המלאים, כלומר רכיב שאפשר לשים
בכל חלק בפריסת דף, עם סגנונות שמגיבים לשטח שתופס הרכיב עצמו. חשש זה גרם
ליצירת שאילתות קונטיינר: שיטה של עיצוב רכיבים
על סמך הגודל של מאגר ההורה שלהם, ולא על סמך אזור התצוגה בלבד.
התחביר של שאילתות הקונטיינר רק התייצב, והתמיכה בדפדפן מוגבלת מאוד,
בזמן הכתיבה - ההוספה של טכנולוגיות הדפדפן שמאפשרות לו לספק לרכיב <picture>
לעשות את אותו הדבר: מאפיין container
פוטנציאלי שמאפשר בחירה של <source>
קריטריונים לפי
המרחב ב-<img>
של הרכיב <picture>
, ולא על סמך הגודל של אזור התצוגה.
אם זה נשמע קצת מעורפל, יש סיבה טובה לכך: הדיונים על תקני האינטרנט האלה נמשכים, אבל רחוקים מלהיקבע — עדיין לא יכול להשתמש בהם.
למרות שתגי עיצוב של תמונות רספונסיביות מבטיחים שרק קל יותר לעבוד איתן עם הזמן, כמו בכל טכנולוגיה אינטרנטית, יש לכך של שירותים, טכנולוגיות ומסגרות שיעזרו להקל על העומס של כתיבה ידנית של תגי העיצוב האלה. במודול הבא, נלמד איך לשלב את כל מה שלמדנו על פורמטים של תמונות, דחיסה ותמונות רספונסיביות בתהליך העבודה המודרני של הפיתוח.