תמונות רספונסיביות

משך זמן קריאה: 10 דקות

כן, נשמע קצת פוסט מ-2015. כבר שמענו המון עליהם, תכלס – אנחנו לא עושים איתם כלום. אולי "אנחנו" זה קצת מוגזם, אז אני אסתפק באולי "רובנו" לא באמת משתמשים בהם מספיק. אז למה פתאום זה עלה? באחד הניוזים שאני מנויה עליהם היה לינק להרצאה של Jason Grigsby על תמונות רספונסיביות. Jason Grigsby הוא חלק מהצוות של W3C שקובע את התקן של HTML בנושא של תמונות רספונסיביות. מה שהוא הסביר בהרצאה היה השיקולים, התהליך והשורה התחתונה של יישום תמונות רספונסיביות ב-HTML5 ולכן ההרצאה שלו חשובה מאוד להבנה שלנו. גם מבחינתו ההרצאה חשובה, כדי לעזור להטמיע את היישום של תמונות רספונסיביות אצל מתכנתי אינטרנט.

רצה המקרה, והתפנתה לי שעה. צפיתי בהרצאה ואני חייבת לומר שיצאתי נפעמת ועם מושג קצת יותר חזק של כל העניין. אין לי כוונה לתרגם את ההרצאה שלו אבל כן להביא את עיקרי הדברים שהבנתי ממנה. לאלו מכם משעדיפים קריאה על פני צפייה, יש גם אתר עם כל הפרטים שמופיעים בהרצאה.

Jason Grigsby מחלק את ההתיחסות לתמונות רספונסיביות ל-2 אספקטים:

הראשון הוא ההתאמה של התמונה לגודל הדפדפן. כלומר – אני רוצה לשמור על אותה פרופורציה של תמונה, אבל עם הירידה בגודל המסך אין לי צורך לטעון תמונה כל כך רחבה ולכן אעדיף לטעון תמונה מוקטנת באותה פרופורציה. עבור השימוש הזה נשתמש במאפיינים srcset ו-sizes.

השני הוא תמונות בפרופורציות שונות תוצגנה ברזולוציות שונות (Jason Grigsby מתייחס לזה בתור Art-Directing). כדי להחיל את השינויים האלה נשתמש בתגית <picture>. אפשר לראות דוגמה טובה לשימוש בתגית כאן, ניתן לראות שינוי תמונה לפי גודל הדפדפן (מומלץ להגדיל ולהקטין כדי לראות תוצאות).

לשני המאפיינים האלה יש תמיכה לא רעה של דפדפנים, אבל עדיין לא כולם (בעייתי אקספלורר, וגרסאות ישנות אשל אנדרואיד) ולכן חשוב לתת fallback.

אלה עיקרי הדברים לגבי האספקט הראשון:

scrset

כדי להתחיל להבין מה הכוונה לשימוש ב-scrset נתחיל עם דוגמה של טעינת 2 תמונות:  למסכים רגילים ולמסכי רטינה. באופן הזה נטענות שתי תמונות, הראשונה ללא ציון גודל והשניה עם הגדרת התמונה כ-2X (לא זה שמופיע בשם התמונה אלא זה שמגיע מיד לאחריו), שאותה יודע מכשיר עם מסך רטינה למשוך. לדוגמה:

<img src="cat.jpg" alt="cat" srcset="cat.jpg, cat-2X.jpg 2x">

אם נרחיב את השימוש, אפשר בעצם להביא כמות גדולה יותר של תמונות בגדלים שונים. כמו בדוגמה של Jason Grigsby:

<img src="cat.jpg" alt="cat" 
     srcset="cat-160.jpg 160w, cat-320.jpg 320w, cat-640.jpg 640w, cat-1280.jpg 1280w">

