לאחרונה נתקלתי מספר פעמים בשאלה איך לבנות רכיב שמכיל תמונה, כאשר לפעמים התשובה היא "יש להשתמש בimg" ולפעמים התשובה היא להשתמש בdiv עם הגדרת background-image
. בפוסט הזה נפרט קצת על ההבדלים ביניהם, ונלמד מתי כדאי להשתמש בכל הגדרה
שימוש בתגית img
לכל תמונה שמוטמעת בעמוד יש רוחב וגובה כלשהם, אלו האורך והרוחב המקוריים שלה. כאשר אנחנו משתמשים בתגית של תמונה, כברירת מחדל התמונה תופיע בגודל המקורי. אם נניח, וניתן לתמונה שלנו הגדרת רוחב, וללא הגדרת גובה, או לחילופין height: auto
– התמונה תגדל/תתכווץ לרוחב שהגדרנו, והגובה שלה יגדל/יקטן בהתאמה.
נניח שיש לנו תמונה באורך וברוחב של 100 פיקסלים. הגדרנו לה רוחב של 150 פיקסלים, וכן height: auto
– כעת הן הרוחב והן הגובה יהיו 150 פיקסלים. כלומר – הגובה יודע להתאים את עצמו באופן אוטומטי, בהתאם לרוחב.
וכן להיפך – אם נגדיר לתמונה width: auto, height: 25px
– הרי שכעת גם האורך וגם הרוחב יהיו לנו 25 פיקסלים. הגובה יהיה 25 פיקסלים – כי זה מה שהוגדר לו, והרוחב יהיה 25 פיקסלים כי זו תמונה ריבועית, ולא הוגדר רוחב אחר, לכן הרוחב יתאים את עצמו לגובה, לפי היחס המקורי של רוחב/גובה.
יש מצבים שבהם אנחנו רוצים שהתמונה תכנס לגודל מסויים. נניח שיש לנו באנר לעמוד, תמונה שאמורה לתפוס את מלא רוחב המסך, וגובהה קבוע בפיקסלים. במקרה הזה – הדרישה היא שתמונה יהיו גם רוחב וגם גובה קבועים.
אם ניתן לתמונה כזו לצורך העניין width: 100%; height: 300px
– הרי שיש מצבים שהיא תאבד את הפרופורציה שלה ותראה מעוותת. אם ניתן כדוגמה תמונה בגודל של 1000 פיקסלים רוחב, ו300 פיקסלים גובה – הרי שבמסך ברוחב של 1000 פיקסלים – התמונה תתאים במדויק ותראה נהדר, אבל במסכים רחבים של 1920 פיקסלים רוחב – התמונה תהיה מתוחה מאד, ותאבד לחלוטין את הפרופורציה שלה.
ההגדרה Object-fit
עבור מקרים כאלה נועדה ההגדרה object-fit
בCSS. ההגדרה הזו מאפשרת לנו להגדיר תמונה עם גובה ורוחב, ואז את ההתנהגות של התמונה, במידה והגודל המקורי לא תואם את הגודל הנדרש. ההגדרה object-fit מקבלת את הערכים הבאים:
fill
– ברירת המחדל. התמונה תמלא את מלא הגודל הנדרש, גם אם היא צריכה להימתח לאורך או לרוחב, מה שיגרום לה לאבד את הפרופורציה.contain
– מקביל לערךcontain
של ההגדרהbackground-size
. התמונה תמלא את הגודל הנדרש באופן כזה שאם אין התאמה ביחס האורך/רוחב בין הגודל המקורי לגודל הנדרש – התמונה תמלא את מלא הגובה/הרוחב, כך שיהיו שוליים במידת הצורך.
לדוגמה תמונה בגודל של 100 רוחב על 150 גובה, נדרשת לקבל 100 פיקסלים רוחב על 250 פיקסלים גובה. התמונה תתפוס 100 פיקסלים גובה (כמו הגובה המקורי שלה), ותישאר בגובה של 150 פיקסלים, ושאר ה100 פיקסלים הנותרים לרוחב הנדרש – יהיו שוליים ריקים.cover
– מקביל לערךcover
של ההגדרהbackground-size
. התמונה תמלא את הגודל הנדרש באופן כזה שלא יישארו שוליים ריקים, אלא במידת הצורך התמונה תיחתך.
אם ניקח לדוגמה תמונה בגודל של 50 פיקסלים רוחב, על 100 פיקסלים גובה (כלומר – הגובה הוא פי 2 מהרוחב), שצריכה להכנס לגודל של 200*200 – בכזה מקרה התמונה תגדל באופן שהרוחב שלה יתפוס 200 פיקסלים, והגובה יגדל ל400 (שמירה על הפרופורציה המקורית שלה), ומאחר והגובה הנדרש הוא רק 200 – הרי שמתוך ה400 בגובה, ייחתכו 200 פיקסלים שאותם לא נראה.none
– התמונה לא תגדל/תקטן, אלא תישאר בגודל המקורי שלה ורק תיחתך/יתווספו שוליים במידת הצורך.
אם יש לנו תמונה בגודל של 300*300, ואנו מגדירים לה רוחב 200 פיקסלים, וגובה של 400 פיקסלים – הרי שברוחב ייחתכו לנו 100 פיקסלים, ובגובה יישארו שוליים ריקים של 100 פיקסלים.scale-down
– התמונה תתנהג כאילו הוגדר contain או none, הקטן מביניהם.
אם יש לנו תמונה בגודל 300*300, ואנחנו מגדירים לה גודל של 400*400 – היא תישאר בגודל המקורי שלה ויהיו שוליים ריקים של 100 לרוחב ו100 לגובה (התנהגות כמו none). לעומת זאת אם לאותה תמונה נגדיר גודל של 200*200 – היא תתנהג כמו contain ותמלא את מלא הגודל, תוך שהיא קטנה.
כלומר, בדיוק כמו השם scale-down – גודל התמונה משתנה (scale) רק כלפי מטה (down).
בדוגמה שלהלן תוכלו לראות את ההתנהגות השונה של ההגדרות השונות (ממליצה לפתוח במסך מלא כדי לחוות את ההתנהגות באופן המיטבי):
העניין הבעייתי היחיד עם ההגדרה object-fit היא תמיכת הדפדפנים שלה. לפי האתר can i use ההגדרה עדיין לא נתמכת בדפדפן internet explorer,לכן אם ישנה דרישה שהאתר ייתמך באופן מלא גם בדפדפן IE – לא תוכלו להסתמך על ההגדרה object-fit. בשביל זה יש את ההגדרה background-image.
background-image + background-size
על האפשרות של הגדרת תמונה כרקע של אלמנט HTML כלשהו – דברנו בהרחבה בפוסט על ההגדרה background, תוכלו לחזור לשם ולקרוא על האפשרויות השונות של background-size
.
אז מה עדיף – img או background-image?
קודם כל – כאשר יש לנו תמונה שצריכה להיות בגודל המקורי שלה, או יותר נכון, ביחס הרוחב/גובה שלה, כמו אייקונים, תמונת לוגו וכדו' – יש עדיפות מובהקת לשימוש בתגית img.
הבעיה מתחילה כאשר אנחנו נכנסים לתמונות שאמורות לשמש כרקע לאלמנט עם גובה מסויים. זה יכול להיות בבאנר שנזכר למעלה, זה יכול להיות רכיב של תמונה בגודל קבוע מעל/מתחת/ליד איזור טקסט, זה יכול להיות מבנה של כרטיסיות תוכן, כאשר למעלה יש תמונה בגודל אחיד לכל הכרטיסיות, מתחתיה תוכן, זה יכול להיות בתמונות מוקטנות לגלריה (thumbnails) וכדו'.
בכל המקרים הללו – במידה ואנחנו לא צריכים לתת תמיכה מלאה לדפדפן IE – שוב עדיף להשתמש בתגית img עם ההגדרה object-fit ולא בbackground-image, כי לתגית img אפשר לתת את ההגדרות alt + title לצורך סריקה פשוטה של מנועי חיפוש.
שימו לב שבמקרה של למשל באנר, שיש עליו רכיבים נוספים מלבד תמונת הרקע, לדוגמה כותרת העמוד וכדו' – יש להגדיר את התמונה עם הגדרת הcss של position: absolute, כדי שלא תפריע לשאר האלמנטים. זה אמור להיות כך שלdiv שעוטף את הבאנר יש גובה (בפיקסלים למשל), וכן יש לו position: relative, בתוכו יש תגית img, עם ההגדרות הבאות:
position: absolute; top: 0; left: 0; width: 100%; height: 100%; z-index: -1;
את ההגדרה z-index אנחנו מגדירים כדי שהתמונה לא תעלה מעל התוכן שבתוך הבאנר. (רוצים לדעת למה היא עשויה לכסות את התוכן? קראו עוד על ההגדרה position).
אבל אם אין לנו ברירה ואנחנו כן צריכים לתמוך בדפדפן IE, או שמדובר בתמונות רקע שאינן חשובות מידי, או שסתם לא בא לנו להתברבר עם תמונה אבסולוטית וכו' – נעדיף להשתמש בהגדרה background-image. כמובן ניתן גם הגדרת גודל לפי הנדרש, בדרך כלל cover.
זוכרים שלתגית img יש לנו אפשרות להגדיר גובה אוטומטי, כך שהוא יגדל/יקטן ככל שהרוחב גדל/קטן? ההתנהגות הזו היא בלעדית רק לתגית img ולא קורית לאלמנט הdiv שלנו, זה עם תמונת הרקע. כדי לתת לאלמנט שלנו גובה אוטומטי ביחס לרוחב – נוכל להשתמש בpadding-top כפי שמוסבר בפוסט הזה.
בהצלחה רבה!