מאפיין יחס הגובה-רוחב של שירות CSS

מאפיין CSS שעוזר לשמור על הריווח בפריסות רספונסיביות.

יחס גובה-רוחב

Browser Support

  • Chrome: 88.
  • Edge: 88.
  • Firefox: 89.
  • Safari: 15.

Source

יחס הגובה-רוחב מבוטא בדרך כלל כשני מספרים שלמים ונקודתיים בממדים של: רוחב:גובה, או x:y. יחסי הגובה-רוחב הנפוצים ביותר בצילום הם 4:3 ו-3:2, בעוד שבסרטונים ובמצלמות צרכניות חדשות יותר, יחס הגובה-רוחב הוא בדרך כלל 16:9.

שתי תמונות עם אותו יחס גובה-רוחב. אחת בגודל ‎634 x 951px והשנייה בגודל ‎200 x 300px. לשניהם יש יחס גובה-רוחב של 2:3.
שתי תמונות עם אותו יחס גובה-רוחב. אחת בגודל ‎634 x 951px והשנייה בגודל ‎200 x 300px. לשניהם יש יחס גובה-רוחב של 2:3.

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

הנה כמה דוגמאות למקרים שבהם חשוב לשמור על יחס הגובה-רוחב:

  • יצירת iframe רספונסיבי, שבו הרוחב הוא 100% מהרוחב של רכיב האב, והגובה צריך להיות יחס מסוים של אזור התצוגה
  • יצירת קונטיינרים של פלייסהולדרים פנימיים לתמונות, סרטונים ותוכן מוטמע כדי למנוע פריסה מחדש כשהפריטים נטענים ותופסים מקום
  • יצירת מרחב אחיד ורספונסיבי להמחשות אינטראקטיביות של נתונים או לאנימציות SVG
  • יצירת מקום אחיד ורספונסיבי לרכיבים מרובי-אלמנטים כמו כרטיסים או תאריכים ביומן
  • יצירת מקום אחיד ורספונסיבי לכמה תמונות בגדלים שונים (אפשר להשתמש בו לצד object-fit)

Object-fit

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

המחשה של מאפיין object-fit
הצגת ערכים שונים של object-fit. לצפייה בהדגמה ב-Codepen

הערכים initial ו-fill משנים את גודל התמונה כך שתמלא את השטח. בדוגמה שלנו, התמונה נדחסת ומטושטשת כי הפיקסלים מותאמים מחדש. זה לא אידיאלי. ‫object-fit: cover משתמש במימד הקטן ביותר של התמונה כדי למלא את השטח, וחתוך את התמונה כך שתתאים לו על סמך המימד הזה. הוא מתרחב בגבול התחתון שלו. ‫object-fit: contain מוודא שכל התמונה תמיד גלויה, ולכן הוא ההפך מ-cover, שבו התמונה מקבלת את הגודל של הגבול הגדול ביותר (בדוגמה שלמעלה זה הרוחב), והגודל שלה משתנה כדי לשמור על יחס הגובה-רוחב המקורי שלה, תוך התאמה למקום. בדוגמה object-fit: none התמונה נחתכת במרכז שלה (מיקום ברירת המחדל של האובייקט) בגודל הטבעי שלה.

object-fit: cover בדרך כלל עובד ברוב המקרים כדי להבטיח ממשק אחיד ונעים כשעובדים עם תמונות בגדלים שונים, אבל בשיטה הזו מאבדים מידע (התמונה נחתכת בקצוות הארוכים שלה).

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

השיטה הישנה: שמירה על יחס גובה-רוחב באמצעות padding-top

שימוש ב-padding-top כדי להגדיר יחס גובה-רוחב של 1:1 בתמונות של תצוגה מקדימה של פוסטים בקרוסלה.
שימוש ב-padding-top כדי להגדיר יחס גובה-רוחב של 1:1 בתמונות בתצוגה מקדימה של פוסט בקרוסלה.

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

פתרון מקובל כיום לשימור יחס הגובה-רוחב על סמך הרוחב של תמונה, שפועל בכל הדפדפנים, נקרא Padding-Top Hack. הפתרון הזה דורש קונטיינר אב וקונטיינר צאצא עם מיקום מוחלט. אחר כך מחשבים את יחס הגובה-רוחב באחוזים כדי להגדיר אותו כ-padding-top. לדוגמה:

  • יחס גובה-רוחב של 1:1 = 1 / 1 = 1 = padding-top: 100%
  • יחס גובה-רוחב 4:3 = 3 / 4 = 0.75 = padding-top: 75%
  • יחס גובה-רוחב 3:2 = 2 / 3 = 0.66666 = padding-top: 66.67%
  • יחס גובה-רוחב של 16:9 = 9 / 16 = 0.5625 = padding-top: 56.25%

אחרי שזיהינו את ערך יחס הגובה-רוחב, אנחנו יכולים להחיל אותו על מאגר האב. דוגמה:

<div class="container">
  <img class="media" src="..." alt="...">
</div>

אפשר לכתוב את ה-CSS הבא:

.container {
  position: relative;
  width: 100%;
  padding-top: 56.25%; /* 16:9 Aspect Ratio */
}

