לדלג לתוכן

1.2 מודל הקופסה הרצאה

מודל הקופסה - box model

הרעיון הבסיסי ביותר ב-CSS הוא שכל אלמנט ב-HTML הוא קופסה. לא משנה אם זה כותרת, פסקה, תמונה או div - הדפדפן מתייחס לכל דבר כקופסה מלבנית.

כל קופסה מורכבת מארבע שכבות, מבפנים החוצה:

  1. תוכן - content - הטקסט, התמונה או כל מה שבתוך האלמנט
  2. ריפוד - padding - מרווח פנימי בין התוכן לגבול
  3. גבול - border - המסגרת של הקופסה
  4. שוליים - margin - מרווח חיצוני בין הקופסה לאלמנטים אחרים

חשבו על זה כמו תמונה ממוסגרת:
- התמונה עצמה היא ה-content
- הפספרטו (הרקע הלבן סביב התמונה) הוא ה-padding
- המסגרת היא ה-border
- המרחק בין המסגרת לקיר הוא ה-margin

תוכן - content

התוכן הוא החלק הפנימי ביותר של הקופסה. אנחנו שולטים בגודל שלו עם width ו-height:

.box {
    width: 300px;
    height: 200px;
}
  • אם לא מגדירים width, אלמנטי block תופסים את כל הרוחב הזמין
  • אם לא מגדירים height, הגובה נקבע אוטומטית לפי התוכן

ריפוד - padding

הריפוד יוצר מרווח בין התוכן לגבול. הוא מקבל את צבע הרקע של האלמנט.

.box {
    /* padding on all four sides */
    padding: 20px;

    /* padding for each side separately */
    padding-top: 10px;
    padding-right: 20px;
    padding-bottom: 10px;
    padding-left: 20px;
}

דוגמה ויזואלית - ההבדל עם ובלי padding:

/* without padding - text touches the border */
.no-padding {
    background-color: lightblue;
    border: 2px solid navy;
}

/* with padding - text has breathing room */
.with-padding {
    background-color: lightblue;
    border: 2px solid navy;
    padding: 20px;
}

גבול - border

הגבול הוא המסגרת של הקופסה. הוא מוגדר על ידי שלושה מאפיינים: עובי, סגנון וצבע.

.box {
    /* shorthand: width style color */
    border: 2px solid black;

    /* or each property separately */
    border-width: 2px;
    border-style: solid;
    border-color: black;
}

סגנונות גבול נפוצים:

.solid-border {
    border: 2px solid black;    /* solid line */
}

.dashed-border {
    border: 2px dashed gray;    /* dashes */
}

.dotted-border {
    border: 2px dotted red;     /* dots */
}

.double-border {
    border: 4px double navy;    /* double line */
}

.no-border {
    border: none;               /* no border */
}

אפשר גם להגדיר גבול לכל צד בנפרד:

.box {
    border-top: 3px solid red;
    border-right: 1px dashed blue;
    border-bottom: 3px solid red;
    border-left: 1px dashed blue;
}

/* common pattern: bottom border only (like underline) */
.underlined {
    border: none;
    border-bottom: 2px solid #333;
}

שוליים - margin

השוליים יוצרים מרווח מחוץ לגבול, בין האלמנט לאלמנטים שמסביבו. השוליים תמיד שקופים.

.box {
    /* margin on all four sides */
    margin: 20px;

    /* margin for each side separately */
    margin-top: 10px;
    margin-right: 20px;
    margin-bottom: 30px;
    margin-left: 20px;
}

מרכוז אופקי עם margin auto

אחד השימושים הנפוצים ביותר של margin הוא מרכוז אלמנט אופקית:

.centered-box {
    width: 600px;
    margin: 0 auto;
}
  • margin: 0 auto אומר: 0 למעלה ולמטה, auto לשמאל ולימין
  • auto מחלק את המרווח הנותר שווה בשווה בין שני הצדדים
  • חשוב: זה עובד רק אם לאלמנט יש width מוגדר (אחרת הוא תופס את כל הרוחב ואין מה למרכז)

קיצורים - shorthand notation

ל-padding ול-margin יש תחביר מקוצר שחוסך הרבה שורות:

/* 1 value: applies to ALL sides */
padding: 20px;
/* top=20, right=20, bottom=20, left=20 */

/* 2 values: vertical | horizontal */
padding: 10px 20px;
/* top=10, right=20, bottom=10, left=20 */