cat-160.jpg הוא שם התמונה ואילו 160w הוא הרוחב פיסי של התמונה. במקום ערך של 2X שמייצג את "עומק" המסך (density) יש לנו ציון של רוחב התמונה. בשימוש של scrset אנחנו מספקים לדפדפן רשימה של תמונות עם ציון הרוחב שלהן, ומצפים שהדפדפן ידע לבחור את התמונה המתאימה ביותר עבור נראוּת האתר ומהירות הטעינה. לדוגמה: ברזולוציית מסך של 1600px התמונה צריכה להיות ברוחב של 300px, ולכן אנחנו רוצים שהדפדפן יטען את התמונה cat-320. נשמע נהדר, לא? הבעיה היא שבזמן טעינת העמוד, הדפדפן יודע רק מה הרוחב שלו – הוא לא יודע עדיין מה צריך להיות גודל התמונה בעמוד. גודל התמונה נקבע ב-media queries בקובץ ה-css. הבעיה היא שעד שהדפדפן טוען את ה-css, קורא אותו, ומגיע ליישם אותו, הוא כבר התחיל להוריד תמונות – תמונות שהוא לא בטוח יצטרך ואז בעצם, לא שיפרנו את זמן הטעינה של העמוד.

ולכן – כדי להשלים את scrset יש לנו את:

sizes

המאפיין sizes ממפה את הקשר בין הגודל הרצוי של התמונה באתר לבין גודל המסך (view port).

sizes = "(max-width: 480px) 100vw,
        (max-width: 900px) 33vw,
        254px;

במאפיין sizes אנחנו מגדירים זוגות של הגדרות, ולבסוף ערך ברירת מחדל. בכל זוג, החלק הראשון הוא מעין 'סב-מדיה קוורי' (בדוגמה: max-width: 480px) שמייצג את הרוחב המקסימאלי של הדפדפן, והחלק השני (בדוגמה: 100vw) הוא הגודל של התמונה ביחס לרוחב הדפדפן כפי שהוחלט בעיצוב, הפרמטר האחרון (בדוגמה: 254px) הוא מעין fallback למקרה שאין תמיכה בפרמטרים האחרים. למשל בדוגמה בקוד – עד רזולוציה של 480px התמונה שתבוא תוצג ב 100% של רוחב המסך. מרזולוציה של 480px ועד 900px התמונה תוצג בגודל של 33vw שזה 33% אחוז מרוחב המסך.

בשילוב של שני המאפיינים scrset ו-sizes אנחנו מאפשרים לדפדפן לדעת מה צריך להיות גודל התמונה ברזולוציות השונות. Jason Grigsby מביא פה דוגמה מצויינת. ושוב – אביא את עיקרי הדברים:

<img src="cat.jpg" alt="cat"
  srcset="cat-160.jpg 160w, cat-320.jpg 320w, cat-640.jpg 640w, cat-1280.jpg 1280w"
  sizes="(max-width: 480px) 100vw, (max-width: 960px) 33vw, 254px">

לדוגמה: ברזולוצייה של 960px אנחנו יודעים שרוחב התמונה יהיה 33vw, כלומר  – רוחב התמונה יהיה 316px. והתמונה שתיטען תהייה cat-320.jpg.

האם כל העבודה הזאת משתלמת? מסתבר שכן. אחרי הטמעה ושימוש במאפיינים האלו בכרום דיווחו על שיפור של 20% מהירות בזמן טעינת הדפים, ובפיירפוקס שיפור של 19% – מספרים לא רעים בכלל המשפרים את חווית הגלישה של המשתמשים.

Jason Grigsby מדבר בהרצאה שלו על איך מחשבים כמה גדלים של תמונות צריך. למי שמתעניין, אפשר לראות בהרצאה דוגמה והסברים (החל מדקה 38), או לקרוא על זה פה. אפשר גם לקרוא, כהעשרה, בפוסט מורחב של smashing magazine בנושא נקודות שבירה לתמונות. ופוסט אחרון חביב של כריס קויר על שמירת תמונות לרזולוציות שונות.

מקורות נוספים לקריאה על תמונות רספונסיביות: Leaner Responsive Images With Client Hints וגם: Responsive Images in Practice.

 

תמונות רספונסיביות בוורדפרס

