Your country

Tools that support it use your country for local currency, number formats, units and paper size. Your choice is saved only in this browser.

Type a name or a two-letter code. Use the up and down arrow keys to move through the countries, Enter to choose one and Escape to close.

CSS  Module 4 – The box model, sizing and overflow

Margin collapse and formatting contexts

When vertical margins collapse into one, how to predict the gap, how flow-root, flex and grid stop it, and how auto margins centre and push boxes.

  • Intermediate
  • 25 minutes
  • Examples run with Node.js 24.21.0 and quickjs 0.32.0
  • By MySmartCoPilot
Free: 25 minutes

What you will learn

  • Predict when vertical margins collapse between siblings, between a parent and child, and through empty blocks
  • Prevent unwanted collapse with display flow-root, padding, borders or a flex or grid parent
  • Use auto margins to centre blocks and to push items apart
  • Choose a spacing strategy in which parents set the space between components with gap

Before you start

What you’ll learn · Before you start

What you will learn

  • Predict when vertical margins collapse between siblings, between a parent and child, and through empty blocks
  • Prevent unwanted collapse with display flow-root, padding, borders or a flex or grid parent
  • Use auto margins to centre blocks and to push items apart
  • Choose a spacing strategy in which parents set the space between components with gap

Before you start

On this page

When the bottom margin of one block meets the top margin of the next, CSS does not add them: they collapse into one margin, as large as the larger of the two. A paragraph with a 30 px bottom margin followed by one with a 20 px top margin sits 30 px above it, not 50 px. Collapse happens only between vertical margins of block boxes in normal flow, and only when nothing separates the margins: no padding, no border, no line of text. A formatting context is the boundary that stops it, which is why the same margins add up inside a flex or grid container. Knowing the rule explains most spacing surprises, such as a heading whose margin pushes its whole card down instead of making space inside it.

This lesson measures twelve cases in Chromium 153, Firefox 155 and WebKit 26.6, which agreed on every one.

The rule: the largest positive margin plus the most negative one

The CSS 2 specification states the rule in a few lines, and its effect fits in one line of code: take the largest positive margin among those that meet, and add the most negative one. If all of them are negative, the most negative wins; if they are all positive, the largest does.

Predict a collapsed margin JavaScript · collapse.mjs
// Adjoining vertical margins combine into one (CSS 2, section 8.3.1): the largest positive margin plus the most
// negative one. Edit the lists and run it again to predict a gap before you open DevTools.

function collapse(margins) {
  const largestPositive = Math.max(0, ...margins);
  const mostNegative = Math.min(0, ...margins);
  return largestPositive + mostNegative;
}

const cases = [
  ['30px below a block, 20px above the next', [30, 20]],
  ['an empty block between: 10, 20, 30, 10', [10, 20, 30, 10]],
  ['30px and -10px', [30, -10]],
  ['-10px and -25px', [-10, -25]],
  ['h2 24px, its section 16px, a -8px pull', [24, 16, -8]],
];
for (const [label, margins] of cases) {
  console.log(`${label.padEnd(42)} -> ${collapse(margins)}px`);
}

// Margins that are not adjoining are simply added: side by side, between flex or grid items, or across padding.
console.log(`${'30px and 20px in a flex column'.padEnd(42)} -> ${30 + 20}px`);

Output

30px below a block, 20px above the next    -> 30px
an empty block between: 10, 20, 30, 10     -> 30px
30px and -10px                             -> 20px
-10px and -25px                            -> -25px
h2 24px, its section 16px, a -8px pull     -> 16px
30px and 20px in a flex column             -> 50px

Recorded with Node.js 24.21.0 on macOS 26 arm64. To run it yourself: mise exec node@24.21.0 -- node collapse.mjs

The rule exists for text. The HTML standard gives every paragraph margin-block: 1em, and because the margins collapse, two paragraphs in a row are 1em apart, not 2em. Margins of the root element never collapse, and horizontal margins never collapse at all.

