CSS Box Model and Layout
1. Content, Padding, Border, Margin Model
| Layer | Properties | Description | Affects Layout |
|---|---|---|---|
| Content | width, height |
Innermost box containing text, images, children | Yes - element size |
| Padding | padding, padding-* |
Space between content and border (inside element) | Yes - adds to total size |
| Border | border, border-* |
Edge around padding (visible boundary) | Yes - adds to total size |
| Margin | margin, margin-* |
Space outside border (separates from other elements) | Yes - spacing only (not size) |
| Property | Shorthand Syntax | Description | Example |
|---|---|---|---|
| margin/padding | all |
Same value for all 4 sides | margin: 10px; |
| margin/padding | vertical horizontal |
Top/bottom, left/right | padding: 10px 20px; |
| margin/padding | top h-sides bottom |
Top, left/right, bottom | margin: 10px 20px 30px; |
| margin/padding | top right bottom left |
Clockwise from top | padding: 10px 20px 30px 40px; |
| Individual sides | *-top/right/bottom/left |
Set individual side values | margin-top: 10px; |
| auto | margin: auto; |
Browser calculates (centers block elements) | margin: 0 auto; |
Example: Box model layers
/* Traditional box model (content-box) */
.box {
width: 200px; /* Content width */
height: 100px; /* Content height */
padding: 20px; /* +40px to width, +40px to height */
border: 5px solid; /* +10px to width, +10px to height */
margin: 10px; /* Spacing outside (doesn't add to size) */
/* Total width: 200 + 40 + 10 = 250px */
/* Total height: 100 + 40 + 10 = 150px */
}
/* Shorthand patterns */
.padding-all { padding: 20px; } /* All sides */
.padding-vh { padding: 10px 20px; } /* V: 10px, H: 20px */
.padding-3 { padding: 10px 20px 30px; } /* T: 10px, H: 20px, B: 30px */
.padding-4 { padding: 10px 20px 30px 40px; } /* T R B L (clockwise) */
/* Centering with auto margin */
.centered {
width: 80%;
max-width: 1200px;
margin: 0 auto; /* Horizontal centering */
}
/* Individual sides */
.custom {
margin-top: 2rem;
margin-bottom: 1rem;
padding-left: 1.5rem;
padding-right: 1.5rem;
}
Note: Margin collapse - Adjacent vertical margins collapse to
the larger value. Padding never collapses. Margins can be negative, padding cannot.
2. Box-sizing Property (border-box vs content-box)
| Value | Calculation | Description | Use Case |
|---|---|---|---|
| content-box | width/height = content only | Default - padding/border added to width/height | CSS default (not recommended) |
| border-box | width/height includes padding + border | Padding/border included in width/height | Modern best practice (intuitive) |
| box-sizing | Width Calculation | Total Width | Behavior |
|---|---|---|---|
| content-box | width + padding + border + margin | Larger than set width | Padding/border expands element |
| border-box | width (includes padding + border) + margin | Exactly set width | Padding/border eat into content |
Example: box-sizing comparison
/* Global best practice - apply to all elements */
*, *::before, *::after {
box-sizing: border-box;
}
/* content-box example (default) */
.content-box {
box-sizing: content-box;
width: 200px;
padding: 20px;
border: 5px solid;
/* Total width: 200 + 20*2 + 5*2 = 250px */
}
/* border-box example (recommended) */
.border-box {
box-sizing: border-box;
width: 200px;
padding: 20px;
border: 5px solid;
/* Total width: 200px (includes padding and border) */
/* Content width: 200 - 20*2 - 5*2 = 150px */
}
/* Practical use - predictable layouts */
.container {
box-sizing: border-box;
width: 100%;
padding: 20px; /* Doesn't cause horizontal overflow */
}
Note: Always use border-box globally. It makes layouts
predictable -
width: 100% with padding won't cause overflow. Industry standard since 2012.
3. Intrinsic and Extrinsic Sizing (width, height)
| Type | Keywords | Description | Use Case |
|---|---|---|---|
| Extrinsic | px, %, em, rem, etc. | Fixed or relative to parent/viewport | Controlled, predictable layouts |
| Intrinsic | auto, min-content, max-content, fit-content | Based on content size | Content-driven, flexible layouts |
| Keyword | Behavior | Description | Example |
|---|---|---|---|
| auto | Default sizing | Block: fills container width; Inline: fits content | width: auto; |
| min-content | Minimum width | Shrinks to smallest possible (longest word/unbreakable content) | width: min-content; |
| max-content | Maximum width | Expands to fit all content without wrapping | width: max-content; |
| fit-content | Adaptive width | Uses max-content up to available space, then wraps | width: fit-content; |
| fit-content(limit) | Clamped adaptive | Like fit-content but with maximum limit | width: fit-content(300px); |
| stretch NEW | Fill available | Fills available space (replaces old -webkit-fill-available) | width: stretch; |
Example: Intrinsic sizing keywords
/* min-content - smallest possible width */
.min-width {
width: min-content;
/* Width = longest word or unbreakable content */
}
/* max-content - no wrapping */
.max-width {
width: max-content;
/* Expands to fit all content on one line */
}
/* fit-content - smart adaptive */
.fit-width {
width: fit-content;
/* Uses max-content if space available, otherwise wraps */
max-width: 100%; /* Prevent overflow */
}
/* fit-content with limit */
.limited {
width: fit-content(500px);
/* Max 500px, shrinks if less space available */
}
/* Practical: button sizing */
button {
width: fit-content; /* Wraps text naturally */
min-width: 120px; /* Minimum size */
}
/* Stretch - fill available space */
.stretch {
width: stretch; /* Fills parent (like width: 100%) */
}
Example: Practical intrinsic sizing patterns
/* Card with dynamic width based on content */
.card {
width: fit-content;
min-width: 250px;
max-width: 100%;
}
/* Table column sizing */
th, td {
width: max-content; /* Fit content without wrapping */
}
/* Navigation items */
.nav-item {
width: fit-content; /* Shrinks to content */
padding: 0.5rem 1rem;
}
/* Grid with intrinsic columns */
.grid {
display: grid;
grid-template-columns:
min-content /* Icon/image column - smallest possible */
1fr /* Main content - fills space */
max-content; /* Action buttons - no wrap */
}
4. Aspect-ratio Property and Constraints NEW
| Property | Syntax | Description | Use Case |
|---|---|---|---|
| aspect-ratio | width / height |
Maintains width-to-height ratio | Responsive images, video embeds, cards |
| Common ratios | 16/9, 4/3, 1/1, etc. | Standard display proportions | Video (16:9), Square (1:1), Portrait (3:4) |
| auto | auto |
Uses intrinsic aspect ratio if available | Images with natural dimensions |
| With width/height | Dimension + aspect-ratio | One dimension set, other calculated from ratio | Responsive sizing with constraints |
Example: aspect-ratio usage
/* Video container - 16:9 ratio */
.video-wrapper {
width: 100%;
aspect-ratio: 16 / 9;
/* Height automatically calculated */
}
/* Square elements */
.avatar {
width: 100px;
aspect-ratio: 1 / 1; /* Square */
}
/* Card with consistent ratio */
.card {
width: 100%;
max-width: 400px;
aspect-ratio: 3 / 4; /* Portrait card */
}
/* Image placeholder before loading */
.image-placeholder {
width: 100%;
aspect-ratio: 16 / 9;
background: #f0f0f0;
}
/* Responsive grid items maintaining ratio */
.grid-item {
width: 100%;
aspect-ratio: 4 / 3;
}
/* With min/max constraints */
.constrained {
aspect-ratio: 1 / 1;
width: clamp(100px, 50vw, 500px);
/* Height follows aspect ratio */
}
Example: Replacing padding-top hack
/* OLD WAY - padding-top hack */
.old-ratio {
position: relative;
width: 100%;
padding-top: 56.25%; /* 16:9 ratio (9/16 = 0.5625) */
}
.old-ratio > * {
position: absolute;
top: 0;
left: 0;
width: 100%;
height: 100%;
}
/* NEW WAY - aspect-ratio property */
.new-ratio {
width: 100%;
aspect-ratio: 16 / 9; /* Much simpler! */
}
/* Combining with object-fit for images */
.responsive-image {
width: 100%;
aspect-ratio: 16 / 9;
object-fit: cover; /* Fill without distortion */
}
Note:
aspect-ratio replaces the old padding-top hack. Works with any dimension - set width or height, the other is calculated. Respects min/max
constraints.
5. Object-fit and Object-position for Media
| Value | Behavior | Aspect Ratio | Use Case |
|---|---|---|---|
| fill | Stretch to fill container (default) | Distorts to match | Rare - causes distortion |
| contain | Scale to fit within container | Preserved - shows all content | Product images, logos (no cropping) |
| cover | Scale to fill container | Preserved - may crop edges | Hero images, backgrounds, thumbnails |
| none | Original size, centered | Preserved - may overflow/gap | Icons, exact size display |
| scale-down | Smaller of none or contain | Preserved - never enlarges | Thumbnails, small images |
| Property | Syntax | Description | Example |
|---|---|---|---|
| object-position | x y |
Position content within box | object-position: center top; |
| Keywords | top, right, bottom, left, center | Named positions | object-position: right bottom; |
| Percentages | 0-100% | Relative positioning | object-position: 75% 50%; |
| Lengths | px, em, rem | Absolute offset from top-left | object-position: 20px 10px; |
Example: object-fit values comparison
/* Common pattern: responsive images */
.image-container {
width: 300px;
height: 200px;
}
/* cover - fills space, crops if needed */
.hero-image {
width: 100%;
height: 100%;
object-fit: cover;
object-position: center; /* Focus on center */
}
/* contain - shows all, may have gaps */
.product-image {
width: 100%;
height: 100%;
object-fit: contain;
object-position: center;
}
/* scale-down - never enlarges */
.thumbnail {
max-width: 150px;
max-height: 150px;
object-fit: scale-down;
}
/* none - original size */
.icon {
width: 48px;
height: 48px;
object-fit: none;
}
Example: object-position for focal points
/* Focus on top of image (faces, important content) */
.portrait {
object-fit: cover;
object-position: center top;
}
/* Focus on bottom */
.landscape {
object-fit: cover;
object-position: center bottom;
}
/* Precise positioning with percentages */
.off-center {
object-fit: cover;
object-position: 75% 25%; /* Right-upper focus */
}
/* Video element */
video {
width: 100%;
height: 400px;
object-fit: cover;
object-position: center;
}
/* Profile pictures - always square, centered */
.avatar img {
width: 100%;
height: 100%;
object-fit: cover;
object-position: center;
border-radius: 50%;
}
Note: Use cover for backgrounds/thumbnails (fills space), contain for logos/products (shows all).
object-position controls focal
point when content is cropped.
6. Overflow Controls (overflow: visible, hidden, scroll, auto)
| Value | Behavior | Scrollbar | Use Case |
|---|---|---|---|
| visible | Content overflows container (default) | None | Default behavior, dropdowns |
| hidden | Clips overflow, content invisible | None | Hide excess, image containers |
| scroll | Always shows scrollbar, content scrollable | Always visible | Force scrollbar presence |
| auto | Scrollbar only when needed | When overflows | Most common - adaptive scrolling |
| clip | Hard clip (no scroll even programmatically) | None | Complete clip, no scroll anchor |
| Property | Syntax | Description | Example |
|---|---|---|---|
| overflow | value |
Both x and y axes | overflow: auto; |
| overflow-x | value |
Horizontal overflow only | overflow-x: scroll; |
| overflow-y | value |
Vertical overflow only | overflow-y: auto; |
| overflow (shorthand) | x y |
Set both axes separately | overflow: hidden auto; |
| overflow-wrap | break-word |
Break long words to prevent overflow | overflow-wrap: break-word; |
| text-overflow | ellipsis |
Show ... for clipped text (requires overflow: hidden) | text-overflow: ellipsis; |
Example: Overflow behaviors
/* Auto - most common (scrollbar when needed) */
.scrollable-container {
max-height: 400px;
overflow: auto;
}
/* Hidden - clip overflow */
.image-container {
overflow: hidden; /* Clips overflow content */
border-radius: 8px; /* Creates rounded images */
}
/* Separate x and y control */
.horizontal-scroll {
overflow-x: auto; /* Horizontal scroll when needed */
overflow-y: hidden; /* No vertical scroll */
white-space: nowrap; /* Prevent wrapping */
}
/* Vertical scroll only */
.chat-box {
height: 500px;
overflow-y: auto; /* Vertical scroll */
overflow-x: hidden; /* No horizontal scroll */
}
/* Clip - hard clip (no scroll programmatically) */
.strict-clip {
overflow: clip; /* Cannot be scrolled even with JS */
}
Example: Text overflow ellipsis
/* Single line ellipsis */
.truncate {
white-space: nowrap; /* Prevent wrapping */
overflow: hidden; /* Hide overflow */
text-overflow: ellipsis; /* Show ... */
}
/* Multi-line ellipsis (webkit only) */
.multi-line-ellipsis {
display: -webkit-box;
-webkit-line-clamp: 3; /* 3 lines */
-webkit-box-orient: vertical;
overflow: hidden;
}
/* Word breaking for long content */
.break-words {
overflow-wrap: break-word; /* Break long words */
word-break: break-word; /* Alternative */
}
/* Card title truncation */
.card-title {
white-space: nowrap;
overflow: hidden;
text-overflow: ellipsis;
max-width: 300px;
}
Example: Scroll containers and behavior
/* Scrollable sidebar */
.sidebar {
position: fixed;
height: 100vh;
overflow-y: auto;
overflow-x: hidden;
}
/* Horizontal scrolling gallery */
.gallery {
display: flex;
gap: 1rem;
overflow-x: auto;
overflow-y: hidden;
scroll-snap-type: x mandatory; /* Snap scrolling */
}
/* Table with fixed header */
.table-container {
max-height: 500px;
overflow-y: auto;
}
/* Modal content */
.modal-content {
max-height: 80vh;
overflow-y: auto;
overflow-x: hidden;
}
/* Code block with horizontal scroll */
pre {
overflow-x: auto;
white-space: pre;
}
Warning:
overflow: hidden creates a new formatting
context which can affect layout (margin collapse, floats). Use overflow: auto for
scrollable containers.
Box Model Best Practices
- Always use box-sizing: border-box globally
- Use aspect-ratio for responsive media containers
- Use object-fit: cover for hero images, contain for product images
- Use overflow: auto for scrollable areas (not scroll)
- Use fit-content for buttons and dynamic width elements
- Remember margin collapse - adjacent vertical margins merge
- Combine
text-overflow: ellipsiswithwhite-space: nowrapandoverflow: hidden