תמונה ראשיתאחרי שצפיתי בהרצאה רתמתי את לאה שתעזור לי להבין מה קורה בוורדפרס וכך יצא – שאת הפוסט המשכנו לכתוב יחד 🙂
החל מגרסת וורדפרס 4.4 תמוונת רספונסיביות נכללות ב-core של וורדפרס (למי שעדיין לא שידרג לוורדפרס 4.4 יש את התוסף RICG Responsive Images). יחד עם התוספת הזאת באו פילטרים המאפשרים למפתח האתר להגדיר את הגדלים שהוא צריך ספציפית לאתר שלו.

כדי להתאים את ערכי בברירת המחדל לתמונות בתוך פוסטים ניתן להשתמש ב:

בתמונות מלוות  (למשל תמונה ראשית – ראו תמונה) או גלריות, אפשר להשתמש בפילטר: wp_get_attachment_image_attributes.

אחד מחברי הצוות שפיתחו את הפיצ'ר הזה כתב מאמר בסמשינג מגזין שמסביר על הפיצ'ר ועל השימוש בפילטרים. בפוסט מובאת דוגמה ממשית לשימוש בפילטרים – הוא מציג את מה שנעשה בתבנית twentysixteen, עם הסברים על איך להפריד את הטיפול בתמונות בתוך פוסטים מטיפול בתמונות מלוות.

 

החלטנו (יותר נכון אני החלטתי ולאה זרמה איתי…) שחייבים ללכלך את הידיים ולהתנסות כי רק ככה באמת לומדים 🙂 . אחד האתרים האחרונים שעבדנו עליו היה סיינטיפיק ישראל ששם יש כמות לא קטנה של תמונות, אז החלטנו להפוך את האתר בשרת פיתוח לאתר ההתנסות שלנו ב sizes + scrset.

שידרגנו גרסת וורדפרס וראינו שהתמונות אכן מקבלות את הערכים של sizes ו-scrset אבל אלו לא היו הערכים שרצינו שיהיו. מהיכן הם הגיעו? מסתבר שהערכים הדיפולטיביים של sizes הם הערכים שמוגדים בהגדרות המדיה של התבנית. אבל! כן, יש אבל גדול – הערכים האלה נלקחים בחשבון רק אם היחס בין הגדלים הוא יחס שווה כמו לדוגמה:

 

proportion-for-responsive-image

 

בעצם וורדפרס בוחרת תמונה באופן דיפולטיבי מתוך מכל גדלי התמונות שיש לתמונת המקור (הגדלים שהוגדרו בתבנית והגדלים שהוגדרו במדיה) אבל רק את אלו שנחתכו באותה פרופורציה, ומביאה אותן בהתאמה לרוחב המסך. למשל, נניח שהתמונה הגדולה שלנו היא בפרופורציה של 750*1024, אז במצב של מכשיר נייד, אין צורך לקבל תמונה כל כך גדולה ווורדפרס תציג את התמונה הקטנה יותר, נניח 512*700. וורדפרס מעידים כי זה איננו הפתרון האידיאלי, אבל כברירת מחדל שעובדת זה הפתרון הקיים כרגע. וורדפרס מאפשרים ומעודדים את מי שמפתח את התבנית להכניס בקוד פילטרים להגדרת הגדלים שהיה רוצה למשוך לפי רוחב המסך (שני הפילטרים שהזכרנו קודם).

באתר שבו בצענו את החקירה, כבר היו גדלים שמוגדרים ב-functions.php המשמשים כתמונות מלוות (לכל סוג קטגוריה יש גודל תמונה שונה), ויש גדלים שמוגדרים במדיה.

אלה הגדלים מהתבנית – נועדות לתמונות מלוות:

add_image_size( 'scientific-2016-full_width', 1600, 585, true );
            add_image_size( 'scientific-2016-full_width_half', 800, 292.5, true );
            add_image_size( 'scientific-2016-articles_size', 390, 390, true );
            add_image_size( 'scientific-2016-fast_science_size', 216, 216, true );
            add_image_size( 'scientific-2016-opinions_size', 388, 255, true );

