The CSS Podcast - 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;
}
הרוחב של התוכן הוא 142px, במקום 100px שציינתם, והוא חורג מהרכיב. למה זה קורה?
מודל התיבה הוא בסיס מרכזי ב-CSS. הבנה של אופן הפעולה של מודל התיבה, איך הוא מושפע מהיבטים אחרים של CSS, וחשוב מכך, איך אפשר לשלוט בו, יכולה לעזור לכם לכתוב CSS צפוי יותר.
חשוב לזכור שכל מה שמוצג על ידי CSS הוא תיבה, גם אם מדובר רק בטקסט או שיש לו border-radius
שגורם לו להיראות כמו עיגול.
תוכן וגודל
ההתנהגות של התיבות משתנה בהתאם לערך display
שלהן, למידות שהוגדרו להן ולתוכן שהן מכילות. התוכן הזה יכול להיות טקסט פשוט, או תיבות נוספות שנוצרו על ידי רכיבי צאצא. בכל מקרה, כברירת מחדל התוכן משפיע על גודל התיבה.
אפשר לשלוט בזה באמצעות הגדרת גודל חיצונית, או להשתמש בהגדרת גודל פנימית כדי לאפשר לדפדפן לקבל החלטות על סמך גודל התוכן.
הנה הדגמה בסיסית שמסבירה את ההבדל:
בהדגמה מופיעות המילים CSS is awesome (CSS זה מדהים) בתיבה עם מידות קבועות ומסגרת עבה. מכיוון שהרוחב של התיבה מוגדר, הגודל שלה נקבע באופן חיצוני.
כלומר, הוא שולט בגודל של התוכן שמוצג בתוכו. עם זאת, המילה awesome גדולה מדי בשביל התיבה, ולכן היא גולשת אל מחוץ לתיבת הגבול של תיבת האב (עוד על כך בהמשך). אחת הדרכים למנוע את החריגה הזו היא לא להגדיר את הרוחב של התיבה, או במקרה הזה, להגדיר את width
ל-min-content
. מילת המפתח min-content
אומרת לתיבה להיות ברוחב המינימלי הפנימי של התוכן שלה (המילה awesome). כך התיבה תתאים בדיוק לטקסט.
דוגמה מורכבת יותר שממחישה את ההשפעה של גדלים שונים על תוכן אמיתי:
אפשר להפעיל ולכבות את ההגדרה של גודל פנימי כדי לראות איך גודל חיצוני נותן לכם יותר שליטה, ואיך גודל פנימי נותן לתוכן יותר שליטה. כדי לראות את האפקטים, מוסיפים כמה משפטים של טקסט לכרטיס. כשהגודל של הרכיב הזה מוגדר חיצונית, יש מגבלה על כמות התוכן שאפשר להוסיף לפני שמתרחשת גלישה, אבל זה לא קורה כשהגודל מוגדר פנימית.
כברירת מחדל, לרכיב הזה מוגדרים width
וheight
של 400px
כל אחד.
המידות האלה מגדירות גבולות ברורים לכל מה שנמצא בתוך הרכיב, והן נשמרות אלא אם התוכן גדול מדי בשביל התיבה. כדי לראות את זה בפעולה, אפשר לשנות את הכיתוב מתחת לתמונה של הפרח למשהו שגבוה יותר מהתיבה.
מונח מרכזי: גלישה מתרחשת כשהתוכן גדול מדי בשביל התיבה שבה הוא נמצא. אפשר לנהל את האופן שבו רכיב מטפל בתוכן שגולש מהגבולות שלו באמצעות המאפיין overflow
.
כשעוברים לשימוש בגודל טבעי, הדפדפן יכול לקבל החלטות בשבילכם על סמך גודל התוכן של התיבה. כך הסיכוי לגלישה קטן משמעותית כי התיבה משנה את הגודל שלה בהתאם לתוכן.
חשוב לזכור שגודל פנימי הוא התנהגות ברירת המחדל של הדפדפן, ובדרך כלל הוא מספק הרבה יותר גמישות מאשר גודל חיצוני.
האזורים של מודל התיבה
התיבות מורכבות מאזורים נפרדים של מודל התיבה, שלכל אחד מהם יש תפקיד ספציפי.
תיבת התוכן היא האזור שבו התוכן נמצא. התוכן יכול לשלוט בגודל של רכיב האב שלו, ולכן זה בדרך כלל האזור שגודלו הכי משתנה.
תיבת הריווח הפנימי מקיפה את תיבת התוכן, והיא הרווח שנוצר על ידי המאפיין padding
.
הריווח הפנימי נמצא בתוך התיבה, ולכן הרקע של התיבה גלוי ברווח שנוצר.
אם הוגדרו לתיבה כללי גלישה, כמו overflow: auto
או overflow: scroll
, גם פסי הגלילה תופסים את המקום הזה.
תיבת הגבול מקיפה את תיבת הריפוד, והמרחב שלה מוגדר על ידי הערך border
, שיוצר מסגרת חזותית לרכיב. קצה הגבול של הרכיב הוא הגבול של מה שאתם יכולים לראות.
האזור האחרון, תיבת השוליים, הוא הרווח מסביב לתיבה, שמוגדר על ידי כלל margin
של התיבה. גם מאפיינים כמו outline
ו-box-shadow
תופסים את המקום הזה כי הם מצוירים מעל הרכיב ולא משפיעים על גודל התיבה. שינוי outline-width
של 200px
בתיבה לא משנה שום דבר בתוך קצה הגבול.
אנלוגיה שימושית
מודל התיבה הוא מורכב להבנה, אז הנה אנלוגיה שתעזור לכם להבין את מה שלמדתם עד עכשיו.