/* 3 values: top | horizontal | bottom */
padding: 10px 20px 30px;
/* top=10, right=20, bottom=30, left=20 */

/* 4 values: top | right | bottom | left (clockwise) */
padding: 10px 20px 30px 40px;
/* top=10, right=20, bottom=30, left=40 */
  • הסדר הוא תמיד בכיוון השעון: למעלה, ימין, למטה, שמאל
  • עם 2 ערכים, הראשון הוא למעלה+למטה והשני שמאל+ימין
  • עם 3 ערכים, הראשון למעלה, השני שמאל+ימין, השלישי למטה
  • זה בדיוק אותו דבר עבור margin

box-sizing - החלק הכי חשוב

כאן מגיע אחד הנושאים שהכי מבלבלים מתחילים. יש שתי דרכים לחשב את הגודל של קופסה:

content-box (ברירת מחדל)

.box {
    box-sizing: content-box; /* this is the default */
    width: 300px;
    padding: 20px;
    border: 5px solid black;
}

מה הרוחב האמיתי של הקופסה הזו?
- content: 300px
- padding left: 20px + padding right: 20px = 40px
- border left: 5px + border right: 5px = 10px
- סה"כ: 350px

כלומר, ב-content-box, ה-width מתייחס רק לתוכן. ה-padding וה-border מתווספים על הרוחב שהגדרנו. זה מעצבן כי אם הגדרנו width של 300px, האלמנט בפועל תופס 350px.

border-box (מה שאנחנו רוצים)

.box {
    box-sizing: border-box;
    width: 300px;
    padding: 20px;
    border: 5px solid black;
}

מה הרוחב האמיתי כאן?
- סה"כ: 300px (בדיוק מה שהגדרנו)
- ה-padding וה-border "נאכלים" מתוך ה-300px
- התוכן עצמו מקבל את מה שנשאר: 300 - 40 - 10 = 250px

ב-border-box, כשאנחנו אומרים width: 300px, האלמנט באמת תופס 300px. הרבה יותר הגיוני ונוח לעבוד ככה.

הגדרה גלובלית

כמעט כל פרויקט CSS מתחיל עם השורה הזו:

*, *::before, *::after {
    box-sizing: border-box;
}

זה מגדיר border-box על כל האלמנטים בדף. ככה לא צריך לחשוב על זה יותר.

קריסת שוליים - margin collapse

תופעה מפתיעה ב-CSS: כשלשני אלמנטים אנכיים (אחד מעל השני) יש שוליים שנוגעים, השוליים לא מתחברים - הגדול "בולע" את הקטן.

.box-a {
    margin-bottom: 30px;
}

.box-b {
    margin-top: 20px;
}

מה המרחק בין box-a ל-box-b?
- אפשר לחשוב שזה 50px (30 + 20)
- אבל בפועל זה 30px (הגדול מבין השניים)

זה נקרא margin collapse. זה קורה רק בכיוון אנכי (למעלה-למטה), לא אופקי.

כללים נוספים:
- אם שני ה-margin-ים שווים, למשל 20px ו-20px, התוצאה היא 20px
- אם אחד שלילי, הם מתחברים: 30px + (-10px) = 20px
- אם שניהם שליליים, נלקח השלילי ביותר

איך למנוע margin collapse

יש כמה דרכים:
- להוסיף padding או border לאלמנט ההורה
- להשתמש ב-overflow: hidden על ההורה
- להשתמש ב-Flexbox או Grid (שם margin collapse לא קורה)

/* adding a tiny border prevents collapse */
.container {
    border-top: 1px solid transparent;
}

רוחב וגובה - width and height

.box {
    width: 400px;      /* fixed width */
    height: 300px;     /* fixed height */
}

אבל הרבה פעמים אנחנו לא רוצים גודל קבוע. אנחנו רוצים גודל שמשתנה אבל עם גבולות:

.box {
    width: 80%;          /* 80% of parent width */
    min-width: 300px;    /* never smaller than 300px */
    max-width: 800px;    /* never larger than 800px */

    height: auto;        /* height adjusts to content */
    min-height: 200px;   /* at least 200px tall */
    max-height: 500px;   /* at most 500px tall */
}
  • min-width / min-height - גודל מינימלי, האלמנט לא יקטן מתחת לזה
  • max-width / max-height - גודל מקסימלי, האלמנט לא יגדל מעבר לזה
  • width: 80% - רוחב יחסי להורה