ואלה הגדלים שהוגדרו במדיה, ונועדו לתמונות שמועלות בתוך הפוסטים:

הגדרת גודל תמונה דרך מדיה

 

כעת, כדי להשתמש בפונקציונליות החדשה, הגדרנו בתבנית (ב-functions.php) פונקציה שתשב על הפילטר wp_calculate_image_sizes  ותגדיר את הערכים עבור גודל התמונות שנרצה שהדפדפן יטען בכל רזולוציה:

function scientific_2016_adjust_image_sizes_attr( $sizes, $size ){
                $sizes = '(max-width: 768px) 100vw, (max-width: 1020px) 100vw,  1024px';
                return $sizes;
            }

            add_filter( 'wp_calculate_image_sizes', 'scientific_2016_adjust_image_sizes_attr', 10, 2 );

וזה בעצם מה שכתוב בקוד: בתוך פוסט, עד רזולוציה של 768px התמונה תוצג ברוחב מלא של המסך, ווורדפרס יודעים לעשות את הקסם (בזכות התוספת החל מגרסה 4.4) ולהביא תמונה קלה יותר, כלומר – ברזולוציה של 320px נקבל את התמונה הקטנה (שהוגדרה להיות 390 פיקסלים, בהגדרות המדיה לעיל), אבל ברזולוציה של 700px למשל – היות והתמונה צריכה להיות ברוחב של 100vw שזה אומר 700px – התמונה הגדולה תמשך (זאת שהיא 1024 פיקסלים). לכאורה אפשר היה לצפות שהבינונית תמשך אבל לא – וורדפרס ימשכו את התמונה הגדולה יותר כדי לא לגרום לירידה באיכות התמונה. הניסוי הזה הדגיש את המורכבות של בחירת מספר הגדלים של התמונות וכמה "נקודות שבירה" יש לתת.

שימוש נוסף שרצינו לעשות בעזרת הפילטר הוא הצגת תמונה שונה ברזולוציות שונות אבל בלי לשמור על פרופורציה (שזו האפשרות השנייה שגריגסבי התייחס אליה, וקרא לה Art-Directing כפי שכתבתי בתחילת הפוסט). מלכתחילה – חשבתי שפה זה המקרה לשימוש בתגית <picture> אבל זה לא חלק מהשידרוג של תמונות רספונסיביות בוורדפרס. אז בחיפוש אחרי דוגמאות לשימוש בפילטרים שפירטנו למעלה נתקלתי בפוסט שמדגים פתרון לבעיה שלנו :).

באתר סיינטיפיק יש לנו לכל פוסט תמונת header גדולה שנפרסת לכל רוחב העמוד. במובייל, לא רצינו כיווץ של התמונה באופן פרופורציוני, אלא חיתוך שלה. בזמן תכנות האתר, הידע שלנו בתמונות רספונסיביות לא היה מספק ומפאת קוצר זמן הפתרון שלי היה שימוש ב object-fit כדי לדמות מצב של cover ל-img. השתמשתי בדוגמה ובהסבר המצויין של css-tricks. ומה טוב מראה עיניים מהסבר:

תמונת heade ברזלוציותהשונות

והקוד (שכתבנו אז, ולא משתמש בתמונות רספונסיביות):

/*in mobile - up to 599px*/
.single .entry-header img{
        width: 100vw;
        height: 50vh;
        object-fit: cover;
        overflow: hidden; // *Cuts off the parts of the image poking out*/
}
/*from 600px and up*/
.single .entry-header img{
       display: block;
       width: 100%;
       height: auto;
}

החסרון כמובן הוא שאנחנו טוענים תמונה מאוד גדולה וכבדה כשאין לה צורך, אבל כאמור – חוסר הידע והזמן הכריעו.

עכשיו, עם השינויי בוורדפרס, ניתן ליישם את העיצוב של תמונת ה-header בדרך נכונה יותר וקלה יותר (קלה מבחינת משקל העמוד). הוספנו לקובץ functions.php את הפונקציה של Misha  Rudrastyh:

