כמעט בכל אתר שאני מפתח יש שימוש בסוג של גריד כשהאלמנטים בגריד הם בעלי גובה זהה. הכל עובד יפה עד שהלקוח מעוניין להוסיף טקסט באורך שונה בכל אחד מהאלמנטים.
פתרון אחד הוא להגביל את כמות התווים שמוצגים בכל אלמנט, כמו בדוגמה הבאה:
לורם איפסום דולור סיט אמט, קונסקטורר אדיפיסינג אלית גולר מונפרר סוברט לורם שבצק יהול, לכנוץ בעריר גק ליץ, ושבעגט ליבם סולגק קלאצי קולורס מונפרד אדנדום סילקוף, מרגשי ומרגשח. עמחליף קונסקטורר אדיפיסינג אלית.
כפתורגולר מונפרר סוברט לורם שבצק יהול, לכנוץ בעריר גק ליץ, צש בליא, מנסוטו צמלח לביקו ננבי, צמוקו בלוקריה שיצמה ברורק. הועניב היושבב שערש שמחויט - שלושע ותלברו חשלו שעותלשך וחאית נובש ערששף
כפתורומה הבעיה עם זה?
הגישה הזו מוגבלת מאוד. ברגע שהלקוח מוסיף תמונה לכרטיס אחד או כותב יותר טקסט באחר, הכפתורים בתחתית מפסיקים להיות מיושרים – למרות ש-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 Item לספוג את כל השטח הפנוי בתוך ה-Flex Container. כשמשתמשים ב-flex-direction: column, האלמנט מתרחב ורטיקלית ודוחף את האלמנטים שמתחתיו לתחתית הקונטיינר.margin-top: auto פשוט יותר - שורה אחת על הכפתור. flex-grow: 1 על אלמנט הטקסט מפורש יותר וגם גורם לאזור הטקסט למלא את הכרטיס ויזואלית. בחרו מה שמתאים לכם.flex-direction: row). כדי להצמיד אלמנט לתחתית צריך שהאלמנטים יהיו מסודרים אנכית, ולכן flex-direction: column הכרחי על קונטיינר הכרטיס.padding-bottom קבוע לכרטיס כדי שהכפתור לא יחפוף תוכן. עם flex-grow או margin-top: auto הפריסה מתכווננת אוטומטית - בלי מספרים קסומים.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 על האלמנט האחרון עושה את אותו הדבר בשורה אחת.


מדריך מעולה!
שיטה נוספת היא לתת לאלמנט האחרון (הכפתור) margin-top : auto…
אמת! תודה על השיתוף… עדכנתי את הפוסט בהתאם 🙂