Skip to content

Box Model

Analogy: person in a winter coat

  1. content
    1. the person
  2. padding
    1. the padding in the winter coat
  3. border
    1. the outside of the coat
  4. margin
    1. personal space (2 meters!)

Percentages for padding/border/margin

always refers to the width

/* top padding will be 50% of the width */
padding-top: 50%;

Units for border/margin/padding


  • percent is based on the width
    • possibly sometimes the height?
    • margin-top: 10% may be calculated from the parent width, not height?

Logical properties

Prefix with

  • border
  • margin
  • padding

  • -block-start: top

  • -block-end: bottom
  • -inline-start:left
  • -inline-end: right


  • border-block-start: 10px


  • only border-style is required
    • without it, border won't render
    • border: solid: will be 3px black
    • there's a bunch of other styles
      • border-styles.png
  • color
    • uses currentColor by default
    • the font color

Border vs outline vs box-shadow

Example: for a focus indicator



  • takes up space in flow
  • box-sizing: border-box?
    • it will shrink the content slightly


  • takes up no space
    • not a part of the box model
  • outline-offset: can be negative -> inside the content
  • outline is still a rectangle in Safari
    • respects border-radius in other browsers
  • Accessibility


  • can have multiple box shadows
  • doesn't appear in Windows high contrast themes

workaround: a transparent outline fallback for box-shadow

a:focus {
    /* Visible in the full-colour space */
    box-shadow: 0px 0px 5px 5px rgba(0, 0, 255, 1);

    /* Visible in Windows high-contrast themes */
    outline-color: transparent;
    outline-width: 2px;
    outline-style: dotted;

Have a border only on one side



Syntax FM Margin episode

  • margin
    • creating space between siblings
  • padding
    • creating space between parent and child

Negative margin

the only one of the three that can be negative

  • will still move around the children
    • because of the flow algo
  • unlike transform: translate()

Margin auto

  • left/right margin: auto only works if there's an explicit width
  • put the leftover space in the left/right
margin-left: auto;
width: 24rem;

margin-top: auto; /* spec says 0 */

Margin Collapse

[[css-flow-layout#Margin collapse]]


  • Only use padding for standalone components
    • you don't know where the component will be
  • only margin-bottom, no margin-top (predictable)
  • use grid for everything (no collapsing margin)
  • a div component just for space

Stretch out an image with margin

Get child to break free from the parent padding

When width: auto, left and right margin extend the width of the box

.stretched works if you put a paragraph in it too

  • you could use calc()

if this feels hacky, see [[css-grid]] and full bleed layout

<div class="card">
    <p>The otter is the best</p>
+    <div class="stretched">
        <img src="/otter.jpg" />
+    </div>
    <p>The best</p>
.stretched {
    margin-left: -32px;
    margin-right: -32px;

.stretched img {
    width: 100%;

margin-can-go-through-parent-padding.png margin-stretched-out.png

Margin vs padding

Uniquely margin

  • margin: creating space from the box & everything else
  • margin: has collapsing margins
  • margin-left/right has the auto property
  • margin can be negative

Uniquely padding

  • padding: making the inside of your box bigger



Default: box-sizing: content-box

  • width: 100px
    • content: 100px

box-sizing: border-box

  • setting width: 100px
    • content + padding + border = 100px
html {
    box-sizing: border-box;

*:after {
    box-sizing: inherit;

Last update: 2022-11-04