ארבע השכבות של כל תיבה
כל אלמנט בעמוד מצויר כמלבן שבנוי מארבע שכבות, מבפנים החוצה:
- תוכן (content): הטקסט, התמונה או אלמנטי הילד, בגודל שנקבע על ידי
widthו-height. - Padding: רווח בתוך התיבה, בין התוכן לגבול. רואים בו את הרקע של האלמנט.
- גבול (border): הקו סביב ה-padding.
- Margin: רווח מחוץ לגבול שדוחף תיבות אחרות הרחק. תמיד שקוף.
בדוגמה לכל שכבה יש צבע משלה: תוכן כחול, padding ירוק, גבול כהה, ואזור כתום סביב התיבה שהוא ה-margin (מצויר על ידי עוטף, כי ה-margin עצמו שקוף).
הקו שמתחת לתיבה נמדד על ידי הדפדפן: 160 + 20 + 20 + 10 + 10 = 220px. ה-margin מוסיף עוד 24px מכל צד, אבל הוא מחוץ לתיבה, ולכן הוא לא חלק מה-220.
חישוב רוחב: content-box מול border-box
כברירת מחדל (box-sizing: content-box), width קובע רק את התוכן. ה-padding והגבול מתווספים מעליו, כך שהתיבה יוצאת רחבה יותר מהמספר שכתבתם. עם box-sizing: border-box, width הוא התיבה כולה, והתוכן מתכווץ כדי לפנות מקום ל-padding ולגבול.
content-box (ברירת מחדל) | border-box | |
|---|---|---|
width פירושו | התוכן | תוכן + padding + גבול |
width: 200px; padding: 20px; border: 5px | ברוחב 250px | ברוחב 200px |
| אזור התוכן במקרה הזה | 200px | 150px |
| Margin | בחוץ, לא נספר | בחוץ, לא נספר |
איפוס ה-border-box
מכיוון ש-border-box גורם לגדלים להסתכם נכון, כמעט כל גיליון סגנונות מודרני מתחיל בכלל הזה:
*,
*::before,
*::after {
box-sizing: border-box;
}
זה חשוב במיוחד עם אחוזים. שתי עמודות עם width: 50% ו-padding לא נכנסות בשורה אחת תחת content-box, כי כל אחת היא 50% ועוד ה-padding שלה:
(הערות ה-HTML מסירות את הרווח בין עמודות ה-inline-block, שאחרת היה מוסיף כמה פיקסלים.)
לראות את ה-box model ב-DevTools
כל דפדפן מצייר בשבילכם את ה-box model. לחצו לחיצה ימנית על אלמנט, בחרו Inspect, ופתחו את הלשונית Computed (או Layout ב-Firefox): תרשים מציג את גודל התוכן במרכז, מוקף בערכי ה-padding, הגבול וה-margin. ריחוף מעל אלמנט בחלונית Elements גם צובע את העמוד: תוכן בכחול, padding בירוק, margin בכתום.
לתיבות inline יש כללים אחרים
ה-box model שלמעלה מתאר תיבות block כמו <div> ו-<p>. אלמנטי inline כמו <span>, <a> ו-<strong> נשברים בתוך שורת טקסט, ומתייחסים לרווח אנכי אחרת:
| מאפיין | על אלמנט inline |
|---|---|
width, height | מתעלמים ממנו |
| padding, גבול ו-margin אופקיים | מוחלים, ודוחפים שכנים הצידה |
| padding וגבול אנכיים | מצוירים, אבל לא דוחפים את השורות שמעל ומתחת |
| margin אנכי | מתעלמים ממנו |
display: inline-block נותן לאלמנט בתוך שורה את ה-box model המלא: הרוחב, הגובה, ה-padding וה-margin שלו תופסים כולם מקום. ראו CSS padding ו-CSS margin לכל שכבה בפירוט.
טעויות נפוצות
- הוספת padding לתיבה ברוחב קבוע ותהייה למה היא גדלה. תחת
content-box, ה-padding והגבול מתווספים ל-width. השתמשו ב-border-box. - ציפייה שה-margin יקבל את צבע הרקע. ה-margin תמיד שקוף; השתמשו ב-padding לרווח צבוע.
- הגדרת
heightאו margin אנכי על אלמנט inline. שום דבר לא קורה; השתמשו ב-display: inline-blockאוblock. - שכחה של הגבולות בחישוב. גבול של 1px על אלמנט עם
width: 100%הופך אותו לרחב מדי ב-2px תחתcontent-box, מה שעלול לגרום לפס גלילה אופקי. - בלבול בין margin ל-padding. בקצרה: padding נמצא בתוך הגבול, margin מחוצה לו. העמוד margin מול padding מציג אותם זה לצד זה.
שאלות נפוצות
מה זה CSS box model?
הכלל שלפיו כל אלמנט מוצג כתיבה מלבנית של ארבע שכבות: התוכן, ה-padding סביבו, הגבול סביב ה-padding, וה-margin מחוץ לגבול. רוחב, גובה ומרווחים ב-CSS נקבעים כולם על השכבות האלה.
מה עושה box-sizing: border-box?
הוא גורם ל-width ול-height לכלול את ה-padding והגבול. תיבה עם width: 200px, עם padding: 20px וגבול של 5px היא אז ברוחב 200px בדיוק, ואזור התוכן מתכווץ ל-150px כדי להיכנס. ברירת המחדל, content-box, מוסיפה את ה-padding והגבול מעל, ונותנת 250px.
איך מחושב הרוחב הכולל של אלמנט?
עם ברירת המחדל content-box: רוחב + padding שמאלי וימני + גבול שמאלי וימני. עם border-box: רק width. ה-margin נמצא מחוץ לתיבה בשני המקרים, כך שהוא מוסיף למקום שהאלמנט תופס, לא לרוחב שלו עצמו.
האם margin הוא חלק מה-box model?
כן, הוא השכבה החיצונית ביותר, אבל הוא תמיד שקוף ואף פעם לא נספר ברוחב או ברקע של האלמנט עצמו. הוא רק דוחף תיבות שכנות הרחק.
כדאי להגדיר box-sizing: border-box על הכול?
רוב הפרויקטים עושים את זה, עם *, *::before, *::after { box-sizing: border-box; } בראש גיליון הסגנונות. כך רוחב באחוזים ו-padding מסתכמים כמו שאנשים מצפים, ו-frameworks כמו Bootstrap ו-Tailwind מגיעים עם אותו איפוס.