תוכן עניינים
בגרסה 3 של CSS נוספו מצבי פריסה נוספים שנועדו לתת מענה טוב יותר לבעיות איתן מתמודדים מקודדים כיום: ריבוי רזולוציות, שינוי אוריינטציית מסך והגדרות ברירת מחדל משתנות לפי דפדפן.
נכון להיום, Flexible Box Layout, או בשמו המקוצר Flexbox – הוא מצב הפריסה הקרוב ביותר ליישום (כרגע מוגדר כטיוטה לפני פרסום), ונתמך במרבית הדפדפנים (נתוני תמיכה ניתן למצוא בסוף המדריך).
בגרסה 2.1 של CSS היו קיימים ארבעה מצבי פריסה שונים, כולם תחת הכותרת Box Model:
- פריסת בלוקים (Block Layout) – מיועדת עבור פריסת אלמנטים במסמך HTML
- פריסה פנימית (Inline Layout) – מיועדת עבור פריסת טקסט
- פריסה טבלאית (Table Layout) – מיועדת עבור פריסת מידע דו מימדית בתבנית טבלה
- פריסה לפי-מיקום (Positioned Layout) – מיועדת עבור מיקום מפורש של אלמנט מסויים, ללא התחשבות באלמנטים אחרים
את מצב הפריסה ניתן להגדיר לכל אלמנט באמצעות הגדרת css:
1 2 3 4 5 6 |
.element { display: block | inline | inline-block | table; position: static | relative | absolute | fixed; } |
כל מצבי הפריסה הללו, למרות שאינם מושלמים, נותנים פתרון טוב כשמדובר באתר אינטרנט לדסקטופ. עם שימוש נכון – הם אפילו נותנים פתרון לא רע לבניית אתרים ריספונסיביים (כפי שקורה היום).
עם זאת, היום CSS וHTML משמשים ליותר מבניית אתרים – הם נמצאים באפליקציות ווב, אפליקציות לסמארטפון, משחקים ועוד. לכן – נוצר צורך במצב פריסה שיתן מענה יעיל למציאות של היום.
Flexible Box Layout: הגדרה
Flexible Box הוא מודל CSS שמציע הגדרות באמצעותן ניתן לקבוע כיצד אלמנט יתנהג כאשר מתרחש שינוי במאפייני התצוגה.
המטרה מאחורי המודל היא לתת לאלמנט המכיל יכולת לשנות את תכונות בניו (רוחב, גובה, סדר ועוד) על מנת שינצלו בצורה המיטבית את השטח הזמין.
Flexbox מול Grid: מה ההבדל?
חשוב לציין שקיים מודל חדש בשם CSS Grid Layout, או בשמו המקוצר Grid, שמטרת העל שלו היא לתת למקודד כלים ליצירת מבנה עיצובי באמצעות הגדרת גרידים. אם לשים את האצבע על ההבדל העיקרי בין CSS Grid Layout ל – Flexible Box Layout, אפשר להגיד שהראשון שימושו העיקרי הוא בסידור האלמנטים ה"ראשיים" (Header, תפריט הניווט, האלמנט המכיל את תוכן האתר, Footer וכו'), ולעומת זאת השימוש העיקרי ב – Flexbox הוא בפריסת הרכיבים בתוך ה"אלמנטים הראשיים" (וגם בתוך כל אלמנט).
המודל (Grid) לא נתמך באופן רחב ברוב הדפדפנים נכון לכתיבת מדריך זה (ב – Chrome, Firefox ו – Safari ניתן "להפעיל" את המודל לצורך בדיקות), ולכן כיום ניתן לבחור להישאר עם ה – Box Model, או להשתמש ב – Flexbox גם לצורך בניית מבנה עיצובי.
למי מכם שמעוניין לקרוא עוד על CSS Grid Layout, מוזמן להיכנס למדריך המעולה של כריס האוס באתר CSS-TRICKS.
לקראת הפיכת המודל לנתמך אכתוב מדריך שימוש מעמיק בעברית 🙂
לפני שצוללים פנימה: מספר מונחי וקווי יסוד
על מנת שהמדריך יהיה מובן ככל האפשר, נגדיר מספר מונחי יסוד בהם אשתמש בהסבריי:
כיוון המסמך
המדריך מתייחס למצב שבו כיוון המסמך (direction) הינו ימין-לשמאל (rtl).
אלמנט מכיל
אלמנט מכיל ייקרא במדריך ובקטעי הקוד flex-container, והוא בעצם אלמנט האב.
אלמנט בן
אלמנט בן ייקרא במדריך ובקטעי הקוד flex-item, והוא בעצם בנו של האלמנט המכיל.
ציר ראשי וציר חוצה
ההסברים במדריך מתבססים על שימוש בציר ה – xy.
הציר הראשי נקבע ע"י הגדרה (flex-direction); הציר החוצה נקבע לפי הציר הראשי: אם ציר ה – x הוא הציר הראשי אזי ציר ה – y הוא הציר החוצה ולהפך.
נקודת התחלה ונקודת סוף
נקודת התחלה ונקודת הסוף מתייחסות לנקודה שבה מתחיל ולנקודה שבה נגמר (בהתאמה) ציר.
מפתח הגדרות Flexbox
הגדרות flex container
את ההגדרות הבאות מחילים על האלמנט המכיל, ובאמצעותן נקבע כיצד יתנהגו בניו (flex items).
display
מגדירה אלמנט כאלמנט שילדיו הם flex-items.
1 2 3 4 5 |
.flex-container { display: flex | inline-flex; } |
flex
האלמנט המכיל יהיה בפריסת בלוק
flex-inline
האלמנט המכיל יהיה בפריסה פנימית (בדומה לdisplay: inline)
ההגדרה חלה על האלמנט המכיל בלבד ולא על ילדיו.
flex-direction
מגדירה את הציר עליו ייפרסו בניו של האלמנט ואת הכיוון.
1 2 3 4 |
.flex-container { flex-direction: row | row-reverse | column | column-reverse; } |
האלמנטים ייפרסו על ציר ה – X (כלומר, אחד סמוך לשני) לפי כיוון המסמך (אם כיוון המסמך הוא rtl, מימין לשמאל; אם ltr, משמאל לימין)
האלמנטים ייפרסו על ציר ה – X בכיוון הנגדי לכיוון המסמך (אם כיוון המסמך הוא rtl – משמאל לימין; אם ltr – מימין לשמאל)
האלמנטים ייפרסו על ציר ה – Y (כלומר, אחד מתחת לשני) כשהאלמנט הראשון יופיע למעלה והאלמנט האחרון למטה
האלמנטים ייפרסו על ציר ה – Y (כלומר, אחד מתחת לשני) כשהאלמנט האחרון יופיע למעלה והאלמנט הראשון יופיע למטה
flex-wrap
מגדירה כיצד יתנהגו האלמנטים במקרה שבו אין מספיק מקום בשורה לכולם.
1 2 3 4 5 |
.flex-container { flex-wrap: nowrap | wrap | wrap-reverse; } |
רוחב האלמנטים יותאם כדי שיוכלו להיות בשורה אחת
כאשר אין מקום לכל האלמנטים בשורה אחת, הם ייפרסו על פני כמה שורות; סדר התצוגה יהיה לפי כיוון המסמך
כאשר אין מקום לכל האלמנטים בשורה אחת, הם ייפרסו על פני כמה שורות; סדר התצוגה יהיה בניגוד לכיוון המסמך
flex-flow
שילוב של flex-direction ו – flex-wrap.
1 2 3 4 5 |
.flex-container { flex-flow: <flex-direction-value> <flex-wrap-value> } |
ערך ברירת המחדל של הגדרה זו הוא שילוב של שני ערכי ברירת המחדל: row nowrap
justify-content
מגדירה כיצד ליישר את האלמנטים בציר הראשי.
הגדרה זו מאפשרת לקבוע כיצד לחלק את השטח העודף שנותר.
1 2 3 4 5 6 |
.flex-container { display: flex; justify-content: flex-start | flex-end | center | space-between | space-around } |
האלמנטים יתיישרו לנקודת ההתחלה (נקודת ההתחלה נקבעת לפי כיוון המסמך)
האלמנטים יתיישרו לנקודת הסוף (נקודת הסוף נקבעת לפי כיוון המסמך)
האלמנטים יתקבצו בנקודת האמצע
האלמנטים יתיישרו עם מרווחים שווים, כשהאלמנט הראשון מתחיל בנקודת ההתחלה והאלמנט האחרון מסתיים בנקודת הסוף
האלמנטים יתיישרו לפי יחידת מרווח שווה מכל צד.
שימו לב שמכיוון שבקצוות ישנה רק יחידת מרווח אחת, הרווח מנקודת ההתחלה ומנקודת הסוף לא שווה לרווח שבין האלמנטים (בין האלמנטים נוצרות שתי יחידות מרווח)
align-items
מגדירה את הדרך שבה האלמנטים יתיישרו על הציר החוצה
1 2 3 4 5 6 |
.flex-container { display: flex; align-items: flex-start | flex-end | center | stretch | baseline } |
האלמנטים יתיישרו לחלק העליון של הציר החוצה
האלמנטים יתיישרו לחלק התחתון של הציר החוצה
האלמנטים יתיישרו לאמצע הציר החוצה
האלמנטים יתיישרו לפי קו הבסיס של אלמנט האב
האלמנטים יימתחו על הציר החוצה (הגדרות רוחב/גובה מבטלות הגדרה זו)
align-content
מגדירה כיצד ליישר את כלל האלמנטים על הציר החוצה, אך ורק כאשר יש יותר משתי שורות של flex-items.
הגדרה זו מקבצת את כלל האלמנטים, לעומת align-items שמיישרת כל אלמנט כפרט.
1 2 3 4 5 6 |
.flex-container { display: flex; align-content: flex-start | flex-end | center | space-between | space-around | stretch } |
האלמנטים יימתחו על מנת למלא את החלל הריק
flex-start
האלמנטים יתקבצו בנקודת ההתחלה של הציר החוצה
האלמנטים יתקבצו בנקודת הסוף של הציר החוצה
האלמנטים יתקבצו בנקודת האמצע
האלמנטים יתקבצו עם מרווחים שווים, כשהאלמנט הראשון מתחיל בנקודת ההתחלה של הציר החוצה והאלמנט האחרון מסתיים בנקודת הסוף של האלמנט החוצה
האלמנטים יתקבצו לפי יחידת מרווח שווה מכל צד
שימו לב שמכיוון שבקצוות ישנה רק יחידת מרווח אחת, הרווח מנקודת ההתחלה ומנקודת הסוף לא שווה לרווח שבין האלמנטים (בין האלמנטים נוצרות שתי יחידות מרווח)
הגדרות בן
את ההגדרות הבאות מחילים על ה – flex-items, והן קובעות התנהגות פרטנית לאלמנט
order
מגדירה סדר תצוגה ספציפי ל – flex-item.
כברירת מחדל, כל flex-item יופיע לפי הסדר הכרונולוגי בקוד.
1 2 3 4 5 |
.flex-item { order: <integer> } |
flex-grow
מגדירה את יחס הגדילה בין flex-items
1 2 3 |
.flex-item { flex-grow: <integer> } |
יחס הגדילה מחושב על-פי הנוסחה הבאה:
1 2 3 |
(flexContainerWidth - flexItemsWidth) / totalFlexGrowthUnits |
* ערכים שליליים לא מתקבלים!
flex-shrink
מגדירה את יחס ההתכווצות בין flex-items
1 2 3 |
.flex-item { flex-shrink: <integer> } |
* גם כאן – ערכים שליליים לא מתקבלים!
flex-basis
מגדירה גודל ברירת מחדל של flex-item לפני חלוקת שארית השטח הריק.
1 2 3 4 |
.flex-item { flex-basis: <unit> | auto; } |
auto (ערך ברירת מחדל)
גודל ברירת המחדל יקבע לפי הגדרת width של האלמנט
unit
יחידת אורך (px, em, % וכו')
*ישנם מס' ערכים נוספים שניתן ליישם, אך הם אינם נתמכים נכון לכתיבת שורות אלו.
flex
שילוב של flex-grow, flex-shrink ו – flex-basis.
1 2 3 4 |
.flex-item { flex: none | [<flex-grow> <flex-shrink> <flex-basis>] } |
* לא חובה לכלול ערכים עבור flex-shrink ו – flex-basis
* הגדרת ברירת מחדל:
1 2 3 |
.flex-item { flex: 0 1 auto; } |
align-self
מאפשרת לדרוס את הדרך שבה אלמנט יתיישר על הציר החוצה
1 2 3 |
.flex-item { align-self: auto | flex-start | flex-end | center | stretch | baseline } |
auto (ערך ברירת מחדל)
האלמנט יתיישר לפי ההתנהגות הטבעית
flex-start
האלמנט יתיישר לחלק העליון של הציר החוצה
flex-end
האלמנט יתיישר לחלק התחתון של הציר החוצה
center
האלמנט יתיישר לאמצע הציר החוצה
baseline
האלמנטים יתיישר לפי קו הבסיס של אלמנט האב
stretch
האלמנט יימתח על הציר החוצה (הגדרות רוחב/גובה מבטלות הגדרה זו)
דוגמאות
כאמור, Flexbox הינו מודל CSS ולכן השלב הראשון יהיה להגדיר את אלמנט האב כאלמנט flex:
1 2 3 4 |
.flex-container { display: flex; } |
ברגע שהגדרנו את מצב הפריסה של האלמנט המכיל כ – flex, הגדרות ברירת המחדל מיושמות:
1 2 3 4 5 6 7 8 9 10 |
.flex-container { display: flex; flex-direction: row; flex-wrap: nowrap; justify-content: flex-start; align-items: flex-start; align-content: stretch; } |
ובעברית: flex-items ייפרסו על ציר ה – X (שהוא הציר הראשי), יתאימו את רוחבם כדי להיות בשורה אחת, יתיישרו לנקודת ההתחלה של ציר ה – X (הציר הראשי) ולנקודת ההתחלה של ציר ה – Y (הציר החוצה) וגובהם יהיה 100%.
ועכשיו לתכלס: מה אפשר לעשות עם ה – flexible box?
דוגמה 1: יישור אלמנט לאמצע
אינספור שיטות ליישור אלמנט לאמצע האנכי של אלמנט האב: שימוש ב – position: fixed ו – margin, שימוש בהגדרה transform ועוד ועוד ועוד.
עם flexbox, זה מעולם לא היה פשוט יותר:
1 2 3 4 |
.flex-container { display: flex; align-items: center; } |
זהו! מעכשיו כל האלמנטים תחת flex-container יתיישרו למרכז האנכי (middle) של האלמנט.
כאמור, כאשר אנו מגדירים אלמנט כ – display: flex, כל בניו יתיישרו כברירת מחדל על ציר ה – x.
ההגדרה align-items קובעת כיצד יתיישרו הבנים על הציר החוצה, שהוא במקרה שלנו ציר ה – y.
אם נרצה ליישר את האלמנטים גם למרכז האופקי (center), נשתמש בהגדרה justify-content:
1 2 3 4 5 6 7 8 |
.flex-container { display: flex; justify-content: center; align-items: center; height: 500px; } |
* css-tricks מציעים במדריך שלהם דרך שונה למרכוז אלמנט (דוגמה ראשונה), באמצעות הגדרת margin: auto; לאלמנט הבן.
אישית, אני מחזיק בדעה שהפתרון שלי אלגנטי ונכון יותר מכיוון שנעשה בו שימוש בהגדרות המיועדות ליישור אלמנט flex.
דוגמה 2: מרווחים שווים? לא צריך לשבור את הראש עם margin!
כמעט בכל פרוייקט עליו עבדתי עד כה, הייתי צריך לסדר מס' פריטים (על ציר ה – x) במרווחים שווים אחד לשני.
בשביל לעשות את זה צריך להתעסק עם שלל הגדרות: floatים כדי שיופיעו אחד לצד השני, הגדרות שונות לילד הראשון (:first-child) כדי לאפס את הmargin ועוד ועוד. עם flexbox זה כל כך פשוט:
1 2 3 4 5 6 |
.flex-container { display: flex; flex-wrap: wrap; justify-content: space-between; } |
זה הכל! כל האלמנטים יתיישרו עם מרווחים שווים ללא קשר לרוחבם, וגם אם תנסו לשנות גודל אלמנט באופן דינאמי – ה – Flexible Box Layout יהיה נכון לאתגר.
שימוש בקידומת webkit
אינני מעריץ גדול של שימוש בקידומות (הן הולכות להיעלם מהעולם), אבל אי אפשר להתעלם מהעובדה שלעתים יש לכך השפעה משמעותית על תאימות לדפדפנים.
במקרה של מודל Flexbox, הוספת קדומת webkit תגדיל את אחוז המשתמשים שיכולים "להנות" מהמודל בכקרוב ל – 4%.
למי שבוחר כן להוסיף את הקידומת, חשוב לזכור שבנוסף להגדרה עם הקידומת, יש לכלול גם את ההגדרה ללא הקידומת:
1 2 3 4 5 6 7 8 9 10 11 |
.flex-container { display: -webkit-flex; display: flex; } .flex-item { -webkit-flex-grow: 2; flex-grow: 2; } |
תאימות לדפדפנים
הטבלה הבאה מציגה אילו דפדפנים תומכים במודל Flexible Box נכון לתאריך כתיבת מדריך זה:
- Internet Explorer (11) *
- Edge (13+)
- Firefox (45+)
- Chrome (29+)
- Safari (9+)
- Opera (36+)
- iOS Safari (8.4+)
כיום בישראל, כ- 85% משתמשים בדפדפנים שתומכים במודל באופן מלא, ועוד 9.5% משתמשים בדפדפנים שתומכים במודל באופן חלקי (סה"כ 95% מהמשתמשים).
כ – 5% משתמשים בדפדפנים שלא תומכים במודל.
* גרסה 11 של Internet Explorer תומכת באופן חלקי בלבד במודל, באגים עשויים להופיע.
בגרסה 10 של Internet Explorer ישנו יישום של ה – Flexbox באמצעות קידומת -ms-. לקריאה נוספת: המדריך למפתח עבור Internet Explorer 10 באתר מיקרוסופט.
מה, הכל ורוד?
חשוב לזכור שעם כל יתרונותיו של המודל, הוא עדיין נמצא בשלב טיוטה והוא איננו חף מתקלות.
גרג וויטוורת' דואג לרכז את כל הבאגים תחת קוד פתוח (שימו לב למשחק המילים המשעשע "Flexbugs"), עם עדכונים על תיקון הבאגים ודרכים לעקוף אותם.
סביר להניח שככל שנתקדם בזמן, יותר ויותר באגים יתוקנו.
ולסיכום
עושה רושם שמשהו טוב עובר על צוות המפתחים של CSS.
אמנם באיחור – הם השכילו להבין שעולם הווב עובר שינוי ונהיה חלק עוד יותר מרכזי בטכנולוגיה.
עד שיצא מודל ה – Grid, מודל ה – Flexbox הוא הפתרון הטוב ביותר ולאחר שמתנסים בשימוש בו,
הוא חוסך זמן רב ומשאבים.
יש לך שאלות? משהו לא ברור? כתבו לי בתגובות ואענה 🙂
מקורות
- מדריך מקיף (באנגלית) – CSS TRICKS
- אפיון רשמי (W3)
- תאימות לדפדפנים (caniuse)
- Flexbugs – מעקב אחר בעיות עם המודל


11 תגובות
אוריאל
27 במאי 2016 - 18:15אחלה מדריך, כל הכבוד 🙂
לביא
29 במאי 2016 - 15:10תודה על המאמר. כל הכבוד על ההשקעה!
יונתן נקסון
29 במאי 2016 - 15:52תודה, כיף לשמוע 🙂
עדי
7 באוקטובר 2016 - 0:04יפה מאוד! תודה רבה!
אריאל
13 באוקטובר 2017 - 23:10משחק נחמד ללימוד ותרגול Flexbox (יש שם המון מהדברים שדיברת עליהם בכתבה פה):
http://flexboxfroggy.com/
אלחנן לבבי
31 בינואר 2018 - 12:05תודה על המדריך המצויין!
רועי
12 ביולי 2018 - 20:49אחלה מדריך! סחתיין… 🙂
מצרף מדריך רלוונטי לנושא שכתבתי על CSS Grid עם מישהו מעוניין…. https://he.savvy.co.il/blog/?p=7580
פלפלת
12 באוקטובר 2019 - 14:38יפה. מוסבר ממש יפה ומפורט.
בת שבע
31 במרץ 2020 - 16:21המדריך טוב מאוד!!
ונחמד שהוא בעברית..
אך עדיין יש לי בעיה שלא הצלחתי לפתור עם זה.
יש לי דף עם כרטיסים. שאם אני לא שמה לו margin אז כשמקטנים את העמוד זה מצתמשם ונדבק אחד לשני.
אך אם אני שמה margin אזי כשאני מקטינה את הדף זה לא מקטין את הכרטיס אלא מוריד שורה כרטיסים.
אשמח לעזרה.
תודה!!
דודי
4 בנובמבר 2020 - 11:01אחלה מאמר עוזר מאוד!
רמי
12 באפריל 2022 - 13:11יש בעיה בהצגת הקודים… ענייני html