חיפוש

הצמדת אלמנט לתחתית קונטיינר באמצעות flex-grow

כמעט בכל אתר שאני מפתח יש שימוש בסוג של גריד כשהאלמנטים בגריד הם בעלי גובה זהה. הכל עובד יפה עד שהלקוח מעוניין להוסיף טקסט באורך שונה בכל אחד מהאלמנטים.

פתרון אחד הוא להגביל את כמות התווים שמוצגים בכל אלמנט, כמו בדוגמה הבאה:

כותרת

לורם איפסום דולור סיט אמט, קונסקטורר אדיפיסינג אלית גולר מונפרר סוברט לורם שבצק יהול, לכנוץ בעריר גק ליץ, ושבעגט ליבם סולגק קלאצי קולורס מונפרד אדנדום סילקוף, מרגשי ומרגשח. עמחליף קונסקטורר אדיפיסינג אלית.

כפתור
כותרת

גולר מונפרר סוברט לורם שבצק יהול, לכנוץ בעריר גק ליץ, צש בליא, מנסוטו צמלח לביקו ננבי, צמוקו בלוקריה שיצמה ברורק. הועניב היושבב שערש שמחויט - שלושע ותלברו חשלו שעותלשך וחאית נובש ערששף

כפתור

ומה הבעיה עם זה?

הגישה הזו מוגבלת מאוד. ברגע שהלקוח מוסיף תמונה לכרטיס אחד או כותב יותר טקסט באחר, הכפתורים בתחתית מפסיקים להיות מיושרים – למרות ש-Flexbox שומר על גובה זהה לכרטיסים:

כותרת

לורם איפסום דולור סיט אמט, קונסקטורר אדיפיסינג אלית גולר מונפרר סוברט לורם שבצק יהול, לכנוץ בעריר גק ליץ, ושבעגט ליבם. דולור סיט אמט, קונסקטורר אדיפיסינג אלית גולר מונפרר סוברט לורם שבצק יהול, לכנוץ בעריר גק ליץ, ושבעגט ליבם סולגק.

כפתור
כותרת

לורם איפסום דולור סיט אמט, קונסקטורר אדיפיסינג אלית גולר מונפרר סוברט לורם שבצק יהול, לכנוץ בעריר גק ליץ, ושבעגט ליבם סולגק לכנוץ בעריר גק ליץ לורפ אי.

כפתור

Flexbox מספק פתרון נקי למצבים האלה. ללקוח תהיה אפשרות להכניס כל תוכן שירצה, והכפתור יישאר צמוד לתחתית.

Flex Containers מחשבים את השטח הפנוי ומאפשרים גמישות גבוהה יותר. באמצעות התכונה flex-grow אפשר ליצור את האפקט הבא בקלות:

כותרת

לורם איפסום דולור סיט אמט, קונסקטורר אדיפיסינג אלית גולר מונפרר סוברט לורם שבצק יהול, לכנוץ בעריר גק ליץ, ושבעגט ליבם. דולור סיט אמט, קונסקטורר אדיפיסינג אלית גולר מונפרר סוברט לורם שבצק יהול, לכנוץ בעריר גק ליץ, ושבעגט ליבם סולגק.

כפתור
כותרת

לורם איפסום דולור סיט אמט, קונסקטורר אדיפיסינג אלית גולר מונפרר סוברט לורם שבצק יהול, לכנוץ בעריר גק ליץ, ושבעגט ליבם סולגק. ושבעגט ליבם סולגק לכנוץ בעריר גק ליץ לורפ אי.

כפתור

הכפתור נשאר צמוד למטה בלי קשר לכמות התוכן. נתקלתי בהמון מפתחים שמשתמשים בטכניקות מיושנות כמו מיקום אבסולוטי או min-height, אבל flex-grow פותר את זה בצורה הרבה יותר נקייה.

