Loading views...

How CSS Works

An interactive guide to how browsers style the web

CSS isn't paint - it's rules. The browser reads your HTML and CSS, builds internal trees, calculates layouts, paints pixels, and composites layers. Understanding this pipeline helps you write better, faster stylesheets.

CSS Parsing

The browser transforms CSS text into a structure it can work with

Pipeline: CSS Text → Tokens → CSSOM Tree → Combined with DOM → Render Tree → Layout → Paint → Composite

Tokens

SELECTOR: .box
PROPERTY: color
VALUE: blue
PROPERTY: font-size
VALUE: 16px

CSSOM Tree

.box
├─ color: blue
└─ font-size: 16px

DOM + CSSOM → Render Tree

The browser combines HTML structure (DOM) with styles (CSSOM) to build what actually renders

Common misconception: People assume display:none and visibility:hidden work the same way. They don't - one removes the element from the render tree entirely, the other keeps it but makes it invisible.

DOM Tree

div.container
├─ div.box-1
├─ div.box-2
└─ div.box-3

CSS Rules

Render Tree

div.container
├─ div.box-1
├─ div.box-2
└─ div.box-3

Visual Result

Box 1
Box 2
Box 3

Toggle checkboxes above to see the difference

Cascade & Specificity

When multiple rules target the same element, specificity decides the winner

Misconception: !important is a quick fix. Reality: It breaks the cascade and makes future overrides nearly impossible without more !important declarations.

Toggle Selectors

Winner

Box
Class (.box)
Specificity: 0-0-1-0

Higher specificity = Higher priority (Inline > ID > Class > Element)

Why !important is dangerous

It overrides all specificity. The only way to override !important is with another !important, creating cascading conflicts that are hard to debug.

Inheritance

Some CSS properties are inherited from parent to child, others are not

Parent Properties

Parent
Child Element
✓ Inherited: color, font-size
✗ Not inherited: border, padding

Typography properties (color, font-size, font-family) inherit by default. Box model properties (padding, margin, border) do not.

Authored vs Computed Styles

What you write isn't what the browser uses

The browser resolves inheritance, defaults, and relative units into absolute computed values. This is what actually gets applied to elements.

Authored CSS (What You Write)

.button {
font-size: 1rem;
padding: 0.5em 1em;
width: 50%;
color: inherit;
}

Computed Styles (What Browser Uses)

.button {
font-size: 16px;
padding: 8px 16px;
width: 400px;
color: rgb(33, 37, 41);
}

Use DevTools Computed tab to see what values the browser actually uses. This helps debug unexpected behavior caused by inheritance or unit conversion.

Box Model

Every element is a box: content + padding + border + margin

Adjust Values

20px
4px
20px
Margin (20px)
Border (4px)
Padding (20px)
Content
Content
100 × 60px
+ Padding
40px
+ Border
8px
+ Margin
40px

Layout Engines

How browsers position elements on the page

Every element has a containing block that determines its positioning context. Absolute positioning confuses developers because it positions relative to the nearest positioned ancestor, not the parent.

Block vs Inline Elements

Block elements (stack vertically):
Block 1 (100% width)
Block 2 (100% width)
Block 3 (100% width)
Inline elements (flow horizontally):
Inline 1Inline 2Inline 3
Margin collapsing (vertical margins collapse):
Box 1 (margin-bottom: 20px)
Box 2 (margin-top: 30px)
Actual gap: 30px (not 50px!) - the larger margin wins

Misconception: Margins add together. Reality: Adjacent vertical margins collapse to the larger value. Horizontal margins never collapse.

Positioning & Containing Blocks

Understanding how absolute positioning actually works

Absolute elements position relative to their containing block, the nearest ancestor with position other than static. If none exists, they use the viewport (initial containing block).

Parent (position: static)
Absolute Child
position: absolute

Static parent: absolute child positions relative to viewport (page edge)

Containing Block

The rectangle that contains an element and determines its positioning context.

  • • Static/Relative: parent's content box
  • • Absolute: nearest positioned ancestor
  • • Fixed: viewport (browser window)

Viewport

The visible area of the web page in the browser window.

  • • Fixed elements stick to viewport
  • • Viewport units: vw, vh, vmin, vmax
  • • Initial containing block

Common mistake: Using position: absolute without a positioned parent. Always ensure the parent has position: relative if you want predictable positioning.

Paint & Composite

Different CSS properties trigger different rendering stages

Layout changes are expensive because they affect element positions. Paint is cheaper - just pixels. Composite is cheapest - GPU moves existing layers around.

Box

Color (Paint only)

✗ Layout
✓ Paint
✗ Composite

Width (Layout + Paint)

200px
✓ Layout
✓ Paint
✗ Composite

Transform (Composite only)

