Quiz: Paint or Reflow?
Prove You Understand the Pipeline
Time to put your knowledge to work. For each scenario, you need to determine which stages of the rendering pipeline the browser executes. Get this right, and you'll never write a janky animation again. Get it wrong? No worries — each explanation traces the cost through the pipeline so you walk away with the right mental model.
Remember the three cost tiers:
- Composite only (cheapest):
transform,opacity— handled entirely by the GPU compositor thread. No main thread work. - Paint + Composite (moderate): Visual-only changes like
color,background-color,box-shadow— pixels change but positions don't. - Layout + Paint + Composite (expensive): Geometric changes like
width,height,top,left,margin,font-size— positions and sizes recalculated, then repainted.
Scenario 1: Moving a Tooltip
Let's start with a common one. You animate an element's position using transform: translateX(100px).
Scenario 2: Changing Background Color
A button changes background-color from blue to green on hover.
Scenario 3: Resizing an Element
You animate width from 200px to 400px.
Scenario 4: Animating Opacity
A card fades from opacity: 1 to opacity: 0.
Scenario 5: Changing box-shadow
An element's box-shadow changes from none to 0 4px 12px rgba(0,0,0,0.15).
Scenario 6: Changing top on an Absolutely Positioned Element
This one catches a lot of people. An absolutely positioned modal moves from top: 50% to top: 40%.
Scenario 7: Changing font-size
A heading's font-size changes from 24px to 32px.
Scenario 8: Changing border-radius
An element changes from border-radius: 0 to border-radius: 50% (becoming a circle).
The Complete Cost Reference
Keep this table bookmarked for production work:
| Cost Tier | Properties | What Happens |
|---|---|---|
| Composite only | transform, opacity | GPU moves/fades existing textures. ~0.1ms. |
| Paint + Composite | color, background-color, background-image, border-color, border-style, border-radius, box-shadow, outline, text-decoration, visibility | Pixels redrawn, then composited. ~1-4ms. |
| Layout + Paint + Composite | width, height, top, right, bottom, left, margin, padding, border-width, font-size, font-weight, line-height, text-align, display, position, float, overflow | Geometry recalculated, potentially cascading, then repainted. ~4-16ms+. |
- 1Only transform and opacity are compositor-only. These are the only properties safe to animate at 60fps.
- 2Visual-only properties (color, background, box-shadow) trigger repaint but not layout — moderate cost.
- 3Geometric properties (width, height, top, left, margin, padding, font-size) trigger the full pipeline — avoid animating these.
- 4Use transform: translate() instead of top/left. Use transform: scale() instead of width/height. Use opacity instead of visibility.
- 5Absolutely positioned elements still trigger layout when their position properties change — use transform instead.
- 6When in doubt, open Chrome DevTools → Performance → record, and check the 'Layout' and 'Paint' rows in the flame chart.