בתרשים הזה, יש שלוש מסגרות לתמונות שמורכבות זו לצד זו על קיר. הרכיבים של התמונה הממוסגרת תואמים למודל התיבה באופן הבא:
- תיבת התוכן היא יצירת האומנות.
- המסגרת הפנימית היא לוח ההדבקה הלבן, בין המסגרת ליצירת האומנות.
- תיבת הגבול היא המסגרת, והיא מספקת גבול מילולי ליצירת האומנות.
- תיבת השוליים היא הרווח בין המסגרות.
- הצל תופס את אותו המקום כמו תיבת השוליים.
ניפוי באגים של מודל התיבה
הכלים למפתחים בדפדפן מספקים הדמיה של החישובים של מודל התיבה של תיבה נבחרת. כך אפשר להבין איך מודל התיבה עובד ואיך הוא משפיע על האתר שעליו עובדים.
כדי לנסות את זה ב-Chrome:
- פותחים את כלי הפיתוח.
- בוחרים רכיב.
- הצגת הכלי לניפוי באגים של מודל התיבה.
שליטה במודל התיבה
כדי להבין איך לשלוט במודל התיבה, קודם צריך להבין מה קורה בדפדפן.
כל דפדפן מחיל גיליון סגנונות של סוכן משתמש על מסמכי HTML. גיליון הסגנונות מגדיר איך האלמנטים צריכים להיראות ולהתנהג, אם לא הוגדר להם CSS. ה-CSS בגיליונות הסגנונות של סוכן המשתמש משתנה בהתאם לדפדפן, אבל לכל דפדפן יש הגדרות ברירת מחדל שמקלות על קריאת התוכן.
גיליון הסגנונות של סוכן המשתמש מגדיר את ערך ברירת המחדל של רכיבים שמקבלים את הערך
display
. לדוגמה, ערך ברירת המחדל של display
באלמנט <div>
הוא block
, ערך ברירת המחדל של display
באלמנט <li>
הוא list-item
, וערך ברירת המחדל של display
באלמנט <span>
הוא 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
.
הרוחב בפועל של התיבה הזו הוא 260px.
מכיוון ש-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
.
המשמעות היא שכל רכיב משתמש עכשיו במודל התיבה החלופי הזה.
מודל התיבה החלופי יכול להיות צפוי יותר, ולכן מפתחים מוסיפים את הכלל הזה לאיפוסים ולנורמליזציות, כמו זה.