CSS Grid הביא איתו יחידת מידה גמישה בשם fr (קיצור של Fractional Unit). 1fr מייצג חלק אחד מתוך השטח הפנוי בתוך grid container.
מי שעבד עם אחוזים או px לרוחב עמודות, ירגיש בבית עם fr – רק שהיא מטפלת בשטח שנותר בצורה אוטומטית, בלי לחשב כלום ידנית.
פריטי הגריד בדוגמאות הבאות ממוקמים באמצעות התכונה grid areas:
.grid-wrap {
max-width: 100%;
margin: 3em auto;
display: grid;
grid-template-columns: 1fr 1fr 1fr 1fr;
grid-template-rows: 50px 150px 50px;
grid-template-areas: "head head2 . side" "main main2 . side" "footer footer footer footer";
}
כל אחת מארבע העמודות תופסת את אותו מקום בגריד.
שימו לב! הדוגמאות בפוסט זה מציגות את הגריד כפי שהוא יופיע באתרי RTL (כלומר באתרים בשפה העובדת מימין לשמאל כגון השפה העברית). באתרים באנגלית (LTR) הגריד יוצג הפוך.
דוגמאות לשימוש ב fr
הנה גריד דומה, אך עם ערכי fr שונים. שימו לב כיצד רוחב העמודות משתנה:
.grid-wrap {
/* ... */
grid-template-columns: 1fr 1fr 40px 20%;
grid-template-rows: 100px 200px 100px;
/* ... */
}בדוגמה האחרונה ה-sidebar תופס 2fr מהשטח. הרוחב שלו שווה לרוחב המשולב של העמודה הראשונה והשנייה.
.grid-wrap {
/* ... */
grid-template-columns: 1fr 1fr 40px 2fr;
grid-template-rows: 100px 200px 100px;
/* ... */
}fr לעומת אחוזים
במבט ראשון, fr ו-% נראים כמעט זהים. שלוש עמודות של 33.33% ייראו אותו דבר כמו 1fr 1fr 1fr – עד שמוסיפים gap.
אחוזים מחושבים לפי הרוחב הכולל של ה-container, בלי להתחשב ב-gaps. גריד עם 33.33% 33.33% 33.33% ו-gap של 20px מסתכם ב-100% מהרוחב ועוד 40px של gaps, וזה גורם לגלישה אופקית:
/* גולש - 99.99% + 40px של gaps > רוחב ה-container */
grid-template-columns: 33.33% 33.33% 33.33%;
gap: 20px;
/* עובד - fr מתחשב ב-gaps אוטומטית */
grid-template-columns: 1fr 1fr 1fr;
gap: 20px;עם fr הבעיה הזו לא קיימת. הדפדפן מחסיר קודם את ה-gaps, ורק אז מחלק את מה שנשאר בין ה-tracks. בלי גלישה, בלי חישובים.
זו הסיבה המרכזית להעדיף fr על % בגריד. לאחוזים עדיין יש מקום כשצריך שעמודה תשמור על פרופורציה מדויקת ללא קשר ל-gaps, אבל ברוב המקרים fr פשוט הבחירה הנכונה.
ערבוב יחידות (Mixed Units)
אפשר לערבב fr עם יחידות אחרות באותה הגדרה – אחוזים, ערכי px קבועים, או auto. הדפדפן מקצה קודם את הערכים הקבועים והאחוזיים, ואז מחלק את מה שנשאר בין עמודות ה-fr.
בואו נראה את זה צעד אחר צעד, על container ברוחב 800px עם grid-template-columns: 300px 10% 1fr 2fr:
- ערכים קבועים קודם: 300px נשמרים.
- אחוזים: 10% מתוך 800px = 80px.
- מה נשאר: 800 – 300 – 80 = 420px.
- חלוקה בין tracks של fr: 420px ÷ 3 fr סה"כ = 140px לכל fr. העמודה של
1frמקבלת 140px, והעמודה של2frמקבלת 280px.
אם יש gap, גם הוא מנוכה בשלב 3. למשל, עם gap: 20px ו-3 מרווחים בין 4 עמודות, נשארים עם 420 – 60 = 360px, כלומר 120px לכל fr.
main {
width: 800px;
display: grid;
grid-template-columns: 300px 10% 1fr 2fr;
/* Result: 300px 80px 140px 280px */
grid-template-rows: auto;
}fr לעומת auto
auto מתאים את העמודה לגודל התוכן שבה. fr לוקח את השטח שנותר, לא משנה מה יש בתוכו.
כשמשלבים את השניים, עמודות auto מחושבות קודם, ועמודות fr מתחלקות במה שנשאר:
grid-template-columns: auto 1fr auto;
/* sidebar | main גמיש | sidebar */תבנית נפוצה לעימוד דפים: ה-sidebar רחב כתוכן שלו, והאזור הראשי ממלא את כל השאר. עובד יפה גם עם תכונת aspect-ratio לכרטיסים שצריכים לשמור על פרופורציות.
fr עם repeat() ו-minmax()
היחידה fr משתלבת מצוין עם תבניות גריד רספונסיביות בלי media queries. שילוב של repeat() עם minmax() יוצר גריד שעוטף פריטים לשורה הבאה לבד:
grid-template-columns: repeat(auto-fill, minmax(250px, 1fr));כל עמודה רחבה לפחות 250px. כשנשאר מקום, 1fr מחלק אותו שווה בשווה. ככל שה-viewport מצטמצם, עמודות יורדות לשורה חדשה במקום להידחס מתחת ל-250px.
ההבדל בין
auto-fillל-auto-fit:auto-fillשומר על tracks ריקים כשיש מקום פנוי, בעודauto-fitמקפל אותם כך שהפריטים הקיימים נמתחים למלא את השורה.
מלכודות נפוצות
כמה דברים שנוטים לבלבל מפתחים שעובדים עם fr בפעם הראשונה:
1. fr לא עובד מחוץ ל-Grid
בניגוד ל-% או px, היחידה fr עובדת רק בתוך grid-template-columns ו-grid-template-rows. לשים אותה ב-width, margin או Flexbox? הדפדפן פשוט יתעלם.
2. גלישה עם תוכן גדול
עמודת fr עלולה לגדול מעבר לחלק שמגיע לה אם התוכן לא נכנס. הפתרון – להשתמש ב-minmax(0, 1fr) במקום 1fr:
/* ברירת מחדל: fr משתמש בגודל התוכן כמינימום */
grid-template-columns: 1fr 1fr;
/* כפיית מינימום 0 - התוכן יגלוש במקום להרחיב */
grid-template-columns: minmax(0, 1fr) minmax(0, 1fr);3. fr לא עובד בתוך calc()
היחידה fr היא מסוג נתונים <flex>, לא <length> כמו px או %. מה שאומר ש-calc(1fr - 20px) הוא CSS לא תקין, והדפדפן יתעלם ממנו. צריכים גודל מינימלי עם גדילה גמישה? תשתמשו ב-minmax(): minmax(200px, 1fr).
4. gaps נספרים לפני fr
התכונה gap מנוכה מהשטח הפנוי לפני חישוב ערכי fr. גריד עם 3 עמודות 1fr 1fr 1fr ו-gap של 20px נותן לכל עמודה (total - 40px) / 3, ולא total / 3.
שאלות נפוצות
1fr ב-CSS Grid?
1fr מייצג חלק אחד מתוך השטח הפנוי ב-grid container. אם מגדירים grid-template-columns: 1fr 1fr 1fr, רוחב ה-container (פחות gaps) מתחלק לשלוש עמודות שוות.fr לאחוזים ב-CSS Grid?
fr מחלקת את השטח שנותר לאחר שגדלים קבועים, אחוזים ו-gaps מנוכים. זה הופך את fr לבטוחה יותר בגריד עם gaps כי היא לא תגרום לגלישה.fr מחוץ ל-CSS Grid?
fr עובדת רק בתוך grid-template-columns ו-grid-template-rows. אין לה השפעה ב-Flexbox, width, margin או כל תכונת CSS אחרת.fr ל-auto ב-CSS Grid?
auto מגדיר track לפי גודל התוכן שלו. fr מחלק את השטח שנותר ללא קשר לתוכן. כשמשלבים אותם, tracks של auto מחושבים קודם, ואז tracks של fr מתחלקים במה שנשאר.fr שלי רחבה מהצפוי?
fr הוא auto, כלומר תוכן יכול לדחוף את העמודה להיות רחבה מהחלק היחסי שלה. כדי לפתור זאת, השתמשו ב-minmax(0, 1fr) במקום 1fr כך שהעמודה תוכל להתכווץ מתחת לגודל התוכן.gap משפיעה על ערכי fr?
fr. לדוגמה, container ברוחב 900px עם gap: 30px ו-1fr 1fr 1fr נותן לכל עמודה 280px, לא 300px, כי שני gaps של 30px סה"כ 60px.fr היא מסוג <flex>, לא <length>. כתיבת calc(1fr - 20px) היא CSS לא תקין והדפדפן יתעלם ממנו. אם צריכים עמודה גמישה עם גודל מינימלי, השתמשו ב-minmax(20px, 1fr) במקום.1fr הוא חלק יחסי מהשטח שנותר לאחר ניכוי גדלים קבועים, אחוזים ו-gaps. ב-container ברוחב 900px עם עמודה אחת של 300px ושתי עמודות 1fr, כל 1fr שווה 300px. שינוי רוחב ה-container או העמודה הקבועה ישנה את ערך הפיקסלים.סיכום
אני משתמש ב-fr כמעט בכל גריד שאני בונה. לא צריך לחשב אחוזים, והכל מתאים את עצמו כשמוסיפים או מורידים עמודות. בשילוב עם px, auto ו-minmax() אפשר לכסות את רוב צרכי העימוד בלי media query בודד.

