The CSS Podcast – 010: Flexbox
דפוס עיצוב שיכול להיות בעייתי בעיצוב רספונסיבי הוא סרגל צד שממוקם בתוך תוכן מסוים. כשיש מספיק מקום בחלון התצוגה, התבנית הזו עובדת מצוין, אבל כשהמרחב מצומצם, הפריסה הנוקשה הזו עלולה להפוך לבעייתית.
מודל הפריסה של תיבות גמישות (flexbox) הוא מודל פריסה שמיועד לתוכן דו-מימדי. הוא מתאים במיוחד לקבוצה של פריטים בגדלים שונים, ומחזיר את הפריסה הטובה ביותר לפריטים האלה.
זהו מודל הפריסה האידיאלי לדפוס סרגל הצד הזה. Flexbox עוזר לא רק להציג את סרגל הצד והתוכן בשורה אחת, אלא גם במקרים שבהם אין מספיק מקום, סרגל הצד יוצג בשורה חדשה. במקום להגדיר מידות קפדניות שהדפדפן צריך לפעול לפיהן, אפשר להשתמש ב-flexbox כדי לספק גבולות גמישים שנותנים רמז לגבי האופן שבו התוכן יוצג.
מה אפשר לעשות עם פריסה גמישה?
למבנים גמישים יש את התכונות הבאות, שאפשר לקרוא עליהן במדריך הזה.
- אפשר להציג אותן כשורה או כעמודה.
- הם מכבדים את מצב הכתיבה של המסמך.
- הן מוצגות בשורה אחת כברירת מחדל, אבל אפשר לבקש שהן יוצגו בכמה שורות.
- אפשר לשנות את הסדר של הפריטים בפריסה ויזואלית, חוץ מהסדר שלהם ב-DOM.
- אפשר לחלק את המרחב בתוך הפריטים, כך שהם יהיו גדולים יותר או קטנים יותר בהתאם למרחב הזמין ברכיב ההורה שלהם.
- אפשר להקצות מקום סביב הפריטים וקווי הגמישות בפריסה עטופה באמצעות מאפייני Box Alignment (יישור התיבה).
- אפשר ליישר את הפריטים עצמם על ציר הצלב.
הציר הראשי והציר הצלב
המפתח להבנת flexbox הוא להבין את המושגים 'ציר ראשי' ו'ציר רוחבי'.
הציר הראשי הוא הציר שמוגדר בנכס flex-direction
.
אם הערך הוא row
, הציר הראשי נמצא לאורך השורה. אם הוא column
, הציר הראשי יהיה לאורך העמודה.
פריטים גמישים נעים כקבוצה בציר הראשי. חשוב לזכור: יש לנו כמה דברים שאנחנו מנסים למצוא להם את הפריסה הטובה ביותר כקבוצה.
ציר הצלב עובר בכיוון ההפוך לציר הראשי, כך שאם flex-direction
הוא row
, ציר הצלב עובר לאורך העמודה.
ניתן לבצע שתי פעולות בציר הצלב.
אפשר להעביר את הפריטים בנפרד או כקבוצה, כך שהם יתאימו זה לזה ולמאגר הגמיש. בנוסף, אם יש לכם קווים גמישים שכוללים קווים גמישים, אפשר להתייחס לשורות האלה כקבוצה כדי לקבוע איך יוקצה המקום לשורות האלה.
בהמשך המדריך נסביר איך כל זה עובד בפועל, אבל בינתיים חשוב לזכור שהציר הראשי עוקב אחרי flex-direction
.
יצירת קונטיינר גמיש
בואו נראה איך Flexbox פועל: לוקחים קבוצה של פריטים בגדלים שונים ומשתמשים ב-Flexbox כדי לפרוס אותם.
<div class="container" id="container">
<div>One</div>
<div>Item two</div>
<div>The item we will refer to as three</div>
</div>
כדי להשתמש ב-Flexbox, צריך להצהיר שאתם רוצים להשתמש בהקשר של עיצוב Flex ולא בתצוגת בלוקים רגילה ובתצוגה בתוך שורה.
לשם כך, משנים את הערך של המאפיין display
לערך flex
.
.container {
display: flex;
}
כפי שלמדתם במדריך לגבי פריסה, כך תקבלו תיבה ברמת הבלוק עם פריטים גמישים בתור צאצאים. פריטים גמישים מתחילים להציג התנהגות מסוימת של Flexbox מיד, על סמך הערכים הראשוניים שלהם.
הערכים הראשוניים משמעותם:
- הפריטים מוצגים בשורה.
- הם לא גלישה.
- הם לא גדלים כדי למלא את המאגר.
- הם ניצבים בתחילת הקונטיינר.
שליטה בכיוון של פריטים
למרות שעדיין לא הוספתם את המאפיין flex-direction
, הפריטים מוצגים בשורה כי הערך הראשוני של flex-direction
הוא row
.
אם רוצים שורה, אין צורך להוסיף את הנכס.
כדי לשנות את הכיוון, מוסיפים את המאפיין ואחד מארבעת הערכים הבאים:
row
: הפריטים מסודרים כשורה.row-reverse:
הפריטים פרוסים כשורה מהקצה של המאגר הגמיש.column
: הפריטים פרוסים כעמודה.column-reverse
: הפריטים מוצגים כעמודה מסוף הקונטיינר הגמיש.
אתם יכולים לנסות את כל הערכים באמצעות קבוצת הפריטים שלנו בדמו שבהמשך.
להפוך את רצף הפריטים והנגישות
חשוב להיזהר כשמשתמשים במאפיינים שמשנה את הסדר של התצוגה החזותית, כך שלא תואמת לסדר שבו הדברים מסודרים במסמך ה-HTML, כי זה עלול להשפיע לרעה על הנגישות.
הערכים row-reverse
ו-column-reverse
הם דוגמה טובה לכך.
המערכת משנה את הסדר רק מבחינה חזותית, ולא מבחינה לוגית.
חשוב להבין את העניין הזה, כי הסדר ההגיוני הוא הסדר שבו קורא המסך יקרא את התוכן, וגם כל מי שמנווט באמצעות המקלדת יתבסס עליו.
בסרטון הבא אפשר לראות איך בפריסה של שורות הפוכות, הקשה על Tab בין קישורים הופכת ללא רציפה כי הניווט במקלדת פועל לפי DOM ולא לפי התצוגה החזותית.
כל דבר שיכול לשנות את סדר הפריטים ב-flexbox או ב-grid עלול לגרום לבעיה הזו. לכן, כל סידור מחדש צריך לכלול בדיקה יסודית כדי לוודא שלא יהיה קשה להשתמש באתר לחלק מהאנשים.
מידע נוסף זמין במאמרים הבאים:
מצבי כתיבה וכיוון כתיבה
כברירת מחדל, פריטים גמישים מוצגים בשורה. שורה נמתחת בכיוון שבו המשפטים זורמים במצב הכתיבה ובכיוון הסקריפט. כלומר, אם אתם עובדים בערבית, שבה כיוון הסקריפט הוא מימין לשמאל (rtl), הפריטים ייערכו בצד שמאל. גם סדר הקלדת Tab יתחיל מימין, כי כך קוראים את המשפטים בערבית.
אם אתם עובדים במצב כתיבה אנכי, כמו בחלק מהגופנים היפניים, השורה תהיה אנכית, מלמעלה למטה.
כדאי לנסות לשנות את flex-direction
בהדגמה הזו שמשתמש במצב כתיבה אנכית.
לכן, האופן שבו פריטים גמישים מתנהגים כברירת מחדל מקושר למצב הכתיבה של המסמך. רוב המדריכים נכתבים באנגלית או במצב כתיבה אופקי אחר, משמאל לימין. כך קל להניח שפריטי Flex יישורו בצד ימין ויוצגו באופן אופקי.
כשמביאים בחשבון את הציר הראשי והציר הרוחבי ואת אופן הכתיבה, קל יותר להבין את העובדה שאנחנו מדברים על התחלה וסיום במקום על 'למעלה', 'למטה', 'ימין' ו'שמאל' ב-Flexbox. לכל ציר יש תחילה וסוף. ההתחלה של הציר הראשי נקראת התחלה ראשית. לכן, הפריטים הגמישים שלנו מתאימים בהתחלה מ-main-start. הקצה של הציר הזה הוא main-end. תחילת הציר המאונך היא cross-start והסוף הוא cross-end.
אריזה של פריטים גמישים
הערך הראשוני של המאפיין flex-wrap
הוא nowrap
.
כלומר, אם אין מספיק מקום בקונטיינר, הפריטים יגלשו.
פריטים שמוצגים באמצעות הערכים הראשוניים יתכווצו עד כמה שאפשר, עד לגודל min-content
, לפני שתתרחש חריגה ממלאי.
כדי לגרום לאריזה של הפריטים, מוסיפים flex-wrap: wrap
למאגר הגמיש.
.container {
display: flex;
flex-wrap: wrap;
}
כשקונטיינר גמישות עוטף, הוא יוצר כמה קווים גמישים. מבחינת חלוקת המרחב, כל שורה פועלת כקונטיינר גמיש חדש. לכן, אם אתם מגדירים שורות שמסתובבות, אי אפשר לגרום למשהו בשורה 2 להתאים למשהו שמעליו בשורה 1. זו הסיבה לכך ש-Flexbox הוא דו-מימדי. אפשר לשלוט ביישור בציר אחד, בשורה או בעמודה, אבל לא בשניהם יחד, כפי שאנחנו יכולים לעשות ברשת.
קיצור הדרך של flex-flow
אפשר להגדיר את המאפיינים flex-direction
ו-flex-wrap
באמצעות קיצור הדרך flex-flow
.
לדוגמה, כדי להגדיר את flex-direction
כ-column
ולאפשר פריטים לעטוף:
.container {
display: flex;
flex-flow: column wrap;
}
שליטה במרחב בתוך פריטים גמישים
בהנחה שיש בקונטיינר יותר מקום ממה שנחוץ כדי להציג את הפריטים, הפריטים ייפרסו בתחילת הקונטיינר ולא יתרחבו כדי למלא את כל הקונטיינר.
הם מפסיקים לגדול כשהם מגיעים לגודל התוכן המקסימלי.
הסיבה לכך היא שהערך הראשוני של המאפיינים flex-
הוא:
flex-grow: 0
: הפריטים לא גדלים.flex-shrink: 1
: הפריטים יכולים להתכווץ לגודל קטן יותר מflex-basis
.flex-basis: auto
: גודל הבסיס של הפריטים הואauto
.
אפשר לייצג את הערך הזה בערך של מילת המפתח flex: initial
.
המאפיין המקוצר flex
או המאפיינים המלאים flex-grow
, flex-shrink
ו-flex-basis
חלים על הצאצאים של קונטיינר ה-flex.
כדי להגדיל את מספר הפריטים, ויחד עם זאת, לאפשר לפריטים גדולים לפנות יותר מקום מאשר לפריטים קטנים, צריך להשתמש בפונקציה flex:auto
.
אפשר לנסות לעשות זאת באמצעות ההדגמה שלמעלה.
כך מגדירים את המאפיינים:
flex-grow: 1
: הפריטים יכולים לגדול מעבר ל-flex-basis
שלהם.flex-shrink: 1
: הפריטים יכולים להתכווץ לגודל קטן יותר מ-flex-basis
.flex-basis: auto
: לפריטים יש גודל בסיס שלauto
.
המשמעות של flex: auto
היא שהגודל של הפריטים יהיה שונה, כי השטח המשותף בין הפריטים משותף אחרי שכל פריט מוגדר לגודל התוכן המקסימלי.
כך, פריט גדול יקבל יותר מקום.
כדי לאלץ את כל הפריטים להיות באותו גודל ולהתעלם מהגודל של התוכן, משנים את הערך של flex:auto
ל-flex: 1
בדמו.
הפירוט הוא:
flex-grow: 1
: הפריטים יכולים לגדול מעבר ל-flex-basis
שלהם.flex-shrink: 1
: הפריטים יכולים להתכווץ לגודל קטן יותר מ-flex-basis
.flex-basis: 0
: לפריטים יש גודל בסיס של0
.
השימוש ב-flex: 1
מציין שכל הפריטים הם בגודל אפס, ולכן כל המרחב בקונטיינר הגמיש זמין לחלוקה.
מכיוון שלכל הפריטים יש גורם flex-grow
של 1
, כולם גדלים באותה מידה והמרחב משותף באופן שווה.
מתן אפשרות לפריטים לגדול בקצב שונה
לא חובה לתת לכל הפריטים גורם flex-grow
של 1
.
אפשר להקצות לפריטי ה-Flex גורמים שונים של flex-grow
.
בדמו שבהמשך, הפריט הראשון מכיל את הערך flex: 1
, הפריט השני מכיל את הערך flex: 2
והפריט השלישי מכיל את הערך flex: 3
.
כשהפריטים האלה גדלים החל מ-0
, נפח האחסון הזמין בקונטיינר הגמיש משותף לשישה.
החלק הראשון מוקצה לפריט הראשון, החלק השני מוקצה לפריט השני והחלק השלישי מוקצה לפריט השלישי.
אפשר לעשות את אותו הדבר מ-flex-basis
של auto
, אבל תצטרכו לציין את שלושת הערכים.
הערך הראשון הוא flex-grow
, השני הוא flex-shrink
והשלישי הוא flex-basis
.
.item1 {
flex: 1 1 auto;
}
.item2 {
flex: 2 1 auto;
}
זהו תרחיש פחות נפוץ, כי הסיבה לשימוש ב-flex-basis
של auto
היא לאפשר לדפדפן להבין את התפלגות החלל.
אם רוצים לגרום לפריט לגדול קצת יותר מכפי שהאלגוריתם קובע, עם זאת, הפריט עשוי להיות שימושי.
שינוי הסדר של פריטים גמישים
אפשר לשנות את הסדר של הפריטים במאגר הגמישה באמצעות המאפיין order
.
המאפיין הזה מאפשר את סדר הפריטים בקבוצות סידוריות.
הפריטים מסודרים לפי הכיוון של flex-direction
, וקודם הערכים הנמוכים ביותר.
אם יש יותר מפריט אחד עם אותו ערך, הוא יוצג עם שאר הפריטים עם הערך הזה.
הדוגמה הבאה ממחישה את הסדר הזה.
בדיקת ההבנה
בוחנים את הידע שלכם ב-Flexbox
ערך ברירת המחדל של flex-direction
הוא
row
column
כברירת מחדל, קונטיינר Flex עוטף צאצאים.
flex-wrap: wrap
עם display: flex
לגלישת ילדיםפריט צאצא של Flex נראה מרוחק, איזה מאפיין Flex עוזר לצמצם את הבעיה הזו?
flex-grow
flex-shrink
flex-basis
סקירה כללית על יישור Flexbox
Flexbox הביא איתו קבוצת מאפיינים ליישור פריטים ולחלוקת מקום בין פריטים. המאפיינים האלה היו כל כך שימושיים שהם הועברו למפרט משלהם, ותוכלו למצוא אותם גם בתצוגת הרשת. כאן מוסבר איך הם פועלים כשמשתמשים ב-Flexbox.
אפשר לחלק את קבוצת הנכסים לשתי קבוצות. מאפיינים לחלוקת המרחב ומאפיינים ליישור. המאפיינים שמקצים שטח הם:
justify-content
: חלוקת המרחב על הציר הראשי.align-content
: התפלגות הרווח על ציר הצלב.place-content
: קיצור דרך להגדרה של שני הנכסים שלמעלה.
המאפיינים שמשמשים ליישור ב-Flexiblebox:
align-self
: מיישר פריט יחיד בציר הרוחבי.align-items
: מיישרת את כל הפריטים כקבוצה על הציר האופקי.
אם עובדים על הציר הראשי, השמות של המאפיינים מתחילים ב-justify-
.
בציר העובר הם מתחילים ב-align-
.
חלוקת השטח על הציר הראשי
בקוד ה-HTML שצוין קודם, פריטי ה-flex מסודרים בשורה, ויש מקום בציר הראשי.
הפריטים לא גדולים מספיק כדי למלא את כל המכל הגמיש.
הפריטים מסודרים בתחילת מאגר הפריטים הגמיש כי הערך הראשוני של justify-content
הוא flex-start
.
הפריטים מופיעים בהתחלה ורווחים מיותרים בסוף.
מוסיפים את המאפיין justify-content
לקונטיינר הגמיש ונותנים לו את הערך flex-end
. הפריטים יופיעו בסוף הקונטיינר והמקום הפנוי ממוקם בהתחלה.
.container {
display: flex;
justify-content: flex-end;
}
אפשר גם לחלק את הרווח בין הפריטים באמצעות justify-content: space-between
.
כדאי לנסות כמה מהערכים בדמו, ולעיין במאמר ב-MDN כדי לראות את הקבוצה המלאה של הערכים האפשריים.
עם flex-direction: column
אם שיניתם את flex-direction
ל-column
, הפונקציה justify-content
תפעל בעמודה.
כדי שיהיה מקום פנוי במאגר כשעובדים בתור עמודה, צריך להקצות למאגר height
או block-size
.
אחרת לא יהיה לכם מקום פנוי לצורך הפצה.
נסו את הערכים השונים, הפעם עם פריסה של עמודות ב-flexbox.
חלוקת רווח בין קווים גמישים
עם מיכל גמיש ארוז, יכול להיות שיהיה מקום לפזר על הציר האופקי.
במקרה כזה, אפשר להשתמש במאפיין align-content
עם אותם ערכים כמו justify-content
.
בניגוד ל-justify-content
שמיישר את הפריטים ל-flex-start
כברירת מחדל, הערך הראשוני של align-content
הוא stretch
.
כדי לשנות את התנהגות ברירת המחדל הזו, מוסיפים את המאפיין align-content
למאגר התגים הגמיש.
.container {
align-content: center;
}
אפשר לנסות את זה בהדגמה.
בדוגמה יש שורות עטופות של פריטים גמישה, ובקונטיינר יש block-size
כדי שיהיה לנו מקום פנוי.
הקיצורה place-content
כדי להגדיר גם את justify-content
וגם את align-content
, אפשר להשתמש ב-place-content
עם ערך אחד או שניים.
אם מציינים שהערך הראשון ישמש את align-content
והשני ישמש את justify-content
, המערכת תשתמש בערך יחיד בשני הצירים.
.container {
place-content: space-between;
/* sets both to space-between */
}
.container {
place-content: center flex-end;
/* wrapped lines on the cross axis are centered,
on the main axis items are aligned to the end of the flex container */
}
יישור פריטים בציר המחובר
בציר הצלב אפשר גם ליישר את הפריטים בתוך הקו הגמיש באמצעות align-items
ו-align-self
.
המרחב שזמין ליישור הזה תלוי בגובה של מאגר ה-Flex או של שורת ה-Flex במקרה של קבוצת פריטים ארוכה.
הערך הראשוני של align-self
הוא stretch
, ולכן פריטים גמישים בשורה נמתחים לגובה הפריט הגבוה ביותר כברירת מחדל.
כדי לשנות את זה, מוסיפים את המאפיין align-self
לאחד מהפריטים הגמישים.
.container {
display: flex;
}
.item1 {
align-self: flex-start;
}
כדי ליישר את הפריט, משתמשים באחד מהערכים הבאים:
flex-start
flex-end
center
stretch
baseline
בדמו הבא יש שורה אחת של פריטים גמישים עם flex-direction: row
.
הפריט האחרון מגדיר את הגובה של מיכל הגמיש.
הפריט הראשון מכיל את המאפיין align-self
עם הערך flex-start
.
אפשר לנסות לשנות את הערך של המאפיין הזה כדי לראות איך הוא זז במרחב שלו בציר העובר.
המאפיין align-self
חל על פריטים ספציפיים.
אפשר להחיל את המאפיין align-items
על קונטיינר הגמיש כדי להגדיר את כל המאפיינים הנפרדים של align-self
כקבוצה.
.container {
display: flex;
align-items: flex-start;
}
בהדגמה הבאה נסו לשנות את הערך של align-items
כדי ליישר קו עם כל הפריטים בציר הצלב כקבוצה.
למה אין justify-self ב-flexbox?
פריטים מסוג Flex פועלים כקבוצה בציר הראשי. לכן אין מושג של פיצול פריט ספציפי מהקבוצה הזו.
בפריסת רשת, המאפיינים justify-self
ו-justify-items
פועלים על הציר המוטבע כדי ליישר את הפריטים שבציר הזה בתוך אזור הרשת שלהם.
בגלל האופן שבו פריסות גמישות מתייחסות לפריטים כקבוצה, המאפיינים האלה לא מיושמים בהקשר של גמישות.
חשוב לדעת ש-flexbox פועל מצוין עם שוליים אוטומטיים.
אם אתם צריכים לפצל פריט אחד מקבוצה, או להפריד את הקבוצה לשתי קבוצות, תוכלו להשתמש בשוליים כדי לעשות זאת.
בדוגמה שמתחת לפריט האחרון, יש שוליים שמאליים של auto
.
השוליים האוטומטיים סופגים את כל השטח בכיוון שבו הם מוחלים.
המשמעות היא שהפריט נדחף שמאלה, וכך הקבוצות מחולקות.
איך למרכז פריט באופן אנכי ואופקי
אפשר להשתמש במאפייני היישור כדי למרכז פריט בתוך תיבה אחרת.
המאפיין justify-content
מיישר את הפריט בציר הראשי, שהוא השורה. המאפיין align-items
בציר החוצה.
.container {
width: 400px;
height: 300px;
display: flex;
justify-content: center;
align-items: center;
}
בדיקת ההבנה
בוחנים את הידע שלכם ב-Flexbox
.container { display: flex; direction: ltr; }
כדי ליישר אנכית באמצעות Flexbox, משתמשים ב-
.container { display: flex; direction: ltr; }
כדי ליישר אופקית באמצעות Flexbox, משתמשים ב-
.container { display: flex; direction: ltr; }
כברירת מחדל, פריטים גמישה מותאמים ל-stretch
. אם רוצים להשתמש בגודל התוכן לפריטי הצאצא, באיזה מהסגנונות הבאים צריך להשתמש?
justify-content: flex-start
align-content: start
content
מיישר קווים גמישים, לא יישור של פריטי צאצא.height: auto
align-items: flex-start