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