The rendering pipeline
Layout calculates geometry
Understand how the browser determines the size and position of boxes and why one geometry change can affect many descendants or neighbors.
Layout turns computed styles and content into geometry. For every box that takes part in rendering, the browser calculates a size and a position.
A lot goes into that calculation: the available width, the writing mode, the box model (content, padding, border, margin), the font metrics, the intrinsic size of images, and the layout algorithm in use, whether block flow, flexbox, or grid.
Geometry is connected
Boxes depend on each other. Change the width of a container and the text inside wraps differently. So the number of lines changes. So the height changes. So everything below it moves.
The browser tries to recompute only the affected subtree. Sometimes that’s a few boxes. Sometimes it’s most of the page. Changing the body font size touches almost everything.
This is why a small CSS change can be expensive. The cost depends on how many boxes depend on the one you changed, not on how many lines you edited.
JavaScript can force layout
Normally the browser batches layout. You change ten styles in a row and it computes layout once, before the next paint.
But if you write a style and then immediately read a geometry value, the browser has no choice. It has to run layout right now to give you a correct answer:
const card = document.querySelector('.card')
card.style.width = '400px'
console.log(card.offsetWidth)
The offsetWidth read forces a synchronous layout between the write and the read. One of these is fine. In a loop over hundreds of elements it becomes a real problem, which we’ll cover later as layout thrashing.
Reads that force layout include offsetWidth, offsetHeight, getBoundingClientRect(), scrollTop, and getComputedStyle() for geometry values.
See it in DevTools
Open the Performance panel and record a page load. Look for Layout events on the Main track. Click one and the Summary shows how many nodes were affected and, in recent Chrome versions, where the layout was triggered from.
Now paste the snippet above in the Console while recording. You’ll see a Layout event with a warning that it was forced by JavaScript, pointing at the offsetWidth line. That warning is how you find forced layouts in real code.
Lesson completed