0px
✗ Layout
✗ Paint
✓ Composite
Layout
Recalculates positions and sizes
Most expensive - avoid in animations
Paint
Draws pixels to layers
Moderate cost - CPU work
Composite
Combines layers (GPU)
Cheapest - hardware accelerated

Reflow vs Repaint

See which rendering pipeline stages run for different property changes

Element

Rendering Pipeline

Layout
Idle
Paint
Idle
Composite
Idle

Reflow (Layout)

Triggered by changes to:
  • • width, height
  • • padding, margin, border
  • • position, top, left
  • • font-size, line-height

Repaint (Paint only)

Triggered by changes to:
  • • color, background-color
  • • visibility
  • • outline
  • • box-shadow

CSS & Accessibility

Visual styling affects how assistive technologies work

CSS can enhance or break accessibility. Focus styles, contrast, and visibility matter for screen readers and keyboard navigation.

Focus Styles

❌ Bad

Keyboard users can't see where they are

✓ Good

Visible focus indicator for navigation

Color Contrast

❌ Bad (2.5:1)

This text is hard to read

✓ Good (7:1)

This text is easy to read

WCAG AA requires 4.5:1 contrast for normal text, 3:1 for large text

Hidden vs Visually Hidden

display: none

Hidden from everyone, including screen readers

visibility: hidden

Hidden from everyone, takes up space

clip-path / sr-only pattern

Visually hidden, but readable by screen readers

position: absolute;
width: 1px; height: 1px;
overflow: hidden;
clip: rect(0,0,0,0);

Common CSS Accessibility Issues

×

Removing focus outlines globally

outline: none breaks keyboard navigation

×

Using color alone for meaning

Color-blind users can't distinguish

×

Tiny clickable areas

Minimum 44×44px touch targets recommended

×

Fixed font sizes (px only)

Users can't scale text with browser zoom

Test your CSS with keyboard navigation (Tab key), screen readers (VoiceOver, NVDA), and browser DevTools accessibility audits.

Browser Differences

CSS is a specification - browsers implement it

Modern browsers follow the same CSS specs (W3C/WHATWG), but small differences exist in rendering engines, default styles, and vendor prefixes.

Blink
Chrome, Edge, Opera, Brave
Most popular engine. Good standards support.
Gecko
Firefox
Strong standards focus. Implements specs early.
WebKit
Safari
Apple's engine. Sometimes slower to adopt new features.

Why Differences Exist

1.

Different rendering engines

Each browser uses different C++/Rust code to parse and render CSS

2.

Feature implementation timing

New CSS features roll out at different speeds across browsers

3.

Default user-agent styles

Each browser has different built-in styles for HTML elements

4.

Vendor prefixes (legacy)

-webkit-, -moz-, -ms- for experimental features

Common Differences

  • • Form element styling (buttons, inputs)
  • • Scrollbar appearance
  • • Sub-pixel rendering
  • • Font rendering (antialiasing)
  • • Flexbox/Grid edge cases

How to Handle It

  • • Use CSS resets (Normalize.css)
  • • Test in multiple browsers
  • • Check caniuse.com for support
  • • Use feature queries (@supports)
  • • Avoid bleeding-edge features

Good news: Modern browsers converge on standards. Most CSS works identically across Chrome, Firefox, Safari, and Edge today.

Performance Tips

CSS properties have different performance costs

Property Performance Heatmap

transform
Composite
opacity
Composite
color
PaintComposite
background
PaintComposite
box-shadow
PaintComposite
width
LayoutPaintComposite
height
LayoutPaintComposite
margin
LayoutPaintComposite
padding
LayoutPaintComposite
top/left
LayoutPaintComposite

Cheap

Use for animations

  • • Runs on GPU
  • • 60fps easily
  • • No layout/paint
transform, opacity

Moderate

Use sparingly

  • • Repaints pixels
  • • No layout changes
  • • Can drop frames
color, background

Expensive

Avoid in animations

  • • Triggers reflow
  • • Affects other elements
  • • Very slow
width, height, margin

Pro Tip

For smooth 60fps animations, stick to transform and opacity. These properties are GPU-accelerated and don't trigger layout or paint.

Further Learning

Want to go deeper? These resources explain CSS internals, specs, and browser rendering in detail.

MDN Web Docs

Comprehensive CSS reference with browser compatibility tables

developer.mozilla.org/CSS →

W3C CSS Specifications

The official specs that define how CSS should work

w3.org/Style/CSS →

CSS Triggers

See which CSS properties trigger layout, paint, or composite

csstriggers.com →

Can I Use

Check browser support for CSS features across versions

caniuse.com →

Recommended Reading

  • • Browser rendering: How browsers work (Tali Garsiel & Paul Irish)
  • • CSS containment and layers for better performance
  • • The CSSOM and how JavaScript interacts with styles
  • • CSS custom properties (variables) and the cascade