Question

I'm restyling a third-party platform (MindTouch 4). While doing so, I'm trying to declare all the various styling properties as broadly as possible, to prevent the unintentional proliferation of natively-styled areas on the page.

The platform has a custom SELECT control, using markup like this:

<div class="mt-site-nav">
    ...
    <span class="quick-more">
        <span class="drop-link">Current Value</span>
        <ul class="dropdown">
            <li>
                <a href="...">Option 1</a>
            </li>

            <li>
                <a href="...">Option 2</a>
            </li>
        </ul>
    </span>
</div>

I wish to style the option text with font-size 14px; the native default is 12px.

So, I wrote this CSS rule:

body#myid .mt-site-nav .quick-more .dropdown { font-size: 14px; }

However, their native rule still wins when rendering the links in the menu:

@media screen { .dropdown li a { font-size: 12px; } }

In Chrome, I can see that both rules are considered when rendering links in the menu, but their rule (which is declared earlier than mine) wins. I was confused by this, since I thought I had a pretty good handle on specificity. So, I checked my understanding of the rules and manually calculated the weight of both rules.

Mine has specificity 0131 (0 inline style, 1 ID, 3 classes, 1 element name).

Native has specificity 0032 (0 inline style, 0 IDs, 1 class, 2 element names). (I am uncertain how to calculate the contribution of the media selector in the native rule.)

I don't care what base you're using for your math, "0131" is greater than "0032". So, my rule should win.

Yes, I could easily duplicate the element chain that appears in the native rule (i.e. ".dropdown li a"), but I think that's a fragile approach, and I feel it's important to set styling properties as broadly as possible, to facilitate scalability and as a preventative against native styling peeking out between the cracks.

Any help sorting this out is appreciated. I obviously have workable alternatives, so what I'm asking for here is an academic explanation of how these two rules fare in CSS weighting systems.

Thanks very much.

Was it helpful?

Solution

The subject of your selector is .dropdown:

body#myid .mt-site-nav .quick-more .dropdown

The subject of the selector within the @media screen rule is a:

.dropdown li a

Since each selector is matching a different element, specificity does not come into play. Your rule applies to the .dropdown element, and the native default applies to the a elements inside it. That's why you see that both rules are being applied. And since the font-size values are in pixels, the a elements will continue to have a 12-pixel font size.

Duplicating the li a portion is not fragile; it's a proper solution (if not the only one) to this sort of problem. Cascading happens on a per-element basis, and if you're not dealing with relative values or inheritance, then targeting the wrong elements isn't going to work as you expect.

Also, screen is a media type (and more extensively a media query), not a selector, and @media rules do not affect the cascade other than to enable or disable the rules inside them depending on whether the media applies to the browser.

OTHER TIPS

As far as I am aware, the correct syntax for the media query is:

@media screen { .dropdown li a { font-size: 12px; } }

This should solve your problem.

See these fiddles, the first uses the correct media query syntax:

http://jsfiddle.net/SE6fP/

The next uses the incorrect syntax used by your example

http://jsfiddle.net/SE6fP/1/


In additon, here is a little on CSS specifity for anyone who isn't sure how it works:

CSS specifity follows a ruleset and produces a score for each selector.

There are calculator tools available which will explain the specifity value for any give rule.

http://www.w3.org/TR/CSS21/cascade.html#specificity says that the following rules are used:

A selector's specificity is calculated as follows:

  • count 1 if the declaration is from is a 'style' attribute rather than a rule with a selector, 0 otherwise (= a) (In HTML, values of an element's "style" attribute are style sheet rules. These rules have no selectors, so a=1, b=0, c=0, and d=0.)
  • count the number of ID attributes in the selector (= b)
  • count the number of other attributes and pseudo-classes in the selector (= c)
  • count the number of element names and pseudo-elements in the selector (= d)

The specificity is based only on the form of the selector. In particular, a selector of the form "[id=p33]" is counted as an attribute selector (a=0, b=0, c=1, d=0), even if the id attribute is defined as an "ID" in the source document's DTD.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top