Part 2: Box Model, Display, and Positioning

Introduction

Every element on a page is a rectangular box. Understanding how those boxes are sized, how they relate to their neighbours, and how they can be pulled out of normal document flow is the foundation of CSS layout. I have debugged more layout problems by going back to box model fundamentals than by any other means. This part covers what I know about the box model, display modes, and positioning, from daily basics to the edge cases that catch people off guard.


The Box Model

Every HTML element generates a box with four layers:

β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
β”‚             margin              β”‚
β”‚  β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”  β”‚
β”‚  β”‚          border           β”‚  β”‚
β”‚  β”‚  β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”  β”‚  β”‚
β”‚  β”‚  β”‚       padding       β”‚  β”‚  β”‚
β”‚  β”‚  β”‚  β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”  β”‚  β”‚  β”‚
β”‚  β”‚  β”‚  β”‚    content    β”‚  β”‚  β”‚  β”‚
β”‚  β”‚  β”‚  β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜  β”‚  β”‚  β”‚
β”‚  β”‚  β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜  β”‚  β”‚
β”‚  β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜  β”‚
β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜
  • Content β€” where text, images, and child elements live

  • Padding β€” transparent space between content and border

  • Border β€” visible (or invisible) line around the padding

  • Margin β€” space outside the border, separating the element from neighbours

box-sizing

The browser's default box-sizing: content-box means width and height set the content area only. Padding and border are added on top, making elements wider/taller than the declared size.

box-sizing: border-box includes padding and border in the declared dimensions:

border-box matches how most people think about sizing. I apply it globally on every project.


Margin, Padding, and Border

Shorthand Syntax

All three properties follow the same shorthand pattern:

Individual Properties

Logical Properties (Modern CSS)

Logical properties work in terms of writing direction rather than physical sides β€” useful for internationalisation:

Border

Outline

outline is drawn outside the border and does not affect layout (no space taken). It is primarily used for focus indicators:

Never do outline: none without providing an alternative focus style β€” it removes keyboard navigation visibility.


Margin Collapse

Block margins collapse in the vertical direction: when two block elements stack, their margins do not add β€” the larger margin wins.

Margin collapse also happens between a parent and its first/last child when there is no border, padding, or content between them:

To prevent parent-child collapse, add any padding or border to the parent:

Margin collapse does not happen:

  • Horizontally (left/right)

  • On flex or grid children

  • When overflow is not visible on the parent


Display

The display property controls how an element participates in flow layout and how it lays out its children.

display: block

Takes full available width, forces a line break before and after, respects width/height/margin.

display: inline

Takes only as much width as its content, no forced line breaks, ignores width/height, vertical margin/padding does not affect surrounding layout.

display: inline-block

Inline flow (no forced line breaks) but respects width/height and all margin/padding.

display: none

Removes element from the page entirely β€” not rendered, takes no space, invisible to accessibility tools.

To hide visually but keep accessible to screen readers:

display: flex

Turns the element into a flex container. Children become flex items. Covered fully in Part 3.

display: grid

Turns the element into a grid container. Children become grid items. Covered fully in Part 4.

display: contents

Removes the element's box but keeps its children in the flow β€” useful when you need to wrap elements for semantic reasons without adding a layout box.


Width and Height

width: auto vs width: 100%

  • auto β€” block element fills available width minus its own margins (respects margin)

  • 100% β€” fills 100% of parent's content width, then adds margin on top (can overflow)

Viewport Units

aspect-ratio


Overflow

Controls what happens when content exceeds the element's dimensions.


Positioning

The position property controls how an element is placed in the document.

position: static (default)

Normal document flow. top, right, bottom, left, and z-index have no effect.

position: relative

Element stays in normal flow but can be offset from its natural position using top, right, bottom, left. The space it originally occupied is preserved.

More commonly used to make an element a containing block for absolutely positioned children:

position: absolute

Removed from normal flow (no space reserved). Positioned relative to the nearest ancestor with position other than static. If none, positions relative to the initial containing block (viewport).

position: fixed

Removed from flow. Positioned relative to the viewport. Stays in place as the user scrolls.

position: sticky

Hybrid: behaves as relative until a threshold is reached while scrolling, then becomes fixed relative to its scroll container.

sticky only works if:

  • A top (or bottom) threshold is set

  • The element's scroll container has scrollable overflow

  • The parent is taller than the sticky element

z-index

Controls stacking order for positioned elements (relative, absolute, fixed, sticky). Higher values stack on top.

z-index only works on positioned elements. It creates a stacking context β€” a child element cannot appear above an ancestor's stacking context peer, regardless of z-index value.


The float Property

Float shifts an element to the left or right edge of its container, allowing text to wrap around it. It is the legacy layout mechanism β€” before Flexbox and Grid, floats were used for multi-column layouts.

Clearing floats:

I use floats only for text-wrapping around images. For page layout, I use Flexbox or Grid.


visibility vs display: none vs opacity: 0

Property
Space Reserved
Accessible to Screen Readers
Events

display: none

No

No

No

visibility: hidden

Yes

No

No

opacity: 0

Yes

Yes

Yes

visibility and opacity are combined here because visibility: hidden cannot be transitioned smoothly, but opacity can. The combination gives a fade effect without layout shift.


Summary

Concept
Key Point

box-sizing: border-box

Width includes padding + border β€” apply globally

Margin collapse

Vertical block margins collapse; flex/grid children exempt

display: block

Full width, forces line break

display: inline

Content width only, no width/height

display: inline-block

Inline flow + respects box model

display: none

Removes element entirely from page and accessibility tree

position: relative

Creates positioning context for absolute children

position: absolute

Removed from flow, positioned to nearest positioned ancestor

position: fixed

Positioned to viewport, stays on scroll

position: sticky

Relative until threshold, then fixed within container

z-index

Stacking order β€” works only on positioned elements

overflow

Control clipping/scrolling of overflowing content


Up Next

Part 3 covers Flexbox β€” the modern one-dimensional layout system.

Last updated