How can I count the rule specificity in CSS? I know the basic things (1000 for style, 100 for id, 10 for att/class, etc.) However, I still get stuck too many times with simple things, example:
How much would this be?
<div class="wrapper">
<div class="inner"></div>
</div>
.wrapper > div /* ??? */
.inner /* 10 */
The first rule is applied, obviously. But how much is it?
Basically, it's like this:
!important styles always override all other styles, but amongst !important styles, specificity rules do apply
Inline styles get 1000 "specificity" points
IDs get 100 points
(pseudo-)classes and attribute selectors get 10 points
tag selectors get 1 point
If there are selectors with equal specificity, the rule that is defined last on the page will override the other rules.
The universal selector * and inherited styles gets no specificity points.
Also, this site might be useful for you. It explains it a bit further.
After testing these rules for myself, I've noticed that this is not exactly true. The order in which the specificity is applied does still hold true, but going by this test, it is not true that it actually works with this points system like most sites I know claim. What seems to be more accurate is putting the styles in "boxes". It would still use the order of "boxes" I listed above, but instead count each "box", and if there is an equal amount of selectors in that group, check the next one. It would then work like this:
!important styles are in box 1. These styles override all other styles. If there are multiple declarations of the same style that both have the !important rule, then the style in the next highest box will be looked at.
inline styles are in box 2. Inline styles will override all other styles. If there are multiple declarations of inline styles, the one defined last will apply.
ID selectors are in box 3. If there are multiple declarations of the same style, with the same amount of ID selectors, the next highest box will be looked at.
(pseudo-)classes and attribute selectors are in box 4. I think you get the story what happens when there are multiple of the same style with an equal amount of this selector...
tag selectors are in box 5. ...
universal selectors are in box 6. This box behaves a bit differently though, since adding more universal selectors does not increase specificity, as can be seen here, so only the order of definition applies in this box. Styles applied with an universal selector do override inherited styles though.
If no styles have been assigned directly to the element, inherited styles might apply, depending on what style it is.
So basically, if we have a style with 1 id selector at the top of our stylesheet, and below that a style with more than 10 class selectors, the style with the id selector will still apply. The style with the id selector "won the battle" in box 3, so the further boxes are ignored. The specificity calculator Fabrício Matté linked to illustrates really well.
PS: using + or > or ~ or any other operator won't affect specificity at all. These styles have exactly as much specificity (so the latter will apply):
div > span {color:red;}
div span {color:blue;}
Related
I'm trying to figure out why one of my css classes seems to override the other (and not the other way around)
Here I have two css classes
.smallbox {
background-color: white;
height: 75px;
width: 150px;
font-size:20px;
box-shadow: 0 0 10px #ccc;
font-family: inherit;
}
.smallbox-paysummary {
#extend .smallbox;
font-size:10px;
}
and in my view I call
<pre class = "span12 pre-scrollable smallbox-paysummary smallbox ">
The font (The overlapping element) shows up as 10px instead of 20 - could someone explain why this is the case?
There are several rules ( applied in this order ) :
inline css ( html style attribute ) overrides css rules in style tag and css file
a more specific selector takes precedence over a less specific one
rules that appear later in the code override earlier rules if both have the same specificity.
A css rule with !important always takes precedence.
In your case its rule 3 that applies.
Specificity for single selectors from highest to lowest:
ids (example: #main selects <div id="main">)
classes (ex.: .myclass), attribute selectors (ex.: [href=^https:]) and pseudo-classes (ex.: :hover)
elements (ex.: div) and pseudo-elements (ex.: ::before)
To compare the specificity of two combined selectors, compare the number of occurences of single selectors of each of the specificity groups above.
Example: compare #nav ul li a:hover to #nav ul li.active a::after
count the number of id selectors: there is one for each (#nav)
count the number of class selectors: there is one for each (:hover and .active)
count the number of element selectors: there are 3 (ul li a) for the first and 4 for the second (ul li a ::after), thus the second combined selector is more specific.
A good article about css selector specificity.
Here's a compilation of CSS styling order in a diagram, on which CSS rules has higher priority and take precedence over the rest:
Disclaimer: My team and I worked this piece out together with a blog post (https://vecta.io/blog/definitive-guide-to-css-styling-order) which I think will come in handy to all front-end developers.
What we are looking at here is called specificity as stated by Mozilla:
Specificity is the means by which browsers decide which CSS property
values are the most relevant to an element and, therefore, will be
applied. Specificity is based on the matching rules which are composed
of different sorts of CSS selectors.
Specificity is a weight that is applied to a given CSS declaration,
determined by the number of each selector type in the matching
selector. When multiple declarations have equal specificity, the last
declaration found in the CSS is applied to the element. Specificity
only applies when the same element is targeted by multiple
declarations. As per CSS rules, directly targeted elements will always
take precedence over rules which an element inherits from its
ancestor.
I like the 0-0-0 explanation at https://specifishity.com:
Quite descriptive the picture of the !important directive! But sometimes it's the only way to override the inline style attribute. So it's a best practice trying to avoid both.
The order in which the classes appear in the html element does not matter, what counts is the order in which the blocks appear in the style sheet.
In your case .smallbox-paysummary is defined after .smallbox hence the 10px precedence.
First of all, based on your #extend directive, it seems you're not using pure CSS, but a preprocessor such as SASS os Stylus.
Now, when we talk about "order of precedence" in CSS, there is a general rule involved: whatever rules set after other rules (in a top-down fashion) are applied. In your case, just by specifying .smallbox after .smallbox-paysummary you would be able to change the precedence of your rules.
However, if you wanna go a bit further, I suggest this reading: CSS cascade W3C specification. You will find that the precedence of a rule is based on:
The current media type;
Importance;
Origin;
Specificity of the selector, and finally our well-known rule:
Which one is latter specified.
Also important to note is that when you have two styles on an HTML element with equal precedence, the browser will give precedence to the styles that were written to the DOM last ... so if in the DOM:
<html>
<head>
<style>.container-ext { width: 100%; }</style>
<style>.container { width: 50px; }</style>
</head>
<body>
<div class="container container-ext">Hello World</div>
</body>
...the width of the div will be 50px
AS is state in W3:
W3 Cascade CSS
the orden that different style sheet are applied is the following (quote from W3 cascading section):
user agent declarations
user normal declarations
author normal declarations
author important declarations
user important declarations
More information about this in the referred W3 document
Element, Pseudo Element: d = 1 – (0,0,0,1)
Class, Pseudo class, Attribute: c = 1 – (0,0,1,0)
Id: b = 1 – (0,1,0,0)
Inline Style: a = 1 – (1,0,0,0)
Inline css ( html style attribute ) overrides css rules in style tag and css file
A more specific selector takes precedence over a less specific one.
Rules that appear later in the code override earlier rules if both have the same specificity.
In a simple and short way, one should keep in mind the two things below:
Inline CSS has a higher priority than embedded and external CSS.
So final Order is: Value defined as Important > Inline > id nesting > id > class nesting > class > tag nesting > tag
I'm running a website on Wordpress. Whenever I have to do CSS, I go onto Appearance > Custom CSS. To find the element I want to target I use the Inspect tool.
However on this instance there is no element ID. As this a small browser window for allowing card payment, I cannot find the div ID using Inspector.
IMAGES
Not OK to CSS
OK to CSS
You may want to give the CSS Selector documentation a read. There are many ways to select an element without a distinct Class or ID, including by attribute, type, and even Combinators (which are probably the best way to solve this problem you're having).
You can start be selecting an ancestor of the element you want, such as the.woocommerce wrapper.
You could then use the Direct Child Combinator: > and select the .order_details element.
Now you can use the Adjacent Sibling Combinator: + to select the div that is its adjacent sibling.
(Note that the adjacent sibling combinator is used here, not the General Sibling Combinator: ~, otherwise it would select all divs that are a later sibling of .order_details.
The following selector would probably be more than sufficient, and perhaps even a bit more specific than it needs to be (you may not need the >, but I put it in there for good measure - when using combinators on elements with no id or class, adding another layer of specificity usually doesn't hurt)
.woocommerce > .order_details + div { /* Styles here*/ }
If you're trying to override any of the inline styles on that div, you'll need to be more careful about the Specificity of the selector. Generally speaking there are 4 levels of specificity:
inline - ID - class - element
The Selector I gave you above has a specificity of 0021 (no inline, no ID, 2 classes, 1 element). However after your comment, it looks like you're trying to overwrite an inline style which has a gargantuan specificity of 1000. So if you apply any CSS that's not already defined inline, it should handily take effect. If you're changing any of the inline styles themselves, you'll need to make use of the _generally, but not always, bad-practice: !important Exception. Using !important will actually add a fifth order of magnitude to your specificity:
!important - inline - ID - class - element
So, if you're trying to change your inline background color, using the following:
.woocommerce > .order_details + div { background-color: #0095ee !important; }
Will give your blue background color an astounding 10021 specificity, which is higher than the inline grey's 01000.
Be very careful not to overuse !important - it's a tool that should be reserved for situations like this, and not just because you have a few CSS rules above that are slightly more specific.
Here's a handy CSS Specificity list, and a handy CSS Specificity calculator.
I originally noticed this problem when working with CSS in an SVG file, and thought it was rendering error, but after trying it in HTML, the same situation occurred.
Take the following code:
.example {color:green}
.example {color:blue}
In this case, as expected using normal class selectors, the value of color is initially green, though later in the file it is redefined as blue, thus the resulting color of elements in the class are blue.
Now take this example:
div[class='example'] {color:green}
.example {color:blue}
In this case, now initially defining the color value for divs in example using attribute selectors, when the value is redefined using normal CSS class selectors, the change from green to blue is ignored in the divs, and the value set by the attribute selector takes precedence, despite the blue color value for the whole class being redeclared later in the file.
According to Mozilla documentation on CSS class selectors, it says normal selectors and attribute selectors are "equivalent", though that doesn't appear to be the case in this situation. What is the cause of this?
I'd originally posted this as a comment, but perhaps I should've made it answer.
Let's look at the actual conditions of your two CSS rules:
div[class='example'] {color:green}
Element must be a <div>
Element must have class "example"
.example {color:blue}
Element must have class "example"
Because your first CSS rule has two conditions, whereas your second rule only has one, the first rule is more specific - therefore it will take precedence.
If you were to remove the div portion from your first rule, it would be considered equivalent (as MDN states), at which point the text would be blue.
Mozilla documentation is correct.
But when considering specificity, you need to take in to the account div and [class='example'].
These two combined are stronger than .example.
Here is an nice representation of specificity:
https://www.smashingmagazine.com/2007/07/css-specificity-things-you-should-know/
If you go and open smasingmagazine.com articele, you will conclude that:
.example has power of 10
Whereas div[class='example'] has power of 11
I have constructed a mock-up of a hierarchical menu system, where the main menu (#moduleMenu1) has a sub-menu (#moduleMenu2), and they both share a CSS class. When I use ID selectors on the menus, all is well (http://jsfiddle.net/stamminator/pwnuymd2/1). However, when I switch to using a class selector, which would be much more elegant (especially if I add a third hierarchy to the menus), the selectors are being overwritten (http://jsfiddle.net/stamminator/pwnuymd2/).
I suppose I can use !important on every property in my styles, but assuming I'll need to have a page which overwrites those styles on an as-needed basis at some point, this isn't a great solution either. Is there a third option besides id selectors or !important that is available?
I'm not sure if this is related, but I've noticed a second problem as well. When I have the HTML files open locally and do a selector in Chrome's JavaScript console on their shared class, I would expect to get back both elements. Instead, I only get back one.
//what I typed into the console:
$(".moduleMenu");
//my result:
<div id="moduleMenu1" class="moduleMenu">
<div>
Proposal
Browse
Financial
Documents
</div>
</div>
//where's #moduleMenu2? They both have the same CSS class
Here is a link so you can download the files and run it in your own debugger if you'd like: https://onedrive.live.com/redir?resid=9F7FCE5CCA52BABF!33812&authkey=!ANi0Ivf0BbmVbGk&ithint=file%2czip.
The JavaScript console issue is a non-issue I suppose, but I figured I'd mention it in case it's related. Any help I can get in getting my CSS working properly would be much appreciated!
ID selectors are of higher importance than class selectors. You should almost never use IDs in CSS. Change your ID selectors to class selectors (even if they're unique) and be happy.
<div id="moduleMenu1" class="moduleMenu moduleMenu1">
Demo
Of course, some of your listed selectors can now be combined.
Demo 2
As mentioned by isherwood, ID selectors take priority over class selectors. This is due to CSS specificity, which is the way CSS determines which rules are applied to an element.
The simplest way to explain CSS specificity is:
!important > inline > ID > class > element > universal & inherited
For a slightly more in-depth explanation, CSS specificity is stored as four separate integers. When no styles are applied to an element (or only universal and inherited rules are applied), the values for that element are 0,0,0,0.
The first value represents inline styles
The second value represents ID style rules
The third value represents class or attribute style rules
The fourth value represents tag style rules
1,0,0,0 overrides 0,1,0,0: an inline style will always override an ID style rule. Likewise, an ID will always override a class. However, 0,1,1,0 overrides 0,1,0,0, so a class and an ID in a rule will override the ID rule.
With the exception of some older browsers that roll over values after 255, there is no number of classes that can override an ID: the only way to override an ID style rule is with an ID, inline styles, or the !important flag.
I usually trace my CSS stylesheet by using the Chrome web browser.
I can see that some of my styles are being ignored by the inspection window of Chrome - the style is struck out with a black line.
I cannot see why it is being ignored. Usually, I follow all the styles using my eyes to see why it is ignored.
Can I know the structure (inheritance) information by Chrome or by other method?
In Short, Specificity
From CSS Specificity: Things You Should Know:
Specificity determines, which CSS rule is applied by the browsers.
Specificity is usually the reason why your CSS-rules don't apply to some elements, although you think they should.
Every selector has its place in the specificity hierarchy.
If two selectors apply to the same element, the one with higher specificity wins.
There are four distinct categories which define the specificity level of a given selector: inline styles, IDs, classes+attributes and elements.
You can understand specificity if you love Star Wars: CSS Specificity Wars.
You can understand specificity if you love poker: CSS Specificity for Poker Players.
When selectors have an equal specificity value, the latest rule is the one that counts.
When selectors have an unequal specificity value, the more specific rule is the one that counts.
Rules with more specific selectors have a greater specificity.
The last rule defined overrides any previous, conflicting rules.
The embedded style sheet has a greater specificity than other rules.
ID selectors have a higher specificity than attribute selectors.
You should always try to use IDs to increase the specificity.
A class selector beats any number of element selectors.
The universal selector and inherited selectors have a specificity of 0, 0, 0, 0.
You can calculate CSS specificity with CSS Specificity Calculator.
For example
If you had a p with class a, what would you predict it's color would be based on the following rules:
p.a { color: red; }
.a { color: blue; }
If you said blue, you'd be wrong!
As Alochi pointed out, if you're looking for more of a Tree View of the styles hit by a particular element, in the Chrome Developer Tools, go to the computed tab and expand the property you're interested in. You'll get a full list of all the other rules that apply to that element with a link to each. From what you know about specificity and cascading, it should be clearer why the "winner" was chosen.
I generaly find Firebug for Firefox, a little more featrured for debugging CSS.
Selecing an element and viewing the computed tab will show where a particular style is coming from. That will then help with the question of "why".
Most web developers are aware of the cascading nature of style shees and how that works: Inline > Page > Sheet. That is which ever is declare last is applied. What not as many developers are aware of is specifity.
http://css-tricks.com/specifics-on-css-specificity/
http://www.htmldog.com/guides/css/intermediate/specificity/
In a nut shell the more specific the selector, the higher priority.
E.g #anID.aClass will overide p.aClass will overide .aClass
Kyles' answer has more on specificty