הפודקאסט של CSS – 001: The Box Model
נניח שיש לכם את קטע ה-HTML הבא:
<p>I am a paragraph of text that has a few words in it.</p>
לאחר מכן, כותבים עבורו את ה-CSS הבא:
p {
width: 100px;
height: 50px;
padding: 20px;
border: 1px solid;
}
התוכן מגיע ברוחב של 142 פיקסלים במקום ה-100 פיקסלים שציינתם, והוא מתנתק מהאלמנט. למה זה קורה?
מודל התיבה הוא הבסיס הבסיסי של CSS. אם תבינו איך פועל מודל התיבה, איך הוא מושפע מהיבטים אחרים של CSS, וחשוב גם איך לשלוט בו, תוכלו לכתוב CSS צפוי יותר.
חשוב לזכור שכל מה שמוצג על ידי CSS הוא תיבה, גם אם זו רק חלק מהטקסט, או שיש בה border-radius
שגורם לזה להיראות כמו עיגול.
תוכן ומידה
ההתנהגות של התיבות משתנה על סמך הערך שלהן ב-display
, המימדים שמוגדרים בהן והתוכן שהן מכילות. התוכן הזה יכול להיות טקסט פשוט או תיבות נוספות שנוצרו על ידי רכיבי צאצא. בכל מקרה, התוכן משפיע על גודל התיבה כברירת מחדל.
אפשר לשלוט בהגדרה הזו באמצעות גודל חיצוני, או להשתמש בגודל פנימי כדי לאפשר לדפדפן לקבל החלטות בהתאם לגודל התוכן.
הנה הדגמה בסיסית שמסבירה את ההבדל:
ההדגמה כוללת את המילים "CSS is a Awesome", בתיבה עם מידות קבועות ושוליים עבים. לתיבה יש רוחב מוגדר, לכן היא בגודל חיצוני.
המשמעות היא שהיא קובעת את הגודל של התוכן הצאצא. עם זאת, המילה "awesome" גדולה מדי לתיבה, ולכן היא גובלת מחוץ לתיבת הגבול של תיבת ההורה (נרחיב על כך בהמשך). דרך אחת למנוע את החריגה הזו היא לאפשר את גודל התיבה באופן פנימי על ידי אי-הגדרת הרוחב, או במקרה הזה, הגדרת הערך של width
ל-min-content
. מילת המפתח min-content
מורה שהתיבה
תחול רק ברוחב המינימלי הפנימי של התוכן שלה (המילה "מדהים"). כך התיבה תתאים את הטקסט בצורה מושלמת.
דוגמה מורכבת יותר, שמראה את ההשפעה של מידות שונות על תוכן אמיתי:
תוכלו להפעיל ולהשבית מידות פנימיות כדי לראות איך מידה חיצונית נותנת לכם יותר שליטה באמצעות מידה חיצונית ושינוי גודל פנימי נותנת לתוכן יותר שליטה. כדי לראות את האפקטים, עליך להוסיף לכרטיס כמה משפטים. אם לאמנט הזה יש מידות חיצוניות, יש מגבלה על כמות התוכן שאפשר להוסיף לפני הגלישה, אבל זה לא קורה כשמשנים את הגודל הפנימי.
כברירת מחדל, לאלמנט הזה יש width
ו-height
מוגדרים של 400px
לכל אחד.
המאפיינים האלה מציבים גבולות קפדניים לכל דבר בתוך האלמנט, שאותם מכבדים אלא אם התוכן גדול מדי לתיבה. כדי לראות זאת,
אפשר לשנות את הכיתוב שמתחת לתמונת הפרח למשהו גדול יותר
מגובה הקופסה.
מונח מפתח: גלישת טקסט מופיעה כשהתוכן גדול מדי לתיבה שבה הוא נמצא. ניתן לך לנהל את האופן שבו רכיב יטפל בתוכן בגלישה באמצעות המאפיין overflow
.
המעבר לשינוי גודל פנימי מאפשר לדפדפן לקבל החלטות בשבילכם על סמך גודל התוכן של הקופסה. במצב כזה יש סיכוי נמוך יותר להצגת נתונים, כי התיבה משתנה בהתאם לתוכן שלה.
חשוב לזכור שגודל פנימי הוא התנהגות ברירת המחדל בדפדפן, ובדרך כלל היא מספקת גמישות רבה יותר מאשר מידות חיצוניות.
האזורים של מודל התיבה
תיבות מורכבות מאזורים שונים של דגם ארגזים, שכולם עושים עבודה מסוימת.
תיבת התוכן היא האזור שבו נמצא התוכן. התוכן יכול לשלוט בגודל ההורה שלו, לכן בדרך כלל זה האזור בעל הגודל המשתנה ביותר.
התיבה בתוך המרווח מקיפה את תיבת התוכן, והיא המרחב שנוצר על ידי המאפיין padding
.
מכיוון שהמרווח הפנימי נמצא בתוך התיבה, הרקע של התיבה גלוי במרחב שהיא יוצרת.
אם מוגדרים בתיבה כללי אפשרויות נוספות, כמו overflow: auto
או overflow: scroll
, גם פסי הגלילה תופסים את השטח הזה.
התיבה של הגבולות מוקפת בתיבת המרווח הפנימי, והשטח שלה מוגדר על ידי הערך border
שיוצר את המסגרת החזותית לאלמנט. קצה הגבול של הרכיב הוא הגבול של מה שאפשר לראות.
האזור האחרון, תיבת השוליים, הוא הרווח שמסביב לתיבה, שמוגדר על ידי הכלל margin
של התיבה. גם מאפיינים כמו outline
ו-box-shadow
תופסים את השטח הזה, כי הם צבועים על גבי הרכיב ולא משפיעים על גודל התיבה. שינוי השדה outline-width
של 200px
בתיבה לא משנה דבר בתוך קצה הגבול.
אנלוגיה שימושית
מודל התיבה מורכב להבנה, ולכן הנה אנלוגיה למה שלמדת עד כה.
בתרשים הזה יש שלוש מסגרות לתמונות שמחוברות זו לזו על קיר. אלמנטים של התמונה הממוסגרת תואמים למודל התיבה באופן הבא:
- תיבת התוכן היא פריטי הגרפיקה.
- תיבת הגבולות היא לוח הקיבוע הלבן, בין המסגרת לגרפיקה.
- תיבת הגבולות היא המסגרת, שמספקת גבול מילולי של הגרפיקה.
- תיבת השוליים היא הרווח בין הפריימים.
- הצללית תופסת אותו שטח כמו תיבת השוליים.
ניפוי באגים במודל התיבה
כלי הפיתוח לדפדפן מספק תצוגה חזותית של חישובים של מודל קופסה בתיבה שנבחרה, וכך עוזרים לכם להבין איך מודל התיבה פועל ואיך הוא משפיע על האתר שבו אתם עובדים.
כדאי לנסות זאת בדפדפן שלכם:
- פותחים את כלי הפיתוח.
- בחירת רכיב.
- הצגת הכלי לניפוי באגים של דגם תיבה.
שליטה במודל הקופסה
כדי להבין איך לשלוט במודל התיבה, קודם כל צריך להבין מה קורה בדפדפן.
כל דפדפן מחיל גיליון סגנונות של סוכן משתמש על מסמכי HTML שמגדיר כיצד רכיבים אמורים להיראות ולפעול אם לא הוגדר להם CSS. ה-CSS בגיליונות הסגנונות של סוכני המשתמש משתנה בין דפדפנים, אבל הם מספקים ברירות מחדל הגיוניות כדי שיהיה קל יותר לקרוא את התוכן.
מאפיין אחד, גיליון הסגנונות של סוכן המשתמש מגדיר את display
ברירת המחדל של תיבה. לדוגמה, בתהליך רגיל, ערך ברירת המחדל של display
של רכיב <div>
הוא block
, ל-<li>
יש ערך ברירת מחדל display
של list-item
ול-<span>
ערך ברירת המחדל display
הוא inline
.
לרכיב inline
יש שוליים של חסימה, אבל רכיבים אחרים לא מכבדים אותו.
עם inline-block
, רכיבים אחרים מכבדים את שולי הבלוק, אבל הרכיב הראשון שומר על רוב דפוסי ההתנהגות שהיו לו כרכיב inline
.
פריט block
ממלא את השטח המוטבע הזמין כברירת מחדל, ואילו הרכיבים inline
ו-inline-block
גדולים כמו התוכן שלהם.
גיליון הסגנונות של סוכן המשתמש גם מגדיר את box-sizing
, שמציין בתיבה איך לחשב את גודל התיבה. כברירת מחדל, לכל הרכיבים יש את הסגנון הבא של סוכן משתמש: box-sizing: content-box;
. המשמעות היא שכשמגדירים מאפיינים כמו width
ו-height
, המאפיינים האלה חלים על תיבת התוכן. אם מגדירים את padding
ו-border
, הערכים האלה מתווספים לגודל תיבת התוכן.
בחינת ההבנה
בוחנים את הידע שלכם לגבי מאפיינים של גודל מודל קופסה שמשפיעים על המאפיינים.
.my-box { width: 200px; border: 10px solid; padding: 20px; }
מה הרוחב לדעתך של .my-box
?
200px
מתאים אם בתיבה היה box-sizing: border-box
.
הרוחב בפועל של התיבה הזו הוא 260 פיקסלים.
מכיוון שה-CSS משתמש בברירת המחדל box-sizing: content-box
, הרוחב המוחל הוא רוחב התוכן, ו-padding
ו-border
בשני הצדדים מתווספים אליו. 200 פיקסלים לתוכן + 40 פיקסלים של מרווח פנימי + 20 פיקסלים של גבול יוצרים רוחב גלוי כולל של 260 פיקסלים.
כדי לשנות את זה, אפשר לציין את המידה של border-box
:
.my-box {
box-sizing: border-box;
width: 200px;
border: 10px solid;
padding: 20px;
}
מודל התיבה החלופי מורה ל-CSS להחיל את width
על תיבת הגבולות במקום על תיבת התוכן. פירוש הדבר הוא שה-border
וה-padding
שלנו נדחים פנימה, כך שכאשר מגדירים את .my-box
לרוחב 200px
, הוא למעשה מוצג ברוחב 200px
.
בהדגמה האינטראקטיבית הבאה תוכלו לבדוק איך זה עובד. כשמחליפים את המצב של הערך box-sizing
, באזור הכחול יופיע איזה CSS מוחל בתוך התיבה.
*,
*::before,
*::after {
box-sizing: border-box;
}
כלל ה-CSS הזה בוחר את כל הרכיב במסמך ואת כל פסאודו רכיב ::before
ו-::after
, ומחיל את box-sizing: border-box
.
המשמעות היא שבכל רכיב נעשה עכשיו שימוש במודל התיבה החלופי הזה.
מכיוון שמודל התיבה החלופי יכול להיות צפוי יותר, מפתחים מוסיפים את הכלל הזה לאיפוסים ולנרמולים, כמו הכלל הזה.