Skip to content

From HTML to Pixels: DOM, CSSOM, Layout, Paint, and Components

I put this guide together to map out how browsers take HTML and CSS code and draw pixels on screen.

Understanding the browser rendering pipeline makes it much easier to track down visual bugs, fix layout issues, and understand where frontend frameworks like React or Vue fit into the process.

Navigate this post

How the browser reads HTML and CSS

When the browser loads a webpage, it parses text files into tree structures:

  • DOM (Document Object Model): A tree of objects representing the HTML tags, text, and attributes. JavaScript interacts with this tree to update content and listen for user clicks.
  • CSSOM (CSS Object Model): A tree of all CSS rules, which the browser uses to calculate styles.
  • Render Tree: A combined tree of only the visible elements on the page along with their calculated styles. (Elements hidden with display: none are left out).

Here is a simple example:

shipment-card.html
<article
  class="shipment"
  data-status="delayed">
  <h2>Container ABC123</h2>
  <p>Delayed at Port Klang</p>
</article>

The browser creates DOM nodes for the <article>, <h2>, <p>, and their text contents. The DOM holds the page structure, while the styling and screen positions are calculated in the next steps.

The pipeline from code to screen

The browser processes a page through five main steps:

---
title: "Browser Rendering Steps"
---
flowchart TB
    accTitle: Browser rendering steps
    accDescr: HTML and CSS turn into DOM and CSSOM, then form the render tree, calculate layout, paint visuals, and composite to screen.

    A["HTML Source"] --> B["DOM Tree"]
    C["CSS Source"] --> D["CSSOM Tree"]
    B --> E["Style Resolution (Render Tree)"]
    D --> E
    E --> F["Layout (Calculate Sizes & Positions)"]
    F --> G["Paint (Draw Colors, Borders, Text)"]
    G --> H["Compositing (Combine Layers)"]
    H --> I["Pixels on Screen"]
  1. Parsing: Converts HTML into the DOM and CSS into the CSSOM.
  2. Style Resolution: Combines the DOM and CSSOM to determine the final styles for each visible element.
  3. Layout: Calculates the exact size and screen coordinates (x, y, width, height) for each box.
  4. Paint: Draws visual details like text, background colors, borders, and shadows into bitmap images.
  5. Compositing: Sends layers to the GPU to draw them in the correct order on screen.

What happens when the DOM changes

When JavaScript updates the page, the browser runs the necessary pipeline steps to update the screen:

update-shipment.js
const shipment = document.querySelector(".shipment");
const message = shipment.querySelector("p");

shipment.dataset.status = "arrived";
message.textContent = "Arrived at Port Klang";

Different changes trigger different amounts of work:

Type of Change Steps Triggered Reason
Changing text, width, or margin Layout \(\to\) Paint \(\to\) Composite Changing size or text moves other elements around, so the browser must recalculate positions.
Changing colors or backgrounds Paint \(\to\) Composite Box positions do not change, so the browser only repaints the pixels.
Using CSS transforms or opacity Composite The GPU can move or fade layers directly without running layout or paint again.

What frontend frameworks mean by rendering

The word "rendering" means different things depending on where it happens:

Context What It Does Output
Server or Build Step Runs templates to create HTML HTML text
Frontend Framework (React / Vue) Runs component code to find changes DOM updates
Browser Engine Calculates layout and paints pixels Pixels on screen

When state changes in React or Vue:

  1. The framework runs the component functions.
  2. It calculates what changed in the UI.
  3. It applies those updates directly to the browser DOM.

After the framework updates the DOM, the browser engine takes over to calculate layout and paint the screen.

How to debug rendering issues

To find where an issue is coming from, check each step in order:

  1. Application Data: Check that your state, props, and API responses contain the correct values.
  2. Framework Components: Use React or Vue DevTools to verify that components are updating as expected.
  3. The Live DOM: Inspect elements in browser DevTools to confirm that HTML tags, attributes, and text are present.
  4. Computed Styles: Check the DevTools Computed tab to see which CSS rule is applied.
  5. Box Layout: Check dimensions, padding, margins, and flex/grid settings.
  6. Performance Traces: Record a trace in the DevTools Performance tab to see how much time is spent on JavaScript, layout calculations, or painting.

Conclusion

HTML and CSS are parsed into the DOM and CSSOM, box sizes and positions are calculated during layout, and the GPU composites the final pixels on screen.

Frontend frameworks help manage application state and update the DOM, while the browser engine handles layout and painting. Keeping these stages in mind makes it straightforward to debug UI problems and build smooth web interfaces.

References and further reading

Open the complete reference catalog

Primary Sources