דפוס נפוץ מאוד לתוכן מרכזי בדף:

.container {
    max-width: 1200px;
    margin: 0 auto;
    padding: 0 20px;
}

זה יוצר קונטיינר שהוא לכל היותר 1200px רוחב, ממורכז בדף, עם קצת ריפוד בצדדים.

גלישה - overflow

מה קורה כשהתוכן גדול מהקופסה? כאן נכנס overflow:

.box {
    width: 300px;
    height: 200px;
    overflow: visible;  /* default: content spills out */
}

.box-hidden {
    width: 300px;
    height: 200px;
    overflow: hidden;   /* content is clipped */
}

.box-scroll {
    width: 300px;
    height: 200px;
    overflow: scroll;   /* always shows scrollbars */
}

.box-auto {
    width: 300px;
    height: 200px;
    overflow: auto;     /* scrollbars only when needed */
}
  • visible (ברירת מחדל) - התוכן גולש מחוץ לקופסה, עלול לחפוף אלמנטים אחרים
  • hidden - התוכן נחתך, מה שלא נכנס פשוט לא נראה
  • scroll - תמיד מציג פסי גלילה (גם אם אין צורך)
  • auto - מציג פסי גלילה רק כשצריך (זה בדרך כלל מה שנרצה)

אפשר גם לשלוט על כל ציר בנפרד:

.box {
    overflow-x: hidden;  /* hide horizontal overflow */
    overflow-y: auto;    /* scroll vertically if needed */
}

הדמיית מודל הקופסה ב-DevTools

ב-DevTools, בתחתית הלשונית Styles (או בלשונית Computed), יש ויזואליזציה של מודל הקופסה. היא מראה:

  • את גודל התוכן במרכז
  • את ה-padding בירוק
  • את ה-border בצהוב
  • את ה-margin בכתום

אפשר גם לרחף עם העכבר על כל אלמנט בדף ולראות את מודל הקופסה שלו מודגש בצבעים שונים. זה כלי מעולה להבנת למה דברים נראים ככה ולא ככה.

דוגמה מסכמת - כרטיס

נבנה כרטיס (card) שמדגים את כל מה שלמדנו:

<div class="card">
    <h2 class="card-title">Box Model Card</h2>
    <p class="card-text">This card demonstrates content, padding, border, and margin working together.</p>
    <a class="card-link" href="#">Learn More</a>
</div>
*, *::before, *::after {
    box-sizing: border-box;
}

body {
    font-family: Arial, sans-serif;
    background-color: #f4f4f4;
    padding: 40px;
}

.card {
    width: 350px;
    background-color: white;
    border: 1px solid #ddd;
    border-radius: 8px;
    padding: 24px;
    margin: 20px auto;
    max-width: 100%;
}

.card-title {
    margin: 0;                    /* reset default margin */
    margin-bottom: 12px;          /* space below title */
    padding-bottom: 12px;         /* space before the line */
    border-bottom: 1px solid #eee; /* subtle separator */
}

.card-text {
    margin: 0;
    margin-bottom: 16px;
    color: #666;
    line-height: 1.6;
}

.card-link {
    display: inline-block;
    padding: 8px 16px;
    border: 2px solid #3498db;
    color: #3498db;
    text-decoration: none;
}

בדוגמה הזו:
- ל-card יש padding פנימי שיוצר מרווח מהגבול
- ל-card יש border עדין
- ל-card יש margin auto למרכוז
- לכותרת יש margin-bottom ו-padding-bottom עם border-bottom שיוצר קו הפרדה
- הכל ב-border-box אז הגדלים הם מה שהגדרנו

סיכום

  • כל אלמנט ב-HTML הוא קופסה עם content, padding, border ו-margin
  • padding הוא מרווח פנימי (מקבל את צבע הרקע), margin הוא מרווח חיצוני (תמיד שקוף)
  • תמיד להגדיר box-sizing: border-box גלובלית
  • הקיצור הוא בכיוון השעון: top, right, bottom, left
  • margin collapse קורה כשמרווחים אנכיים נפגשים - הגדול בולע את הקטן
  • margin: 0 auto ממרכז אלמנט אופקית (אם יש לו width)
  • overflow: auto מוסיף גלילה כשצריך
  • max-width עדיף על width קבוע ברוב המקרים