Exercise 1: Only margin-left Is Auto — Possible Solution ==================================================================== THE TEST ------------------------------ e = block({'width': '100px', 'margin': '0 20px 0 auto'}) calculate_block_width(e, root_cb) # root_cb content width = 300 e.dimensions.margin.left e.dimensions.margin.right RESULT ------------------------------ margin.right -> 20.0 (unchanged, exactly as declared) margin.left -> 180.0 WORKING THROUGH THE 4-VALUE SHORTHAND FIRST ------------------------------ '0 20px 0 auto' is a 4-value margin shorthand: top=0, right=20px, bottom=0, left=auto -- read directly in that order (top, right, bottom, left), no reuse rule applies here since all four positions are given explicitly. expand_margin_shorthand produces MarginEdges(top=0.0, right=20.0, bottom=0.0, left='auto'). WHY margin-left ALONE ABSORBS THE FULL LEFTOVER ------------------------------ calculate_block_width detects ml_auto=True, mr_auto=False. Since width_str is '100px' (not 'auto'), the width_auto branch is skipped entirely, and the "not width_auto" branch runs: if ml_auto and mr_auto: ... elif ml_auto: margin_left = underflow elif mr_auto: ... else: ... Only the `elif ml_auto:` branch matches (mr_auto is False), so margin_left is set to `underflow` directly -- the ENTIRE leftover space, not half of it. underflow is computed as: total = margin_left(0, zeroed since auto) + border.left(0) + padding.left(0) + width(100) + padding.right(0) + border.right(0) + margin_right(20, NOT auto, kept as-is) = 0 + 0 + 0 + 100 + 0 + 0 + 20 = 120 underflow = cb_width(300) - total(120) = 180 So margin_left becomes 180. margin_right, since mr_auto is False, is never touched by any of the four branches at all -- it keeps its originally parsed value of 20.0 straight from expand_margin_shorthand, completely untouched by the auto-resolution logic. WHY THIS WORKS AS AN ANSWER ------------------------------ This confirms the algorithm's own branch selection genuinely depends on WHICH SPECIFIC combination of auto flags is set, not just "how many" are auto. A single auto margin behaves completely differently from two auto margins (which split the leftover evenly, per the chapter's own Case C) -- with only one auto margin, that ONE margin takes on the entire burden of making the equation balance, and the other, explicitly -declared margin is left exactly as the author wrote it, never recomputed or touched in any way.