Tips・When you get stuck

How to work out why your CSS isn't applying

"I wrote it and nothing changed" has four causes: it never arrived, it isn't selecting, it's losing, or it can't work there. Here's how to narrow it down from the top, with what to look at in DevTools.

You wrote CSS and the look didn’t change. This stumble always resolves if you split it into four causes and work down from the top.

  1. It never arrived (the CSS file isn’t being loaded)
  2. It isn’t selecting (the selector doesn’t reach the element)
  3. It’s losing (something else overrides it)
  4. It can’t work there (a declaration with no effect on that element or in that situation)

Rewriting at random just burns time. Deciding which stage you’re stuck at is the fastest fix there is.

TipsGetting started with developer toolsHow to open DevTools and the features to learn first

Stage 1: did the CSS arrive?

When nothing at all is applying—not one rule, but colours, spacing and type all sitting at their defaults—the file itself never arrived.

  1. Open the Network tab in DevTools
  2. With it open, reload the page
  3. Find the style.css row and look at the Status column
StatusMeaningWhat to do
200 / 304It arrivedMove to stage 2
404Not foundThe path in your link tag is wrong
403Not allowedCheck the permissions where it’s hosted

If it’s a 404, there are four things to check in the link tag.

<link rel="stylesheet" href="css/style.css">
  • The path’s levels—is it the route as seen from the HTML (css/style.css, style.css, or ../css/style.css)?
  • The spellingstyle.css and styles.css are different files
  • Upper and lower caseStyle.css and style.css can be treated as different files
  • rel="stylesheet"—leave it out and nothing loads
TipsHow to read and write pathsA 404 is almost always the path. How to write relative paths, sorted out here

Stage 2: is the selector reaching?

The CSS arrived, but only certain rules do nothing—now suspect the selector.

  1. Right-click the element you’re trying to change → Inspect
  2. Look at the Styles panel on the right
  3. Check whether your rule is listed

If it isn’t listed, your selector isn’t reaching that element. The usual causes:

  • . versus #class="card" needs .card; id="card" needs #card. Swap them and nothing matches
  • A misspelt class name—one character of difference between HTML and CSS is enough. Copy-paste to be sure
  • A forgotten .—writing card { } looks for a <card> tag
  • A space, or no space.card .title (a descendant) and .card.title (an element with both classes) mean completely different things
  • Uppercase tag names—write tag names in lowercase in CSS
  • A stray non-ASCII space—invisible to the eye. VSCode’s “zenkaku” extension colours them in

By the same logic, a missing } or a forgotten ; takes out everything after it. Run your eye down the file and see whether the colours change partway.

Stage 3: is something else beating it?

Your rule is in the Styles panel but it’s struck through—that’s “written, but losing.” When rules conflict, this order decides:

StrengthHow it’s writtenExample
Strongest!importantcolor: red !important;
StrongAn inline style<p style="color: red">
MediumAn id#title
WeakClass, attribute, pseudo-class.title / :hover
WeakestA tag nameh1

At equal strength, whichever comes later wins. So “I declared it twice on the same class and the earlier one was ignored” is another common story.

Counting is simple: how many classes you used decides most of it.

.title            { color: blue; }    /* one class */
.card .title      { color: green; }   /* two classes ← this wins */
.page .card .title { color: red; }    /* three classes ← this wins over both */

So the honest fix is making the selector of the rule you want at least as specific as the one that’s winning.

/* the theme's rule */
.card .title { color: green; }

/* yours: match it at two classes, and coming later wins */
.card .title { color: crimson; }

When tracing Styles gets tedious, the Computed tab is faster. It lists only the values that finally applied, so “what is it actually doing?” is answered at a glance.

Stage 4: declarations that can’t work there

No strike-through, and your value shows in Computed—yet the look doesn’t change. Now you’ve written a declaration with no effect in that situation. These six are the classics.

Written but does nothingWhy
width / height on a <span>Inline elements can’t take a size. Add display: block or inline-block
Top and bottom margin on a <span>Same reason—vertical values are ignored
align-items (Flexbox)With no height on the parent, there’s nothing to align within
gapIt belongs on the parent (the flex or grid container), never a child
z-indexOnly works when position isn’t static
position: stickyAn offset like top is required, and an ancestor’s overflow disables it

When there’s no typo and nothing is beating it, suspect the fit between the property and the element.

TipsThe position quick referenceHow position and z-index fit together, in this quick reference

Still nothing? Saving and caching

Sometimes the code is fine and the new CSS simply isn’t being seen.

  • Did you save?⌘ / Ctrl + S. A ”●” on the tab means unsaved
  • Are you in the right file?—two similarly named files, and you were editing the one that isn’t loaded
  • The cache⌘ + ⇧ + R / Ctrl + Shift + R reloads while ignoring it
  • A published site not changing—did the upload finish? is a server-side or CDN cache still holding the old file?

On WordPress, also suspect a caching plugin. There’s a mechanism for keeping a theme’s CSS from being remembered stale, too.

TipsThe right way to load CSS and JavaScript (wp_enqueue)How to load CSS properly in WordPress, cache-busting included

The checklist, top to bottom

  1. Did you save? (the ”●” on the tab)
  2. Reload ignoring the cache with ⌘ / Ctrl + ⇧ + R
  3. Nothing works at all → check the CSS file’s Status in Network (404 means the path)
  4. Only some rules fail → is your rule listed in Styles? (if not, it’s the selector)
  5. Listed but struck through → it’s losing. Match or exceed the winning selector’s strength
  6. No strike-through → suspect the property-element fit (inline elements, parent height, position)
  7. Has an unclosed comment or } killed everything below it?

Summary

  1. There are four causes—it never arrived, it isn’t selecting, it’s losing, it can’t work there
  2. If nothing works, check for a 404 in Network; if one rule fails, check whether it’s listed in Styles
  3. A strike-through means “losing.” The honest fix is matching the class count and coming later
  4. !important is a last resort. Leave a comment when you use it
  5. An unclosed comment or } invalidates every rule after it
TipsDon't panic when an error appearsUnlike CSS, JavaScript tells you with an error. How to read them

The awkward thing about CSS is that it silently ignores mistakes instead of raising an error. Which is exactly why the people who learn to look in DevTools are the ones who never get stuck.

FAQ

None of my CSS is applying. What should I check first?
Whether the CSS file is reaching the browser at all. Open the Network panel in DevTools, reload the page, and check that style.css doesn't show Status 404. A 404 means the path in your link tag is wrong.
Only some of my rules aren't working
Select the element in the Elements panel and look at Styles. If your rule isn't listed there, the selector isn't reaching the element. If it is listed but struck through, something else is beating it.
I saved and reloaded and nothing changed
The browser may be remembering the old CSS (the cache). Reload while ignoring the cache with ⌘ + Shift + R (Ctrl + Shift + R on Windows).
Is it okay to use !important?
Treat it as a last resort. Once you use it, overriding it later also requires !important, and the strength keeps escalating. Revisit your selectors first, and only reach for it when nothing else works.