Debugging CSS in devtools, which is most of the job
Most CSS problems are not solved by knowing more CSS. They are solved by looking at what the browser actually did, which is different from what you think you wrote. Beginners guess and change lines at random; experienced developers open devtools and read the answer in ten seconds.
This lesson is the ten seconds.
Opening it
F12, or Ctrl + Shift + I, or Cmd + Option + I on a Mac. Or right-click an
element and choose Inspect, which selects that element for you — usually the
fastest route.
Ctrl + Shift + C (Cmd + Shift + C) turns on the element picker directly. Point
at anything on the page and it is selected in the tree.
Dock it to the right-hand side rather than the bottom while you are learning responsive work — a narrow page next to the panel is a useful default.
The Styles panel, read properly
Select an element and the right side shows every rule that applies, most specific first. Four things to read:
Struck-through declarations. This is the big one. A line with a strike through it was overridden by something else, or was not understood at all. Hover it and devtools tells you which rule won.
A warning triangle next to a declaration means the browser did not understand it — a misspelled property, an invalid value, a bad unit. This is the answer to "why is my CSS not doing anything", and it is the reason to look here first, given that CSS never errors.
The file and line number on the right of each rule. Click it to jump to the source. If a rule you expected is not in this list at all, your selector does not match — which is a different problem from being overridden, and needs a different fix.
user agent stylesheet, which is the browser's own rules from the
defaults lesson. Seeing them here is how you find out where a margin came from.
Computed, for the final answer
The Computed tab shows one value per property: what the element actually ended
up with, after everything. No competing rules, no shorthands, no relative units —
font-size: 1.5rem appears as 24px.
Use Styles to ask why, and Computed to ask what. When somebody says "it should be 16px", Computed settles it.
Expand any property there and it shows the winning rule, plus the ones that lost. And the filter box at the top is the fastest way to answer "what is this element's line-height" without scrolling.
The box model diagram
At the bottom of the Styles panel (or in Computed) is the box diagram from the last lesson, filled in with real numbers: content, padding, border, margin.
You can edit it directly. Double-click a number and type. That is the fastest way to find the padding that looks right, before writing it in your stylesheet.
Hovering the element in the tree highlights it on the page with the same colours — blue for content, green for padding, orange for margin. When something is mysteriously not where you expect, hover it and look at the orange.
Editing live
Everything in the Styles panel is editable, and none of it is saved:
- Click a value and type. Arrow keys nudge by 1;
Shift + arrowby 10;Alt + arrow(Option) by 0.1. This is how you find a spacing value. - Click the checkbox beside a declaration to toggle it off. Excellent for "is this line the problem?"
- Click blank space inside a rule to add a new declaration, with autocomplete.
- Click
.clsto toggle a class on and off, or add one, without touching the HTML. - Click
:hovto force:hover,:focus,:activeor:focus-visible— the only practical way to style a hover state, since moving your mouse to devtools ends the real hover.
That :hov panel is worth remembering. Trying to style a dropdown that disappears
the moment you move the mouse is a rite of passage nobody needs.
The four bugs you will actually have
1. "My style is not applying"
Three causes, and devtools distinguishes them immediately:
- The rule is not in the Styles list at all → your selector does not match.
Check for the
nav > agrandchild problem, a typo in the class name, or a different element than you think. - The rule is there but struck through → something more specific won. Hover to see what.
- The declaration has a warning triangle → the browser did not understand it. Look for the typo.
2. "There is a horizontal scrollbar and I cannot find why"
In the Console:
document.querySelectorAll("*").forEach(el => {
if (el.scrollWidth > document.documentElement.clientWidth) console.log(el);
});
Hover each logged element to see it highlighted. Usually an image with no
max-width, a fixed pixel width, a min-width, 100vw, or a long unbroken
string.
3. "Where is this space coming from?"
Hover the element and read the orange margin band. If the space is above a
heading inside a box, it is almost certainly a collapsed margin escaping — the
defaults lesson covers it. If it is a mysterious gap under an image, it is the
inline-baseline gap, fixed by display: block.
4. "It works on my laptop and not on a phone"
Toggle device mode — Ctrl + Shift + M (Cmd + Shift + M). Pick a device, or
set a custom width, and reload the page, because some things only apply on load.
Crucially: device mode changes the viewport, so your media queries now behave as they will on a real phone. If they do not change at all, check the viewport meta tag — module 1's 980-pixel problem.
Throttling, which you should use more than you will want to
In the Network tab, set throttling to Slow 4G. Reload.
This is the honest test. The course's stated audience is somebody on a mid-range Android on mobile data in Pune, and on a laptop with office wifi you cannot see what they see. A hero image you never noticed becomes a three-second wait.
You can also throttle the CPU: in the Performance tab's settings, set a 4× slowdown. A phone's processor is not your laptop's.
Other panels worth knowing now
Elements → Accessibility: the accessibility tree, the computed name of an element, and the contrast ratio of any text. This is where module 5's work gets checked, and you can look now — select a heading and read its computed name.
Elements → Layout: overlays for Grid and Flexbox containers, showing line numbers and gaps. Module 3 uses this constantly and it makes Grid enormously easier to learn.
Network: every request, its status, its size, its time. Sort by size to find your biggest file, which is nearly always an image.
Lighthouse: an audit for performance, accessibility and best practices. Run it
on your own page now and then, and read the accessibility section in particular —
it catches missing alt, poor contrast and unlabelled form fields.
Console: the CSS you got wrong never appears here, but a mistyped HTML attribute or a failed request does.
Two habits
Inspect other people's sites. Everything on the web is readable. When you see a layout you like, select it and read the CSS. This is the fastest way to learn, it is entirely legitimate, and it is what everybody does.
When something surprises you, look before you theorise. The cost of checking is ten seconds and the cost of a wrong theory is an hour. Most of the time the browser did exactly what you asked, and reading the Computed value tells you what you asked for.
Check your work
Styles versus Computed. Why, versus what.
What a strike-through means. Overridden — hover to see by what.
What a warning triangle means. The browser did not understand the declaration.
What it means when a rule is absent from Styles entirely. The selector does not match, which is a different bug from being overridden.
Where a mystery margin came from. The user agent stylesheet, visible in the same list.
How to style a hover state. The :hov panel, because moving the mouse ends the
real hover.
The three arrow-key nudges. 1, Shift 10, Alt 0.1.
How to find a horizontal scrollbar's cause. The scrollWidth console snippet.
What device mode needs after switching. A reload.
What to check if media queries do not respond in device mode. The viewport meta tag.
Why throttle to Slow 4G. Because your laptop's wifi is not your visitor's connection.
Which panel checks contrast. Elements → Accessibility.
Practice
- Inspect a heading on your own page and find its rule, its file and its line.
- Find a struck-through declaration somewhere and identify what overrode it.
- Misspell a property deliberately and find the warning triangle.
- Write a selector that matches nothing and confirm the rule is absent from Styles entirely rather than struck through.
- Read a margin in the box diagram, then change it by double-clicking.
- Nudge a
paddingvalue with the arrow keys, then withShift, then withAlt. - Toggle a declaration off with its checkbox to test whether it matters.
- Add a class with
.clsand see the page change without editing HTML. - Force
:hoverwith:hovand style the hover state. - Find an element's
font-sizein Computed and compare it with theremvalue you wrote. - Cause a horizontal scrollbar with a wide image, then find it with the console snippet.
- Switch to device mode as an iPhone SE, reload, and confirm your media queries respond.
- Throttle to Slow 4G and reload. Note the slowest file.
- Run Lighthouse on your page and read the accessibility section.
- Inspect a site you admire and find out how it centres its main content.
Official documentation
- Chrome DevTools — View and change CSS — Every interaction in the Styles panel, including the ones this lesson skipped.
- Chrome DevTools — Device mode — Throttling, device emulation and the caveats about what it does not simulate.
- Firefox DevTools user docs — Firefox's Grid and Flexbox inspectors are better than Chrome's. Worth having both browsers.
Next: colours and units, and which ones are worth using.
Stuck on this lesson?
Being stuck is part of it — but being stuck alone for three days is not. Our internship programme pairs this curriculum with code review and one-to-one help from working developers, and it is free.
About the internship