Why this exists

A shared class is supposed to mean "this looks the same everywhere it's used." That assumption holds right up until a page has its own leftover CSS sitting in a <style> block, written for something else entirely, that happens to match the same element by accident. When that happens, nothing throws an error. The class is still applied, exactly as written. It just loses.

What it actually looked like

The site's brand wordmark - the logo and text treatment at the top of every hero section - is styled by a single shared class, .brand-mark, that renders it at a large, consistent size across the entire site. On two service pages and six location pages, it wasn't doing that. The logo icon rendered at its normal size; the text next to it rendered at roughly body-copy size - readable, but nowhere near the scale every other page showed.

Nothing in the markup was different. Every affected page had the exact same <p class="brand-mark"> structure as every unaffected page. The class was there, spelled correctly, doing nothing.

What was actually happening

Each of the eight affected pages carried its own <style> block with a rule meant for ordinary paragraph text inside that page's content area:

.service-content p, .service-content li { font-size: 0.95rem; ... }

Reasonable on its own. The problem is that .brand-mark is applied to a <p> tag, and on these eight pages that <p> happens to sit inside .service-content. Both rules matched the same element. The shared class lost - not because of where either rule was written, but because of what each selector is worth:

  • .brand-mark - one class - specificity (0, 1, 0)
  • .service-content p - one class plus one tag - specificity (0, 1, 1)

A compound selector with a tag name attached outweighs a single class, full stop, regardless of which rule appears first or which file loads last. Moving the utility class's own declaration later in the stylesheet wouldn't have changed anything - the two rules aren't tied, so source order was never the deciding factor to begin with.

The decision log

Decision 1: Rule out a markup problem before touching any CSS

The first instinct with "a class isn't working" is to assume it's missing, misspelled, or applied to the wrong element. Checking the rendered markup on an affected page confirmed class="brand-mark" was present and correct - which meant the class was being overridden, not skipped.

Decision 2: Compute specificity directly instead of guessing

Once two rules are both confirmed to match the same element, guessing which one wins from memory is exactly how this kind of bug slips through review. Writing out both selectors' specificity side by side - one class versus one class plus one tag - made the outcome unambiguous instead of assumed.

Decision 3: Reject !important

Forcing the utility class to win with !important would have fixed these eight pages immediately and made the next specificity conflict harder to reason about, since !important rules don't lose to anything short of another !important rule. The goal was a fix that stayed inside normal cascade rules, not one that opted out of them.

Decision 4: Override with deliberately higher, scoped specificity

The actual fix was a second rule - .service-content p.brand-mark - that matches only this exact situation and outweighs the page rule on its own terms: one class, one tag, and one more class, a strictly higher specificity than either of the two rules it sits between. It doesn't touch the original page rule, and it doesn't need to - it just wins where it needs to win.

Before and after

Before

  • .brand-mark (0, 1, 0) losing to .service-content p (0, 1, 1)
  • Wordmark rendering at body-copy size on 8 pages
  • Same markup, same class, silently different result page-to-page
  • No error, no warning - just a smaller logo

After

  • .service-content p.brand-mark added at (0, 2, 1)
  • Original page-scoped rule left completely untouched
  • Wordmark renders identically on every page
  • Fix scoped to exactly the elements it needs to cover

What this actually took

One additional CSS rule, added once to the shared stylesheet rather than copy-pasted into each of the eight pages individually. The harder part wasn't writing the fix - it was noticing the pattern in the first place, since the eight affected pages had nothing in common at a glance except a coincidence of markup structure that only a specificity comparison actually explained. Auditing shared CSS for conflicts like this one is part of the Web & Digital practice, especially on sites with years of accumulated page-specific styling.

Frequently asked questions

What's the fastest way to compare two selectors' specificity?

Count three numbers for each selector: ID attributes, then classes/attributes/pseudo-classes, then element tags. Compare left to right - more IDs always wins regardless of the rest, then more classes, then more tags. A single class and a class-plus-tag selector differ at the second number, so the class-plus-tag selector wins even though it "looks" simpler.

Why not just use !important and move on?

It would have worked here, but it trades a small, local problem for a permanent one: an !important rule can only be overridden by another !important rule, which means every future style intended for that element has to know to fight back the same way. A targeted, more-specific selector fixes the immediate conflict without changing the rules for anything that comes after it.

How do you find every other place a shared class might be silently losing?

Search the codebase for every selector that could plausibly match the same elements the utility class is meant to style - in this case, every page-scoped rule targeting a bare tag name that the class also gets applied to - and compare specificity for each one directly, rather than assuming a class that works on most pages works on all of them.

Wondering if a shared style is quietly losing somewhere on your own site?

It usually takes a specificity comparison, not a guess, to find out for sure.