function scientific_2016_sources( $sources, $size_array, $image_src, $image_meta, $attachment_id ){
 // this should only apply to the 1600 pixels wide images
 if ( $image_meta['width'] == 1600 ) {

    $mobile_image = 'scientific-2016-articles_size';
    $breakpoint = 599;

    $upload_dir = wp_upload_dir();

    $img_url = $upload_dir['baseurl'] . '/' . str_replace( basename( $image_meta['file'] ), $image_meta['sizes'][$mobile_image]['file'], $image_meta['file'] );

    $sources[$breakpoint] = array(
     'url' => $img_url,
     'descriptor' => 'w',
     'value' => $breakpoint,
    );
 }
 return $sources;
}

add_filter( 'wp_calculate_image_srcset', 'scientific_2016_sources', 10, 5 );

את השינוי הזה רצינו להחיל רק על תמונת ה-header שלנו. לשמחתנו, הפונקציה מקבלת מידע שמאפשר לה להציב תנאי לפי רוחב בפרמטר הרביעי – $image_meta, וכך, מיד בתחילת הפונקציה מוסיפים את התנאי:

if ( $image_meta['width'] == 1600 )

ו- פפאפם! יש לנו תמונה קלה יותר במובייל 🙂

נקודה אחרונה בנושא הזה: אצלנו באתר, לכל פוסט הייתה תמונה ראשית (קטנה בגודל של 390*390) ועוד תמונה מלווה – תמונה header. את תמונת ה-header מעלים דרך שדה מיוחד. מה שאומר שיצרנו תגית img בצורה עצמאית. במקרה כזה, יש צורך להוסיף את מאפייני ה-srcset וה-sizes בצורה ידנית ע"י קריאה ל-wp_get_attachment_image_srcset() ול-wp_get_attachment_image_sizes()והשמת תוצאה של כל קריאה במאפיין המתאים לו בתגית. לשתיהן צריך לספק attachment_id בלבד.

עריכה (27.02.2017): ב smashing magazine יש מאמר מעניין מאוד על פתרונות של "ארט דיירקטינג" לתמונות רספונסיביות. שווה קריאה 🙂

ההתנסות הזאת בהוספת המאפיינים scrset ו-sizes הייתה מאוד חשובה בעייני. כשצפיתי בהרצאה, לא חשבתי שהחלק של חישוב גודל וכמות התמונות חשוב כל כך, אבל עכשיו אחרי הנסיון שלנו אני יודעת שזה מאוד חשוב ומאוד לא פשוט. כמו שאומר Jason Grigsby בתחלת ההרצאה שלו, כולם יודעים כמה תמונות רספונסיביות חשובות אבל איכשהו זה לא נכנס לעבודה. אז מבחינתי מעכשיו זה לגמרי בעבודה ויהיה חשוב לי ליישם את זה בפרויקט וורדפרס הבא שלי.

כמו שכתבתי איפשהו באמצע הדרך, את הפוסט הזה כתבנו במשותף לאה ואני, אם תרצו לקרוא בהרחבה על כל התהליך של הטמעת תמונות רספונסיביות ב-core של וורדפרס תוכלו לקרוא בבלוג של לאה.

עריכה (08.03.2017): כלי נחמד שמנתח את התמונות בעמוד ואומר אם יש מה לשפר בהן.

עריכה (29.03.2018): שימוש לא קונבנציונאלי ב sizes – חילוף תמונה כדי להציג תמונה מוגדלת.

MAY RESPONSIVE IMAGES BE WITH YOU

  2 תגובות ל “תמונות רספונסיביות

  1. 20 במרץ 2018 at 23:28

    יפה מאד רחל! מאד עוזר….. המשיכי לכתוב מאמרים מעניינים 🙂

    • rachelbt
      21 במרץ 2018 at 8:34

      תודה רבה!
      כנ"ל 🙂

כתיבת תגובה

האימייל לא יוצג באתר. שדות החובה מסומנים *