קו מוצרי Flexbox

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
כברירת מחדל, flexbox יתאים את הפריטים לשורה ויציב אותם בתחילת השורה. כשהתכונה 'התאמה לעמודה' מופעלת, המערכת תמשיך ליצור שורות כדי שהילדים יוכלו לנוע ביניהן.
column
הגדרת flex-direction לעמודה היא דרך מצוינת להצמיד רכיבים, אבל זה לא ערך ברירת המחדל.

כברירת מחדל, קונטיינר Flex עוטף צאצאים.

true
צריך להפעיל את האריזה.
false
שימוש ב-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

לרשימת הערכים המלאה ב-MDN

בדמו הבא יש שורה אחת של פריטים גמישים עם 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
כן, אנחנו רוצים ליישר אותם אנכית ל'חלק העליון' או להתחלה, וכך להסיר את ערך ברירת המחדל של מתיחה ולהשתמש במקום זאת בגובה התוכן.

משאבים