אפשר להשיג את אותה תוצאה גם עם margin-top: auto על הכפתור. שתי הגישות עובדות – margin-top: auto דוחף את האלמנט למטה על ידי צריכת השטח הפנוי מעליו, בעוד flex-grow על האלמנט שלפניו מרחיב אותו כדי למלא את הפער. אראה כאן את הגישה של flex-grow כי היא מפורשת יותר.

הפתרון – שימוש ב flex-grow

בואו נראה שלב אחרי שלב איך מגיעים לתוצאה.

שלב 1 – כתיבת ה Markup

יצרתי קונטיינר בסיסי שמכיל מספר כרטיסים. כל כרטיס מכיל כותרת, תמונה אופציונלית, טקסט וכפתור.

<div class="flex-alignment">
    <div>
        <h2>כותרת</h2>
        <p>לורם איפסום דולור סיט אמט, קונסקטורר אדיפיסינג אלית גולר מונפרר סוברט לורם שבצק יהול, לכנוץ בעריר גק ליץ, ושבעגט ליבם. דולור סיט אמט, קונסקטורר אדיפיסינג אלית גולר מונפרר סוברט לורם שבצק יהול, לכנוץ בעריר גק ליץ, ושבעגט ליבם סולגק.
        </p>
        <a href="">כפתור</a>
    </div>
    <div>
        <h2>כותרת</h2>
        <img src="https://via.placeholder.com/450x200?text=Nice+Picture"/>
        <p>לורם איפסום דולור סיט אמט, קונסקטורר אדיפיסינג אלית גולר מונפרר סוברט לורם שבצק יהול, לכנוץ בעריר גק ליץ, ושבעגט ליבם סולגק.</p>
        <a href="">כפתור</a>
    </div>
</div>

שלב 2 – קביעתו כ-Flex Container

כפי שהסברתי במדריך ה-Flexbox שלי, הדבר היחיד שצריך לעשות כדי ליצור Flex Container הוא להוסיף display: flex לקונטיינר. זה נותן לנו שליטה על האלמנטים שבתוכו.

.flex-alignment {
    display: flex;
    flex-wrap: wrap;
    justify-content: space-between;
}

ה"ילדים" כאן הם שני ה-<div> שנמצאים בתוך הקונטיינר עם הקלאס .flex-alignment.

שלב 3 – הגדרת כל כרטיס כ-Flex Container בפני עצמו

הוספנו display: flex ו-flex-direction: column לכל כרטיס כדי שיימתח ורטיקלית ויקבל גובה זהה בכל שורה. עכשיו יש לנו שליטה באלמנטים שבתוך כל כרטיס – הכותרת, התמונה, הטקסט והכפתור:

.flex-alignment > div {
    display: flex;
    width: calc(50% - 10px);
    flex-direction: column;
    padding: 15px;
    box-sizing: border-box;
}

ערך ה-width משתנה בהתאם למספר הכרטיסים שאתם רוצים בכל שורה. הנה אגב פוסט מעניין על יצירת גריד רספונסיבי ללא Media Queries.

שלב 4 – הצמדת הכפתור לתחתית

התכונה flex-grow מגדירה את היכולת של Flex Item לגדול ביחס לאלמנטים האחרים באותו Flex Container:

.flex-alignment p {
    flex-grow: 1;
}

קבענו flex-grow: 1 על אלמנט ה-<p> שמכיל את הטקסט. זה אומר לו להתרחב ולמלא את כל השטח הנותר.

מכיוון שאנחנו משתמשים ב-flex-direction: column, הפסקה גדלה ורטיקלית – ודוחפת את הכפתור מתחתיה לתחתית הכרטיס.

האלטרנטיבה: margin-top: auto

קיימת דרך פשוטה אפילו יותר להשיג את אותה תוצאה. במקום להשתמש ב-flex-grow על הפסקה, מוסיפים margin-top: auto ישירות על הכפתור:

.flex-alignment a {
    margin-top: auto;
}