Where margins meet

Margins are adjoining, and so collapse, in three situations, as long as no padding, border, line box or clearance lies between them and both boxes are in normal flow in the same block formatting context:

  1. the bottom margin of a block and the top margin of the next sibling;
  2. the top margin of a block and the top margin of its first child, or the bottom margin of a block whose height is auto and the bottom margin of its last child;
  3. the top and bottom margins of an empty block, which has no height, no padding, no border and no content: its two margins collapse with each other and with the margins around it.
Two vertical margins collapse only in normal flow, in one formatting context, with nothing between them.Two vertical margins meet:siblings, a parent and its first or last child,or the top and bottom of an empty block1. Are both boxes in normal flow,in the same block formatting context?If not, the margins add up: flex and grid items,floats, inline-blocks, children of flow-root2. Does anything separate them:padding, a border, a line of text or clearance?If so, the margins add up3. They collapse into one margin:the largest positive marginplus the most negative oneyesno

Two questions decide whether two margins collapse

Text description of the diagram

The diagram is a column of steps that starts where two vertical margins meet: two siblings, a parent and its first or last child, or the top and bottom of an empty block.

  1. The first question asks whether both boxes are in normal flow, in the same block formatting context. If not, the margins do not collapse and add up. That is the case for flex and grid items, floats, inline-blocks and the children of a flow-root box.
  2. If they are, the second question asks whether padding, a border, a line of text or clearance separates the margins. If something does, they add up too.
  3. If nothing does, the margins collapse into one margin: the largest positive margin plus the most negative one.

The lab puts each case in a box of its own and measures the result with getBoundingClientRect(). For the six parent cases it reports how far the child’s 24 px margin ends up above the parent and how far inside it:

