Ad – 728×90
🎨 Introduction

How CSS Works – Inside the Browser's Rendering Engine

You write a CSS file, the browser reads it, and suddenly text is blue and buttons are rounded. But what actually happens between those two steps? Understanding how the browser parses and applies CSS will help you write better styles, debug problems faster, and avoid the performance pitfalls that slow websites down. In this lesson you will trace the full path from a .css file to a painted pixel on screen.

⏱️ 18 min read 🎯 Beginner 📅 Updated 2026 👁️ Lesson 2 of 4

The Browser's 5-Step Rendering Process

When you open a web page, the browser performs five major steps to go from raw files to a visible page:

  1. Parse HTML → Build the DOM — the browser reads the HTML and builds a tree of objects called the DOM (Document Object Model). Each tag becomes a node in this tree.
  2. Parse CSS → Build the CSSOM — the browser reads all CSS (from <link> tags, <style> tags, and inline styles) and builds the CSSOM (CSS Object Model), a parallel tree of style rules.
  3. Combine → Create the Render Tree — the browser merges the DOM and CSSOM. Invisible elements (like display: none) are excluded. The result is a render tree of only visible content with their computed styles.
  4. Layout (Reflow) — the browser calculates the exact position and size of every element on the page, based on the render tree and the viewport dimensions.
  5. Paint — pixels are drawn to the screen. Background colors, text, borders, shadows — everything gets painted in the correct order.
💡
Why this matters for performance

Steps 4 and 5 (layout and paint) are expensive operations. CSS rules that trigger layout (like changing width or margin) are slower than rules that only trigger paint (like changing color). Rules that trigger only the GPU compositor layer (like transform and opacity) are fastest of all — use them for animations.

The DOM and CSSOM — Two Trees, One Page

The DOM is the browser's internal representation of your HTML. The CSSOM is the browser's internal representation of your CSS. They are separate trees that get merged to produce the visual result.

Here is a simple HTML + CSS example:

HTML
<!DOCTYPE html>
<html>
  <head>
    <link rel="stylesheet" href="styles.css">
  </head>
  <body>
    <h1>Hello, CSS!</h1>
    <p class="intro">This is my first styled page.</p>
  </body>
</html>
CSS (styles.css)
h1 {
  color: #1572B6;
  font-size: 2rem;
}

.intro {
  color: #555;
  font-size: 1.1rem;
  line-height: 1.6;
}

The browser builds these two trees from that code:

DOM tree (simplified)
html
 └── head
 │    └── link[rel=stylesheet]
 └── body
      ├── h1 → "Hello, CSS!"
      └── p.intro → "This is my first styled page."
