skip to content

When margins that collapse in CSS include negative values — for example margin-bottom: 30px meeting margin-top: -10px — how is the resulting margin computed?

level: middleimportance: should knowfreq 38%

answer

  1. not simply largest wins
  2. biggest positive plus most negative
  3. all-negative means the most negative
  4. evaluated over the whole set at once
  5. zero participates and always loses

basics

~20 s

Take the largest positive margin and the most negative margin and add them: 30px plus -10px gives 20px. When every value is positive the rule reduces to the largest wins; when every value is negative, the most negative wins.

solid answer

~40 s

The collapsed margin is the maximum of the positive margins plus the minimum of the negative ones. So `30px` meeting `-10px` resolves to `20px` — the boxes end up closer than the positive margin alone would place them. If all the adjoining margins are positive that reduces to the familiar "largest wins"; if they are all negative it reduces to "most negative wins", so `-20px` meeting `-30px` gives `-30px` and the boxes overlap by 30px. More than two margins can be adjoining at once — a parent, its first child and that child's first child — and the same max-plus-min rule runs across the whole set rather than pairwise. A zero margin always participates and simply loses to any positive value.

go deeper

for a junior

Know that a negative margin does not simply replace the positive one — the two are added, so 30px meeting -10px leaves 20px of space.

for a middle

State the general rule as largest positive plus most negative, and show that all-positive and all-negative sets are just special cases of it.

for a senior

Predict what a pull-up technique will actually do in block flow, and know that moving the pair into flex or grid makes the negative margin apply literally.

for a principal

Have a position on negative margins as a technique: where an overlap is legitimate layout intent versus where it is a patch, and what convention keeps such values from accumulating across a stylesheet.

## The general rule The familiar phrasing "collapsed margins take the larger value" is a special case. The general rule is: > collapsed margin = max(all positive margins) + min(all negative margins) where `min` means the most negative value, and an absent side of the expression contributes zero. Work through the cases: - **All positive.** `max` picks the largest, `min` contributes 0. `20px` and `30px` give `30px` — the rule everybody quotes. - **Mixed.** `30px` and `-10px` give `30 + (-10) = 20px`. `10px` and `-10px` give exactly `0` and the boxes sit flush. - **All negative.** `max` contributes 0, `min` picks the most negative. `-20px` and `-30px` give `-30px`, and the following box is pulled 30px up, overlapping the previous one. - **More than two.** `20px`, `40px`, `-15px` all adjoining give `40 + (-15) = 25px`. Note that this is *not* the same as collapsing them pairwise in source order, which is why the rule is stated over the whole set. ## Where sets larger than two come from Adjoining margins are not limited to a sibling pair. If a section wraps a div which wraps a heading and none of the wrappers has padding, a border, or preceding content, then all three top margins are adjoining and collapse together. Add the previous sibling's bottom margin and you have four values in one collapse. The max-plus-min rule is evaluated once over that whole collection. ## Why this matters in practice Negative margins are a common pull-up technique — a hero image that should bleed up under a header, a card whose first row overlaps the section above. The moment such a margin lands next to another margin in block flow, the result is not the negative value you wrote: it is your negative value *added to* whatever the largest adjoining positive margin is. That is why a `-10px` pull sometimes appears to do nothing at all: if the box it is pulling against carries a `40px` bottom margin, the collapsed result is still a positive `30px` and the box has merely moved down less than before. ```css .section { margin-bottom: 40px; } .hero { margin-top: -10px; } /* used margin between them: 30px */ ``` If you genuinely want the boxes to overlap, either make the negative value exceed the positive one, or take the pair out of collapsing — put them in a flex or grid container, where margins never collapse and the negative margin is applied literally. ## The zero case A `0` margin is not special. It participates in the collapse as a positive-side value of zero, which means it can never win against a positive margin and can never rescue you from a negative one. Setting `margin-top: 0` on the second of two boxes does not remove the gap; the first box's bottom margin is still in the set and still wins.

  • Why can a -10px margin appear to have no effect at all between two blocks?
    Because it collapses with the adjoining margin rather than being applied on top of it. If the box above declares `margin-bottom: 40px`, the collapsed result is `40 + (-10) = 30px` — still a positive gap. The pull only produces overlap once the negative value exceeds the largest positive one in the set.
  • Three margins are adjoining: 20px, 40px and -15px. What is the used margin, and why is pairwise reasoning wrong?
    25px — the largest positive (40px) plus the most negative (-15px). Collapsing is defined over the whole set of adjoining margins at once, not as a chain of two-at-a-time merges, so working left-to-right through the values can give a different and incorrect answer.
  • How do you make a negative margin apply literally rather than collapsing?
    Take the pair out of block-flow collapsing. Margins of flex items and grid items never collapse, so in a flex column a `-10px` top margin is applied in full alongside the neighbour's margin. Separating the margins with padding or a border works too, since non-adjoining margins are both used.

saying these in an interview costs you the question

  • Says the negative margin simply overrides the positive one
  • Adds every adjoining margin together instead of collapsing
  • Thinks all-negative margins sum to the most negative total
  • Collapses more than two margins pairwise in source order
  • Believes a zero margin cancels the neighbour's margin

context