Learn Note

Why Your CSS Isn’t Working: A Friendly Guide to Specificity

Have you ever written CSS, refreshed the page…

…and nothing changed?

Yeah. Same.

I first learned about CSS specificity during a coding bootcamp I eventually had to drop out of. One of our assignments used a wall covered in graffiti. The graffiti pieces were stacked all over the page with CSS, and our job was to “clean” the wall by removing the styles that placed them there.

It was actually a clever exercise. Instead of reading a dry explanation, we could see CSS rules competing visually.

But even after that, specificity still confused me.

I understood that some CSS rules were “stricter” than others, but I kept forgetting the order. Why did one selector win? Why did another one get ignored? Why did moving a rule lower in the file sometimes work, but sometimes do absolutely nothing?

That confusion is what this post is about.


What is CSS specificity?

CSS specificity determines which CSS rule wins when multiple rules target the same element.

In plain English:

Specificity is CSS asking, “Which rule is more specific?”


The specificity ladder

From strongest to weakest:

  1. Inline styles
  2. IDs
  3. Classes, attributes, and pseudo-classes
  4. Elements and pseudo-elements

My memory trick:

Inline is the boss.
IDs are managers.
Classes are team leads.
Elements are interns.


Let’s see it in action

🔹 1. Inline styles (the BOSS)

html
<p style="color: red;">This text is red</p>

Let’s say in your index.html file, you added style="color: red;" in an HTML tag <p> like this example snippet above. Your aim is to make this particular text red.

Now, let’s write another CSS styling for <p> in your external CSS file style.css, for example:

css
p {
  color: blue;
}

Here, you want your text within the <p> tags to be blue.

👉🏻 Result: red

Even though the CSS says blue, the inline style wins because it has the highest priority. This is especially helpful if you want a specific line of text (or even a single word) to stand out in a different color (red) from the rest of the text in your file (blue).


🔹 2. ID vs Class (managers and team leads)

You’ve seen this before in other people’s HTML files, where you see an id attribute and a class attribute in HTML. Example below:

html
<p id="message" class="warning">What color am I?</p>

And then your external CSS style.css defines both the message ID and the warning class:

css
.warning {
  color: red;
}

#message {
  color: green;
}

👉🏻 Result: green

The ID selector #message is more specific than the class selector .warning, so it wins. This is especially helpful if you want a block of text to stand out from the rest on your page.

Something to keep in mind:

  • IDs = defined as is and cannot be reused in any other element
  • Classes = reusable in any element

🔹 3. Class vs Element (team leads and interns)

We are now going to compare CSS applied to a defined class and to an undefined element.

html
<p class="highlight">Hello world</p>

Here, we’re using the highlight class for this particular sentence, Hello World.

We define highlight using the CSS below in style.css:

css
p {
  color: blue;
}

.highlight {
  color: orange;
}

👉🏻 Result: orange

A class selector is more specific than an element selector, so it overrides the undefined element. The class highlight is being defined to have the color blue. You can use the highlight class to turn any text to blue within your page.


🔹 4. Same specificity → last rule wins

Sometimes, even if you move a rule lower in your CSS file, nothing changes. Other times… it suddenly works.

We’ll get into why that happens.

html
<p>Hello world</p>

Your CSS in your style.css file looks like this:

css
p {
  color: blue;
}

p {
  color: purple;
}

👉🏻 Result: purple

Both selectors are the same, so the browser uses the one that appears last.

This works a bit like overwriting a value in programming. If you assign a variable multiple times, the last value is the one that gets used.

CSS works similarly here. When two rules have the same specificity, the browser uses the last one it finds.

This is one of the easier rules to understand:

If two selectors have the same specificity, the browser uses the one that appears last.


🔹 5. When order doesn’t matter

Let’s refer back to the example for 2. IDs vs Classes. Keep in mind the order in which the selectors were written in the previous example and compare it to the one in this section.

html
<p id="message" class="warning">What color am I?</p>

Your ID and class definitions look like this:

css
#message {
  color: green;
}

.warning {
  color: red;
}

👉🏻 Result: green

Even though the warning comes later, the ID selector is stronger, so it still wins.

This is where people get confused: Order only matters when the specificity is equal. Refer to the example in 4. Same specificity → last rule wins.


🔹 6. About !important

There is a special flag we can use in CSS: !important.

When a rule has !important, it overrides normal specificity rules.

In other words, even if another selector is “stronger” (like an ID), the rule with !important will still win.

css
.warning {
  color: red !important;
}

#message {
  color: green;
}

👉🏻 Result: red

Even though #message is an ID (which is normally stronger), the .warning rule wins because of !important.

Think of !important as cutting the line. It skips the normal rules and goes straight to the front.

It works, but it can make your CSS harder to manage.

If you rely on !important too much, your styles start fighting each other instead of working together. Use sparingly.


Wrapping up

If your CSS “isn’t working,” it usually isn’t broken.

It’s just losing.

Most of the time, it comes down to three things:

  • specificity
  • order
  • and sometimes !important

Once you understand how those interact, things start to make a lot more sense.

You don’t have to memorize everything right away. Even experienced developers sometimes get tripped up by CSS.

What matters is knowing how the browser decides which rule wins. After that, debugging becomes a lot less frustrating.

This is something I struggled with for a long time, too, so if you’re confused, you’re not alone.

CSS isn’t magic. It just has rules… a lot of them.

Lately, I’ve been exploring ways to simplify CSS styling even further, especially for small projects.

But even then, understanding the basics like specificity still matters.