CSSOM tree (simplified)
StyleSheet
 ├── Rule: h1 → { color: #1572B6, font-size: 2rem }
 └── Rule: .intro → { color: #555, font-size: 1.1rem, line-height: 1.6 }

The browser then matches DOM nodes to CSSOM rules. The <h1> node gets the h1 rule. The <p class="intro"> node gets the .intro rule. Together they form the render tree and the final visual output.

Ad – 336×280

Where Does CSS Come From?

When building the CSSOM, the browser collects CSS from three sources:

1. External Stylesheet

The most common source. A separate .css file linked in the <head>:

HTML
<link rel="stylesheet" href="styles.css">

This is best practice for production sites — one stylesheet file can be cached by the browser and shared across every page.

2. Internal Style Block

CSS written inside a <style> tag in the HTML <head>:

HTML
<style>
  h1 { color: navy; }
  p { line-height: 1.6; }
</style>

Useful for single-page demos or page-specific styles, but not cacheable across pages.

3. Inline Styles

CSS written directly on an HTML element via the style attribute:

HTML
<p style="color: red; font-weight: bold;">This is inline styled.</p>

Inline styles have the highest specificity (outside of !important) and override both external and internal styles. They are hard to maintain at scale — avoid them for production code.

How CSS Inheritance Works

One of CSS's most powerful features is inheritance. Many CSS properties, when set on a parent element, automatically pass down to all child elements.

CSS – Inheritance example
body {
  font-family: Arial, sans-serif;
  color: #333;
  line-height: 1.6;
}
HTML
<body>
  <h1>This heading inherits font-family and color</h1>
  <p>This paragraph too — all text in the body inherits these styles.</p>
  <div>
    <span>Deeply nested — still inherits.</span>
  </div>
</body>

Properties that inherit by default include: color, font-family, font-size, font-weight, line-height, letter-spacing, text-align, visibility.

Properties that do not inherit by default: background-color, border, margin, padding, width, height, display, position.

ℹ️
Force inheritance with inherit

Any property can be forced to inherit from its parent by setting its value to inherit. For example: border: inherit; makes the border of a child match the parent's border.

Reflow vs Repaint — Why Your CSS Performance Matters

Not all CSS changes are equal in cost. When you change a CSS property with JavaScript or CSS, the browser may need to:

  • Reflow (Layout) — recalculate positions and sizes. Triggered by changes to: width, height, margin, padding, font-size, display, position. This is expensive — it invalidates the layout of the entire page (or a large portion).
  • Repaint — redraw pixels without recalculating layout. Triggered by: color, background-color, border-color, box-shadow. Cheaper than reflow.
  • Compositor only — handled entirely by the GPU without touching layout or paint. Only transform and opacity qualify. This is why CSS animations using transform are smooth even on mobile.
CSS – Prefer transform over position for animations
/* Slow – triggers reflow on every frame */
.bad-animation {
  animation: move-bad 1s infinite;
}
@keyframes move-bad {
  from { left: 0; }
  to   { left: 200px; }
}

/* Fast – compositor only, no reflow */
.good-animation {
  animation: move-good 1s infinite;
}
@keyframes move-good {
  from { transform: translateX(0); }
  to   { transform: translateX(200px); }
}

📋 Summary

  • The browser builds a DOM from HTML and a CSSOM from CSS, then merges them into a render tree.
  • CSS comes from three sources: external stylesheets (best), internal style blocks, and inline styles (highest specificity).
  • Many CSS properties inherit from parent to child automatically (color, font-family, line-height).
  • CSS changes can trigger reflow (expensive), repaint (cheaper), or compositor only (fast) — use transform and opacity for smooth animations.
  • Understanding the rendering pipeline helps you write performant CSS and debug styling issues more effectively.

Frequently Asked Questions

What is the CSSOM? +

The CSSOM (CSS Object Model) is the browser's internal tree-structured representation of all CSS rules. Just as the DOM represents HTML as a tree of nodes, the CSSOM represents CSS as a tree of style rules. The browser builds the CSSOM by parsing all CSS sources (external files, internal style blocks, inline styles) and then uses it together with the DOM to compute final styles for each element.

Does CSS block page rendering? +

Yes — CSS is a render-blocking resource. The browser will not display the page until it has downloaded and parsed all linked CSS files. This is why it's important to keep your CSS files small and load only what you need. You can use media attributes (media="print") to mark stylesheets as non-blocking for non-matching media types, and use tools to inline critical CSS in the <head> for fastest initial paint.

What is reflow and why should I care? +

Reflow (also called layout) is when the browser recalculates the position and size of all affected elements. It happens when you change a CSS property that affects layout (width, height, margin, padding, font-size). Reflow is expensive — it can cause visual "jank" (stuttering) in animations and scrolling. You can minimize reflow by batching DOM changes, using CSS transforms instead of position changes for animations, and avoiding reading layout properties (like offsetWidth) immediately after writing to them in JavaScript.

Why does my CSS not apply sometimes? +

The most common reasons: (1) Specificity — another rule with higher specificity is overriding yours. Open DevTools and check the computed styles. (2) Inheritance — the property does not inherit and you have not set it directly. (3) Typo — a misspelled property or selector silently fails. (4) Cascade order — a later rule with equal specificity is winning. (5) Wrong selector — the selector is not matching the element you think it is. Use DevTools (F12 → Elements panel) to inspect computed styles and see exactly which rules apply.