מה display: flex עושה
שימו display: flex על הורה, והילדים הישירים שלו מסתדרים בשורה, זה לצד זה, ונמתחים לאותו גובה. ההצהרה האחת הזאת מחליפה floats, inline-block ואת רוב טריקי המיקום לסידור שורה של דברים.
בתיבה הראשונה כל div תופס שורה שלמה. בשנייה שלושת הפריטים יושבים בשורה אחת, כל אחד ברוחב התוכן שלו בלבד, ו-One ו-Three נמתחים לגובה של Two. רק ההורה השתנה: display: flex נכתב על המכל, אף פעם לא על הפריטים.
עורך אונליין ל-Flexbox
בחרו ערכים וצפו בפריטים זזים. שורת הקוד שמתחת לתיבה היא ה-CSS של מה שאתם רואים, והרשימה שמתחתיה היא איפה הדפדפן באמת הציב כל פריט, כפי שנמדד עם getBoundingClientRect().
דברים לנסות:
justify-content: space-between: פריט 1 נוחת ב-x 0 ופריט 3 נוגע בקצה הרחוק.align-items: center: שלושת הפריטים שומרים על הגובה שלהם והמרכזים שלהם מתיישרים. עם ברירת המחדלstretch, לפריט 1 אין גובה משלו והוא ממלא את כל 170px של המכל.flex-direction: column: עכשיוjustify-contentמזיז פריטים אנכית ו-align-itemsאופקית. שני המאפיינים עוקבים אחרי הצירים, לא אחרי המסך.
ציר ראשי וציר ניצב
לכל מכל flex יש שני צירים. הציר הראשי הוא הכיוון שבו הפריטים זורמים, שנקבע על ידי flex-direction. הציר הניצב חוצה אותו.
flex-direction | ציר ראשי | ציר ניצב | justify-content מזיז פריטים | align-items מזיז פריטים |
|---|---|---|---|---|
row (ברירת מחדל) | אופקי, בסדר הקריאה | אנכי | אופקית | אנכית |
row-reverse | אופקי, הפוך | אנכי | אופקית | אנכית |
column | אנכי, מלמעלה למטה | אופקי | אנכית | אופקית |
column-reverse | אנכי, מלמטה למעלה | אופקי | אנכית | אופקית |
בעמוד מימין לשמאל (dir="rtl"), row מתחיל בקצה הימני, כי הציר הראשי עוקב אחרי כיוון הכתיבה.
מאפייני המכל
אלה נכתבים על האלמנט עם display: flex:
| מאפיין | מה הוא עושה | ברירת מחדל |
|---|---|---|
flex-direction | שורה או עמודה, ובאיזה כיוון | row |
flex-wrap | אם פריטים עוברים לשורה חדשה כשנגמר להם המקום | nowrap |
flex-flow | קיצור ל-flex-direction ול-flex-wrap | row nowrap |
justify-content | מיקום וריווח לאורך הציר הראשי | normal (מתנהג כמו flex-start) |
align-items | מיקום הפריטים לאורך הציר הניצב | normal (מתנהג כמו stretch) |
align-content | ריווח בין שורות כשפריטים עוברים שורה | normal |
gap | רווח בין פריטים (row-gap, column-gap) | 0 |
ל-justify-content ול-align-items יש כל אחד עמוד משלו עם כל הערכים: justify-content ו-align-items. שבירת שורה וכיוון מוסברים בעמוד ה-flex-wrap.
מאפייני פריט: flex-grow, flex-shrink, flex-basis
אלה נכתבים על הילדים וקובעים איך הם מתחלקים ברוחב המכל:
flex-basis: הגודל שממנו פריט מתחיל לפני שהמקום הפנוי מתחלק (autoפירושו "השתמש ברוחב שלי או בתוכן שלי").flex-grow: כמה חלקים מהמקום הנותר הפריט לוקח.0פירושו שהוא אף פעם לא גדל.flex-shrink: כמה הפריט מוותר כשאין מספיק מקום.0פירושו שהוא אף פעם לא מתכווץ.
הקיצור flex קובע את שלושתם:
| אתם כותבים | שפירושו | התנהגות |
|---|---|---|
flex: initial (ברירת מחדל) | 0 1 auto | גודל התוכן, יכול להתכווץ, אף פעם לא גדל |
flex: 1 | 1 1 0% | מתחיל מאפס ולוקח חלק שווה מהמקום |
flex: auto | 1 1 auto | גודל התוכן ועוד חלק מהמקום הנותר |
flex: none | 0 0 auto | בדיוק התוכן או הרוחב שלו, אף פעם לא גדל או מתכווץ |
flex: 2 | 2 1 0% | פי שניים מהחלק של פריט עם flex: 1 |
כל שורה ברוחב 480px בתוך ה-padding שלה, ושני הרווחים של 8px משאירים 464px לפריטים. הרוחבים המודפסים מראים איך המקום התחלק: בערך 155px כל אחד בשורה הראשונה, 116 + 232 + 116 בשנייה (הפריט עם flex: 2 מקבל פי שניים מהחלק של כל שכן), ו-100 + 372 בשלישית, שבה הפריט עם flex: none שומר על הרוחב שלו והפריט האחר לוקח את כל השאר.
פריסות אמיתיות עם flexbox
כותרת עליונה עם לוגו בהתחלה וקישורים בסוף היא פריסת ה-flex הנפוצה ביותר. margin-inline-start: auto על פריט אחד בולע את כל המקום הפנוי לפניו ודוחף אותו ואת כל מה שאחריו לסוף:
align-items: center מיישר את הטקסט הגדול יותר של הלוגו עם הקישורים, ו-gap מרווח את הקישורים בלי margin שצריך לבטל בקישור האחרון.
דפוס יומיומי שני הוא שורת מדיה: אייקון בגודל קבוע וטקסט שלוקח את השאר ונשבר בתוך העמודה שלו.
flex: none הוא הערובה. פריטי flex מתכווצים כברירת מחדל, ולכן אם תסירו אותו מהעיגול ותסירו גם את flex: 1 מהטקסט, הפסקה תדחוס את העיגול לרוחב של בערך 23px: אליפסה. כדי למרכז דבר אחד בתוך תיבה, flexbox הוא שתי שורות (justify-content: center; align-items: center); עמוד מרכוז div משווה את זה לדרכים האחרות.
order ונגישות
המאפיין order והכיוונים עם -reverse משנים איפה פריטים מופיעים, לא איפה הם נמצאים ב-HTML. קוראי מסך ומקש ה-Tab עדיין עוקבים אחרי הסדר ב-HTML, כך שמשתמש מקלדת יכול לקפוץ מהקישור הראשון על המסך לאחרון. השתמשו בהם רק לקישוט; כשלסדר יש משמעות, שנו את ה-HTML.
Flexbox או grid
Flexbox עובד בכיוון אחד בכל פעם: פריטים בשורה קובעים את הגודל שלהם לפי התוכן, ושורה שנייה (עם שבירת שורה) לא מתיישרת עם הראשונה. Grid עובד בשני כיוונים: מגדירים עמודות ושורות, והפריטים נכנסים לתוכן. סרגל ניווט, סרגל כלים או שורה בטופס הם flexbox; גלריה או עמוד עם סרגל צד הם grid.
טעויות נפוצות
display: flexעל הפריט במקום על ההורה. המכל מקבלdisplay: flex; הילדים שלו הם הפריטים.- ציפייה ש-
align-itemsיזיז פריטים אנכית בלי גובה. אם המכל גבוה רק כמו הפריט הגבוה ביותר שלו, אין מקום לזוז. תנו למכל גובה; אחרת הוא עובד, פשוט אין לו מה לעשות. - טקסט שגולש במקום להתכווץ. לפריטי flex יש
min-width: auto. הוסיפוmin-width: 0לפריט שצריך להתכווץ. - שימוש ב-
flex: 1ותהייה למה הרוחבים שונים. פריטים עםflex: 1מתחלקים במקום שווה בשווה, אבל פריט שהתוכן שלו לא נכנס (כתובת URL ארוכה, תמונה) לא יתכווץ מתחת לתוכן. גם את זהmin-width: 0מתקן. - margin בין פריטים. השתמשו ב-
gapעל המכל; הוא נכנס רק בין פריטים. - קינון flex מיותר. רק ילדים ישירים הם פריטי flex. נכדים עוקבים אחרי פריסה רגילה, אלא אם גם ההורה שלהם הוא
display: flex.
שאלות נפוצות
מה עושה display: flex?
הוא הופך אלמנט למכל flex. הילדים הישירים שלו הופכים לפריטי flex ומוצבים כברירת מחדל בשורה, זה לצד זה, מתוחים לאותו גובה, ומאפיינים כמו justify-content, align-items ו-gap שולטים באופן שבו הם מתחלקים במקום.
מה המשמעות של flex: 1?
flex: 1 הוא קיצור של flex: 1 1 0%: הפריט יכול לגדול (flex-grow: 1), יכול להתכווץ (flex-shrink: 1), ומתחיל מגודל אפס (flex-basis: 0%). פריטים שלכולם יש flex: 1 מחלקים את המקום הפנוי שווה בשווה, כך שהם יוצאים באותו רוחב, אלא אם התוכן שלהם לא נכנס.
מה ההבדל בין justify-content ל-align-items?
justify-content ממקם פריטים לאורך הציר הראשי (אופקית בשורה), ו-align-items ממקם אותם לאורך הציר הניצב (אנכית בשורה). עם flex-direction: column שני הצירים מתחלפים, כך ש-justify-content הופך לאנכי.
להשתמש ב-flexbox או ב-grid?
השתמשו ב-flexbox לשורה או עמודה אחת שהפריטים שלה קובעים את הגודל שלהם לפי התוכן: סרגלי ניווט, קבוצות כפתורים, תווית ליד שדה קלט. השתמשו ב-grid כשאתם רוצים שורות ועמודות שמתיישרות זו עם זו, כמו רשת כרטיסים או פריסת עמוד.
למה פריט ה-flex שלי גולש מהמכל?
לפריט flex יש min-width: auto כברירת מחדל, ולכן הוא מסרב להתכווץ מתחת לרוחב של המילה הארוכה ביותר או הילד הרחב ביותר שלו. הגדירו min-width: 0 (או overflow: hidden) על הפריט כדי לאפשר לו להתכווץ, למשל כדי ש-text-overflow: ellipsis יעבוד.
האם flexbox עובד על אלמנטי inline כמו span?
כן. כל אלמנט עם display: flex הוא מכל flex, והילדים שלו הופכים לפריטי flex לא משנה מה ערך ה-display שלהם, כך שילדי <span> מפסיקים להיות inline ומקבלים רוחב, גובה ו-margin כמו בלוקים.