Reputation: 9127
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.
Upvotes: 1
Views: 992
Reputation: 723448
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.
Upvotes: 2
Reputation: 4736
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:
The next uses the incorrect syntax used by your example
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.
Upvotes: 1