זה עובד כי auto margins ב-Flex Container סופגים את כל השטח הפנוי. ה-margin העליון של הכפתור מתרחב כדי למלא את הפער, ודוחף את הכפתור לתחתית.

שתי השיטות מייצרות תוצאה זהה. אני מעדיף flex-grow כשאני רוצה שאזור הטקסט ימלא את הכרטיס ויזואלית, ו-margin-top: auto כשאני רק צריך את הכפתור צמוד למטה עם מינימום CSS.

שאלות נפוצות

שאלות נפוצות על הצמדת אלמנטים לתחתית Flex Container:

מה בדיוק עושה flex-grow: 1?
flex-grow: 1 אומר ל-Flex Item לספוג את כל השטח הפנוי בתוך ה-Flex Container. כשמשתמשים ב-flex-direction: column, האלמנט מתרחב ורטיקלית ודוחף את האלמנטים שמתחתיו לתחתית הקונטיינר.
מה עדיף: flex-grow או margin-top: auto?
שתי הגישות משיגות את אותה תוצאה. margin-top: auto פשוט יותר - שורה אחת על הכפתור. flex-grow: 1 על אלמנט הטקסט מפורש יותר וגם גורם לאזור הטקסט למלא את הכרטיס ויזואלית. בחרו מה שמתאים לכם.
האם צריך flex-direction: column כדי שזה יעבוד?
כן. כברירת מחדל, Flex Containers מסדרים אלמנטים אופקית (flex-direction: row). כדי להצמיד אלמנט לתחתית צריך שהאלמנטים יהיו מסודרים אנכית, ולכן flex-direction: column הכרחי על קונטיינר הכרטיס.
למה לא להשתמש ב-position: absolute כדי להצמיד את הכפתור?
מיקום אבסולוטי מוציא את האלמנט מהזרימה הרגילה. זה אומר שצריך להוסיף padding-bottom קבוע לכרטיס כדי שהכפתור לא יחפוף תוכן. עם flex-grow או margin-top: auto הפריסה מתכווננת אוטומטית - בלי מספרים קסומים.
אפשר להשתמש ב-CSS Grid במקום Flexbox לזה?
כן. עם CSS Grid אפשר להשתמש ב-grid-template-rows כדי להגדיר גדלי שורות, או להחיל align-self: end על הכפתור. אבל ללייאוטים פשוטים של כרטיסים שבהם רק צריך להצמיד אלמנט אחד למטה, Flexbox עם flex-grow או margin-top: auto פשוט יותר.
הטכניקה עובדת עם יותר משני כרטיסים בשורה?
בהחלט. מספר הכרטיסים בשורה נקבע לפי התכונה width של כל כרטיס (למשל, calc(33.33% - 10px) עבור שלושה בשורה). טכניקת ההצמדה עם flex-grow עובדת בדיוק אותו דבר בלי קשר למספר הכרטיסים בשורה.

סיכום

התכונה flex-grow היא אחת מתכונות ה-Flexbox השימושיות ביותר ללייאוטים אמיתיים. על ידי הוספת flex-grow: 1 לאזור התוכן של כרטיס, אתם דוחפים את הכפתור (או כל אלמנט אחרון) לתחתית – בלי מיקום אבסולוטי ובלי גבהים קבועים.

אם אתם רוצים את הפתרון הכי פשוט, margin-top: auto על האלמנט האחרון עושה את אותו הדבר בשורה אחת.

דיון ותגובות
2 תגובות  ]
  • גאיבראש 3 דצמבר 2019, 15:03

    מדריך מעולה!

    שיטה נוספת היא לתת לאלמנט האחרון (הכפתור) margin-top : auto…

השאירו תגובה

הוסיפו קוד באמצעות הכפתורים מטה. למשל, בכדי להוסיף PHP לחצו על הכפתור PHP והוסיפו את הקוד בתוך השורטקוד. מצאתם שגיאה בפוסט? עדכנו אותנו...

Savvy WordPress Development official logo