.media {
  position: absolute;
  top: 0;
}

שמירה על יחס גובה-רוחב עם aspect-ratio

שימוש ביחס גובה-רוחב כדי להגדיר יחס גובה-רוחב של 1:1 בתמונות של תצוגה מקדימה של פוסט בקרוסלה.
שימוש ב-aspect-ratio כדי להגדיר יחס גובה-רוחב של 1:1 בתמונות בתצוגה מקדימה של פוסט בקרוסלה.

לצערנו, החישוב של ערכי padding-top האלה לא מאוד אינטואיטיבי, ונדרשים בו תקורה ומיקום נוספים. עם aspect-ratio מאפיין ה-CSS החדש aspect-ratio, השפה לשמירה על יחסי גובה-רוחב הרבה יותר ברורה.

באמצעות אותו תג עיצוב, אפשר להחליף את padding-top: 56.25% ב-aspect-ratio: 16 / 9, ולהגדיר את aspect-ratio ליחס שצוין של width / height.

שימוש ב-padding-top
.container {
  width: 100%;
  padding-top: 56.25%;
}
שימוש ביחס גובה-רוחב
.container {
  width: 100%;
  aspect-ratio: 16 / 9;
}

השימוש ב-aspect-ratio במקום ב-padding-top הרבה יותר ברור, ולא משנה את מאפיין הריווח כדי לבצע פעולה מחוץ להיקף הרגיל שלו.

המאפיין החדש הזה מאפשר גם להגדיר את יחס הגובה-רוחב ל-auto, כאשר "רכיבים שהוחלפו עם יחס גובה-רוחב פנימי משתמשים ביחס הגובה-רוחב הזה; אחרת, לתיבה אין יחס גובה-רוחב מועדף". אם מציינים גם את auto וגם את <ratio>, יחס הגובה-רוחב המועדף הוא היחס שצוין של width חלקי height, אלא אם מדובר ברכיב שהוחלף עם יחס גובה-רוחב פנימי, ובמקרה כזה נעשה שימוש ביחס הגובה-רוחב הזה.

דוגמה: עקביות ברשת

השיטה הזו עובדת טוב מאוד גם עם מנגנוני פריסה של CSS כמו CSS Grid ו-Flexbox. נניח שיש לכם רשימה עם רכיבי צאצא שאתם רוצים לשמור על יחס גובה-רוחב של 1:1, כמו רשת של סמלי ספונסרים:

<ul class="sponsor-grid">
  <li class="sponsor">
    <img src="..." alt="..."/>
  </li>
  <li class="sponsor">
    <img src="..." alt="..."/>
  </li>
</ul>
.sponsor-grid {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(120px, 1fr));
}

.sponsor img {
  aspect-ratio: 1 / 1;
  width: 100%;
  object-fit: contain;
}
תמונות ברשת עם רכיב האב שלהן במידות שונות של יחס גובה-רוחב. לצפייה בהדגמה ב-Codepen

דוגמה: מניעת שינוי פריסה

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

סרטון שמציג שינוי פריסה מצטבר שמתרחש כשלא מוגדר יחס גובה-רוחב בנכס שנטען. הסרטון הזה מוקלט באמצעות רשת 3G מדומה.

לעומת זאת, שימוש ב-aspect-ratio יוצר placeholder כדי למנוע את שינוי הפריסה הזה:

img {
  width: 100%;
  aspect-ratio: 8 / 6;
}
סרטון עם יחס גובה-רוחב מוגדר מוגדר בנכס שנטען. הסרטון הזה מוקלט באמצעות רשת 3G מדומה. לצפייה בהדגמה ב-Codepen

טיפ בונוס: מאפייני תמונה ליחס גובה-רוחב

דרך נוספת להגדיר את יחס הגובה-רוחב של תמונה היא באמצעות מאפייני תמונה. אם אתם יודעים מראש את המידות של התמונה, מומלץ להגדיר את המידות האלה כ-width ו-height שלה.

בדוגמה שלמעלה, המידות הן 800x600 פיקסלים, ולכן תגי ה-markup של התמונה ייראו כך: <img src="image.jpg" alt="..." width="800" height="600">. אם התמונה שנשלחה היא באותו יחס גובה-רוחב, אבל לא בהכרח עם אותם ערכי פיקסלים מדויקים, עדיין נוכל להשתמש בערכי מאפייני התמונה כדי להגדיר את היחס, בשילוב עם סגנון של width: 100%, כדי שהתמונה תתפוס את המקום המתאים. הקוד המלא ייראה כך:

<!-- Markup -->
<img src="image.jpg" alt="..." width="8" height="6">
/* CSS */
img {
  width: 100%;
  height: auto;
}

בסופו של דבר, האפקט זהה להגדרת aspect-ratio בתמונה באמצעות CSS, ונמנעת תזוזת פריסה מצטברת (ראו הדגמה ב-Codepen).

סיכום

עם מאפיין ה-CSS החדש, aspect-ratio, שמופעל בכמה דפדפנים מודרניים, קל יותר לשמור על יחסי גובה-רוחב נכונים במדיה ובקונטיינרים של הפריסה.

תמונות מאת Amy Shamblen ו-Lionel Gustave דרך Unsplash.