Twelve margin cases, measured HTML · margin-lab.html
<!doctype html>
<html lang="en">
<head>
  <meta charset="utf-8">
  <title>Margin collapse lab</title>
  <style>
    body { margin: 0; }
    /* Each case sits in its own bordered flow-root box, so no case can collapse with another. */
    .case { display: flow-root; border: 1px solid #999; margin-block-end: 8px; }
    .block { block-size: 24px; background: #dde; }

    /* Blocks that follow each other: the first has a bottom margin, the second a top margin. */
    #siblings .first { margin-block-end: 30px; }
    #siblings .second { margin-block-start: 20px; }
    #empty .first { margin-block-end: 10px; }
    #empty .nothing { margin-block: 20px 30px; } /* an empty block: its two margins touch */
    #empty .second { margin-block-start: 10px; }
    #mixed .first { margin-block-end: 30px; }
    #mixed .second { margin-block-start: -10px; }
    #negative .first { margin-block-end: -10px; }
    #negative .second { margin-block-start: -25px; }
    #flex-column { display: flex; flex-direction: column; }
    #flex-column .first { margin-block-end: 30px; }
    #flex-column .second { margin-block-start: 20px; }
    .side { display: inline-block; inline-size: 40px; block-size: 24px; background: #dde; }
    #side-by-side .first { margin-inline-end: 30px; }
    #side-by-side .second { margin-inline-start: 20px; }

    /* A parent whose first child has a 24px top margin. */
    .marker { block-size: 10px; background: #edd; }
    .child { margin-block-start: 24px; block-size: 24px; background: #ded; }
    #padded .parent { padding-block-start: 1px; }
    #flow-root .parent { display: flow-root; }
    #overflow-hidden .parent { overflow: hidden; }
    #overflow-clip .parent { overflow: clip; }
    #container .parent { container-type: inline-size; }
  </style>
</head>
<body>
  <div class="case" id="siblings"><div class="block first"></div><div class="block second"></div></div>
  <div class="case" id="empty"><div class="block first"></div><div class="nothing"></div><div class="block second"></div></div>
  <div class="case" id="mixed"><div class="block first"></div><div class="block second"></div></div>
  <div class="case" id="negative"><div class="block first"></div><div class="block second"></div></div>
  <div class="case" id="flex-column"><div class="block first"></div><div class="block second"></div></div>
  <div class="case" id="side-by-side"><span class="side first"></span><span class="side second"></span></div>

  <div class="case" id="plain"><div class="marker"></div><div class="parent"><div class="child"></div></div></div>
  <div class="case" id="padded"><div class="marker"></div><div class="parent"><div class="child"></div></div></div>
  <div class="case" id="flow-root"><div class="marker"></div><div class="parent"><div class="child"></div></div></div>
  <div class="case" id="overflow-hidden"><div class="marker"></div><div class="parent"><div class="child"></div></div></div>
  <div class="case" id="overflow-clip"><div class="marker"></div><div class="parent"><div class="child"></div></div></div>
  <div class="case" id="container"><div class="marker"></div><div class="parent"><div class="child"></div></div></div>
  <script>
    const box = (selector) => document.querySelector(selector).getBoundingClientRect();
    const px = (n) => Math.round(n * 100) / 100; // engines measure in fractions of a pixel
    for (const id of ['siblings', 'empty', 'mixed', 'negative', 'flex-column']) {
      console.log(`${id}: ${px(box(`#${id} .second`).top - box(`#${id} .first`).bottom)}px between the blocks`);
    }
    console.log(`side-by-side: ${px(box('#side-by-side .second').left - box('#side-by-side .first').right)}px between the boxes`);
    // Where the child's 24px top margin ends up: above the parent, or inside it.
    for (const id of ['plain', 'padded', 'flow-root', 'overflow-hidden', 'overflow-clip', 'container']) {
      const above = px(box(`#${id} .parent`).top - box(`#${id} .marker`).bottom);
      const inside = px(box(`#${id} .child`).top - box(`#${id} .parent`).top);
      console.log(`${id}: ${above}px above the parent, ${inside}px inside it`);
    }
  </script>
</body>
</html>
Case Margins Result
siblings 30 and 20 px 30 px apart
an empty block between 10, 20, 30, 10 px 30 px apart
mixed signs 30 and −10 px 20 px apart
both negative −10 and −25 px −25 px: overlap
a flex column 30 and 20 px 50 px apart
side by side 30 and 20 px 50 px apart
parent, first child 24 px on the child 24 above, 0 inside
parent, 1 px padding the same 0 above, 25 inside
parent, flow-root the same 0 above, 24 inside
parent, overflow: hidden the same 0 above, 24 inside
parent, overflow: clip the same 24 above, 0 inside
parent, container-type the same 0 above, 24 inside

The parent and first child row is the case people run into most. The child’s margin collapses with its parent’s top margin, the parent has none of its own, so the combined 24 px margin belongs to the parent: it appears above the parent and pushes it down, while the child sits flush with the parent’s top edge. On a page, it looks like a card or a section moving down for no reason, with the space outside its background instead of inside it.

What stops margins from collapsing

Anything that separates two margins keeps them apart. A single pixel of padding or border is enough, as the 1 px padding row shows, and so is a line of text between them. The other way is a box that starts a new formatting context: the layout inside it is independent of the layout around it, and margins never collapse across its edge. These boxes start one:

  • display: flow-root starts one with no side effects: it exists for this.
  • Flex and grid containers start one, and their items’ margins never collapse with each other either; the children are laid out as flex or grid items.
  • display: inline-block and table cells start one; the box sits in a line of text, or in a table.
  • Floats and absolutely or fixed positioned boxes start one, and leave normal flow.
  • overflow: hidden, auto or scroll start one; the box also clips and becomes a scroll container.
  • overflow: clip does not. It clips, and nothing else.
  • container-type: inline-size or size start one; the box’s width then no longer depends on its content.
  • contain: layout, paint, content or strict start one, as part of their containment.

Two of these catch people out. overflow: clip clips like hidden but deliberately does not start a formatting context, so margins still collapse through it, as the lab measured. And container-type, which you add to use container queries, starts one, so adding it to a wrapper can move the spacing of its first and last child before any @container rule matches.

display: flow-root, the side-effect-free fix

A block formatting context is the region in which blocks stack one after another. The box that starts one contains its own floats, grows to wrap them, keeps floats outside it from overlapping its content, and keeps its children’s margins inside. display: flow-root makes an ordinary block do exactly that and nothing more. It is Baseline widely available, and it replaces the older “clearfix” rules that added an invisible pseudo-element after the floats.

For the card whose heading margin leaks out, there are two good fixes:

Keeping a heading's margin inside its card CSS · card-fixes.css
/* The problem: the heading's top margin collapses through the card and pushes the whole card down. */
.card h2 {
  margin-block-start: 24px;
}

/* Fix 1: the card becomes a block formatting context, so the heading's margin stays inside it. */
.card {
  display: flow-root;
}

/* Fix 2: no margin to leak: the card's padding makes the space, and its first child starts at the top. */
.card {
  padding: 24px;
}
.card > :first-child {
  margin-block-start: 0;
}

Choose flow-root when the card’s spacing should come from its children’s margins. Choose padding when the card is a component whose inner spacing it controls itself; then removing the first child’s top margin also keeps the space the same whatever element comes first.

Auto margins: centring and pushing apart

A margin of auto takes up free space, and what counts as free space depends on the layout. The page below has a 600 px column in an 800 px window, a 200 px box in a 120 px tall block, a navigation bar and a flex container with one item:

Auto margins in block and flex layout HTML · auto-margins.html
<!doctype html>
<html lang="en">
<head>
  <meta charset="utf-8">
  <title>Auto margins in block and flex layout</title>
  <style>
    body { margin: 0; font: 16px/24px Arial, sans-serif; }
    /* Block layout: auto margins on both sides share the free space, which centres the box. */
    .page { max-inline-size: 600px; margin-inline: auto; }
    /* In normal flow, auto top and bottom margins count as 0. */
    .tall { block-size: 120px; }
    .tall .note { inline-size: 200px; margin: auto; }
    /* Flex layout: an auto margin takes all the free space on its side. */
    nav { display: flex; gap: 8px; inline-size: 600px; }
    nav a { padding: 8px; }
    nav .account { margin-inline-start: auto; }
    .hero { display: flex; block-size: 120px; }
    .hero .note { margin: auto; }
  </style>
</head>
<body>
  <div class="page">A 600px column</div>
  <div class="tall"><p class="note">margin: auto in a block</p></div>
  <nav><a href="#">Home</a><a href="#">Shop</a><a class="account" href="#">Account</a></nav>
  <div class="hero"><p class="note">margin: auto in a flex container</p></div>
  <script>
    const r = (selector) => document.querySelector(selector).getBoundingClientRect();
    const px = (n) => Math.round(n * 100) / 100; // engines measure in fractions of a pixel
    console.log(`column in an 800px window: starts at ${r('.page').left}px, ends ${800 - r('.page').right}px from the right`);
    console.log(`block, margin: auto: the note starts ${r('.tall .note').top - r('.tall').top}px below the top of its 120px box`);
    console.log(`nav: Account ends at ${px(r('nav .account').right)}px, the right end of the 600px nav`);
    const hero = r('.hero'), note = r('.hero .note');
    console.log(`flex, margin: auto: the note has ${note.top - hero.top}px above it and ${hero.bottom - note.bottom}px below it`);
  </script>
</body>
</html>
  • In block layout, margin-inline: auto on the 600 px column centred it, with 100 px on each side.
  • In block layout, margin: auto on the 200 px box left it at the top: auto top and bottom margins count as 0.
  • In the flex row, an auto start margin on the last link moved it to the far end.
  • In the flex container, margin: auto on its only item centred it, with 48 px above and below.

In normal flow, margin-inline: auto shares the unused width equally between the two sides, so it centres any block that has a width or a maximum width smaller than its container; without one, the block already fills the line and there is nothing to share. Top and bottom auto margins count as zero there. In a flex container, auto margins take all the positive free space on their side before justify-content runs, in both directions: one auto margin pushes an item to the far end, such as an account link at the right of a navigation bar, and margin: auto on a single item centres it horizontally and vertically.

A spacing strategy that avoids surprises

Collapse is predictable once you know the rule, but it is easier not to depend on it. A common pattern in design systems is that a component sets no margin on its outer edge, and the container that places components sets the space between them:

Space set by the parent CSS · spacing.css
/* Components have no outer margin; the container that places them decides the space between them. */
.stack {
  display: flex;
  flex-direction: column;
  gap: 16px; /* between items only: nothing before the first or after the last, and nothing collapses */
}

/* Text flow, where the elements are paragraphs and headings: space before every element but the first. */
.flow > * + * {
  margin-block-start: 1em;
}

gap works in flex and grid containers (and in multi-column layout). It adds space only between items, never before the first or after the last one, and since the margins of flex and grid items never collapse, items without margins of their own end up exactly 16 px apart with gap: 16px. For running text, where paragraphs and headings follow each other in normal flow, the .flow > * + * rule gives every element but the first a top margin, so only one margin ever sits between two blocks. The margin-trim property, which removes children’s margins at the edges of their container, would help here too, but only Safari supports it so far.

Practise: predict the gap

The exercise turns the rules of this lesson into two functions, and its tests include the cases of the lab.

Exercise · Medium · JavaScript

Predict where a heading's top margin ends up

A card whose heading has a top margin can show that space inside the card, or above it, where it pushes the whole card down. Write two functions in gaps.mjs that predict it, and export them. All lengths are in px.

The first function, collapse(margins), returns the single margin that a list of adjoining vertical margins becomes: the largest positive margin plus the most negative one. collapse([30, -10]) is 20, collapse([-10, -25]) is -25, and an empty list gives 0.

The second, childStart({ parent, childMargin }), describes a parent block and the top margin of its first child, and returns { above, inside }: how far the parent's border box starts below the block before it (which has no margin of its own), and how far below the parent's border-box top the child's border box starts. parent may leave out any of these, which then have the values in brackets: margin (its own top margin, 0), paddingTop (0), borderTop (0), display ('block'), overflow ('visible') and containerType ('normal').

  • The two margins collapse when nothing separates them, that is with no top padding and no top border, and when the parent does not start a new formatting context. Then above is collapse([parent.margin, childMargin]) and inside is 0.
  • The parent starts a new formatting context when its display is 'flow-root', 'flex', 'grid' or 'inline-block', when its overflow is 'hidden', 'auto' or 'scroll' (not 'clip'), or when its containerType is 'inline-size' or 'size'.
  • Otherwise above is the parent's own margin and inside is the border, the padding and the child's margin added.

The sample tests import both functions from gaps.mjs and run in your browser; several of them are the cases of the lesson's lab, measured in three browser engines.

Starter code · gaps.mjs

/** The one margin that adjoining vertical margins collapse into (px). */
export function collapse(margins) {
  // Replace this line with your code.
  return 0;
}

/** Where a first child's top margin ends up: { above, inside } (px). */
export function childStart({ parent, childMargin }) {
  // Replace this line with your code.
  return { above: 0, inside: childMargin };
}
The sample tests · gaps.test.mjs
import { test, assert } from 'mysmartcopilot:test';
import { collapse, childStart } from './gaps.mjs';

test('the largest positive margin wins', () => {
  assert.equal(collapse([30, 20]), 30);
  assert.equal(collapse([10, 20, 30, 10]), 30);
});

test('negative margins are taken off, and all-negative lists keep the most negative', () => {
  assert.equal(collapse([30, -10]), 20);
  assert.equal(collapse([24, 16, -8]), 16);
  assert.equal(collapse([-10, -25]), -25);
  assert.equal(collapse([-5]), -5);
});

test('no margins, or only zeros, make 0', () => {
  assert.equal(collapse([]), 0);
  assert.equal(collapse([0, 0]), 0);
});

test('a plain parent lets the child margin out (the lab: 24px above, 0 inside)', () => {
  assert.deepEqual(childStart({ parent: {}, childMargin: 24 }), { above: 24, inside: 0 });
  assert.deepEqual(childStart({ parent: { display: 'block', overflow: 'visible' }, childMargin: 24 }), { above: 24, inside: 0 });
});

test("the parent's own margin collapses with the child's", () => {
  assert.deepEqual(childStart({ parent: { margin: 16 }, childMargin: 24 }), { above: 24, inside: 0 });
  assert.deepEqual(childStart({ parent: { margin: 32 }, childMargin: 24 }), { above: 32, inside: 0 });
  assert.deepEqual(childStart({ parent: { margin: 16 }, childMargin: -8 }), { above: 8, inside: 0 });
});

test('padding or a border keeps the margin inside (the lab: 1px of padding gives 25px)', () => {
  assert.deepEqual(childStart({ parent: { paddingTop: 1 }, childMargin: 24 }), { above: 0, inside: 25 });
  assert.deepEqual(childStart({ parent: { borderTop: 2 }, childMargin: 24 }), { above: 0, inside: 26 });
  assert.deepEqual(childStart({ parent: { margin: 16, paddingTop: 8, borderTop: 1 }, childMargin: 24 }), { above: 16, inside: 33 });
});

test('flow-root, flex, grid and inline-block start a new formatting context', () => {
  for (const display of ['flow-root', 'flex', 'grid', 'inline-block']) {
    assert.deepEqual(childStart({ parent: { display }, childMargin: 24 }), { above: 0, inside: 24 }, display);
  }
  assert.deepEqual(childStart({ parent: { display: 'flow-root', margin: 10 }, childMargin: 24 }), { above: 10, inside: 24 });
});

test('overflow hidden, auto and scroll do too, but clip does not', () => {
  for (const overflow of ['hidden', 'auto', 'scroll']) {
    assert.deepEqual(childStart({ parent: { overflow }, childMargin: 24 }), { above: 0, inside: 24 }, overflow);
  }
  assert.deepEqual(childStart({ parent: { overflow: 'clip' }, childMargin: 24 }), { above: 24, inside: 0 });
});

test('a size container is a new formatting context', () => {
  assert.deepEqual(childStart({ parent: { containerType: 'inline-size' }, childMargin: 24 }), { above: 0, inside: 24 });
  assert.deepEqual(childStart({ parent: { containerType: 'size' }, childMargin: 24 }), { above: 0, inside: 24 });
  assert.deepEqual(childStart({ parent: { containerType: 'normal' }, childMargin: 24 }), { above: 24, inside: 0 });
});
A hint

For collapse, keep two running values that start at 0: the largest margin and the smallest one. The answer is their sum, so [30, -10] gives 30 + (−10). For childStart, first decide with one boolean whether the margins can touch: no top padding, no top border, and none of the listed values that start a formatting context.

The sample tests run on this device, in your browser (QuickJS): nothing is sent to mysmartcopilot.com. The first run downloads JavaScript (about 0.6 MB), which is kept for the next runs. A check in your browser is feedback for you, not proof that the code is right for every input.

Interview questions

Fresher · What is margin collapsing, and does it happen to horizontal margins?

Margin collapsing is CSS combining adjoining vertical margins of block boxes into one margin instead of adding them. The result is the largest positive margin plus the most negative one, so 30 px above 20 px gives 30 px, and 30 px with −10 px gives 20 px. It happens between a block and its next sibling, between a parent and its first or last child when no padding or border separates them, and through an empty block. It only happens in normal flow, in the same block formatting context: margins of flex and grid items, floats, absolutely positioned boxes and inline-blocks never collapse, and neither do margins across the edge of a flow-root or overflow: hidden box. Horizontal margins never collapse; two inline-blocks with 30 px and 20 px margins between them sit 50 px apart.

Key takeaways

  • Adjoining vertical margins collapse into one: the largest positive margin plus the most negative one. Horizontal margins never collapse.
  • They meet between siblings, between a parent and its first or last child, and through an empty block, as long as no padding, border or line of text separates them.
  • A child’s top margin that collapses with its parent’s appears above the parent: give the parent padding, or make it display: flow-root.
  • Flex and grid containers, floats, inline-blocks, overflow other than visible or clip, and size containers start a new formatting context, and margins do not collapse across it. overflow: clip does not.
  • margin-inline: auto centres a block that has a width; in flex layout, auto margins take all the free space and can push an item to the end or centre it both ways.
  • Let parents set the space between components with gap, and keep components free of outer margins.

Check yourself

6 questions about this lesson. Every answer and why it is right is on the page, behind “Show the answer”. Your score stays in this browser.

  1. Question 1 of 6 A paragraph has margin-bottom: 18px and the heading after it margin-top: 32px. Both are ordinary blocks in normal flow. How many pixels separate them?

    Type a number.

    Show the answer to question 1

    Answer: 32 px

    The two margins are adjoining, so they collapse into one: the larger, 32 px. They would add up to 50 px only if something separated them or if the two boxes were flex or grid items.

  2. Question 2 of 6 Three margins meet: 24px, 40px and -16px. What is the collapsed margin?

    Type a number.

    Show the answer to question 2

    Answer: 24 px

    The largest positive margin, 40 px, plus the most negative one, −16 px, gives 24 px. The 24 px margin itself plays no part.

  3. Question 3 of 6 A card's first heading has a top margin that leaks out above the card. Which changes to the card keep the margin inside it?

    Choose every answer that is right.

    Show the answer to question 3

    Answer:

    • padding-top: 1px
    • display: flow-root
    • display: flex; flex-direction: column

    flow-root and a flex container start a new formatting context, and padding separates the two margins, so each keeps the heading's margin inside the card. overflow: clip clips without starting a formatting context, so the margin still leaks, as the lab measured in all three engines. The card's own margin is not what leaks.

  4. Question 4 of 6 Two inline-block badges sit side by side; the first has margin-right: 12px, the second margin-left: 8px. What is the gap between them, not counting any space character?

    Choose one answer.

    Show the answer to question 4

    Answer: 20px, because horizontal margins never collapse

    Only vertical margins of block boxes collapse. Horizontal margins are always added, so the gap is 12 + 8 = 20 px. Between inline-blocks a space in the HTML also adds the width of a space character, which is why the question leaves it out.

  5. Question 5 of 6 You add container-type: inline-size to a wrapper so its children can use container queries. What can change in the layout even before any query matches?

    Choose one answer.

    Show the answer to question 5

    Answer: Margins of the first and last child stop collapsing through the wrapper, so spacing near it changes.

    A size container establishes an independent formatting context, so its children's margins no longer collapse with its own. In the lab, a child's 24 px margin moved from above the wrapper to inside it as soon as container-type was set. Inline-size containment also stops the wrapper from taking its width from its content.

  6. Question 6 of 6 Which CSS centres a block horizontally in its container?

    Choose one answer.

    Show the answer to question 6

    Answer: max-inline-size: 40rem; margin-inline: auto;

    Auto margins on both sides share the space the box does not use, so the box needs a width or a maximum width smaller than its container. Without one it already fills the line and there is nothing to share. Auto top and bottom margins count as 0 in normal flow, and text-align centres the inline content, not the box.

References

Related tools

Report a problem with this lesson

Quick answers and tool search

Type to search tools or to get a quick answer, for example 18% of 2500. Use the up and down arrow keys to move through the results, Enter to choose, and Escape to close.