I have 2 stylesheet files, style.css, and index.css which are loading respectively
1-style.css
2-index.css
in my style.css I have code like this
#mainNav nav > a:hover span:before {
background-color: transparent !important;
}
#mainNav nav a.darkBlue span:before {
background-color: #17729a;
}
now in my index.css
when I write
#mainNav .darkBlue span:before {
background-color: transparent;
}
It doesnt work and I should write !important at the end to make it work
but when I write selectors order in a different way like the way I used in my style.css it works without !important
like this
#mainNav nav a.darkBlue span:before {
background-color: transparent;
}
Why?
CSS has a hierarchy. If you you wanna overwrite some styles you have to use the same selectors or some more specific.
Example:
a.selector { color: blue }
.selector { color: red }
The color will not be changed.
But
.selector { color: blue }
a.selector { color: red }
will change the color to red, because the combination of TAG and class selector you are more specific.
Your declarations are being applied based on how specific they are.
Per MDN - Specificity:
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 a weight that is applied to a given CSS declaration, determined by the number of each selector type in the matching selector.
The link above also goes into the factors that determine specificity:
The following list of selector types increases by specificity:
Type selectors (e.g., h1) and pseudo-elements (e.g., ::before).
Class selectors (e.g., .example), attributes selectors (e.g., [type="radio"]) and pseudo-classes (e.g., :hover).
ID selectors (e.g., #example).
Universal selector (*), combinators (+, >, ~, ' ') and negation pseudo-class (:not()) have no effect on specificity. (The selectors declared inside :not() do, however.)
CSS chooses which rules to apply based on a few conditions. Given rules applying to the same element, they are regarded in the following order:
1. !important
span { color: red; } /* base */
#mySpan { color: blue; } /* specific */
span { color: green !important; } /* important */
<span id="mySpan" style="color: purple;">Example</span>
2. Inline styles
span { color: red; } /* base */
#mySpan { color: blue; } /* specific */
<span id="mySpan" style="color: purple;">Example</span>
3. Specificity
span { color: red; } /* base */
#mySpan { color: blue; } /* specific */
<span id="mySpan">Example</span>
4. Last declared
span { color: red; } /* base */
span { color: yellow; } /* last applied */
<span>Example</span>
It's generally best to avoid using !important wherever possible. If you throw them around carelessly, there may come a time when you actually need to override one, but you've already used your highest order of precedence.
You have something called CSS specificity:
https://www.w3schools.com/css/css_specificity.asp
A really great read on what comes first and the order of specificity: check https://www.smashingmagazine.com/2007/07/css-specificity-things-you-should-know/
Be aware, it's a loooong article. Most people don't even have the slightest idea of how far this goes.
Simply put: If two CSS selectors apply to the same element, the one
with higher specificity wins.
That's why I follow the BEM methodology, this prevents these kinds of hassles.
Related
I'd like to understand how CSS selectors work with property collisions. How is one property selected over another one?
div {
background-color: red;
}
div.my_class {
background-color: black;
}
div#my_id {
background-color: blue;
}
body div {
background-color: green;
}
body>div {
background-color: orange;
}
body>div#my_id {
background-color: pink;
}
<div id="my_id" class="my_class">hello</div>
How does selector priority work?
I'll just toss in a link to the CSS 2.1 spec itself, and how browsers are supposed to calculate specificity:
CSS 2.1 Section 6.4.3:
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.
Concatenating the four numbers a-b-c-d (in a number system with a large base) gives the specificity.
If the specificities are equal, then CSS 2.1 Section 6.4.1 comes into play:
Finally, sort by order specified: if two declarations have the same weight, origin and specificity, the latter specified wins. Declarations in imported style sheets are considered to be before any declarations in the style sheet itself.
Note that this is talking about when the style is defined, not when it is used. If classes .a and .b have equal specificity, whichever is defined last in the stylesheet(s) wins. <p class="a b">...</p> and <p class="b a">...</p> will be styled identically, based on the definition order of .a and .b.
Element
Class selectors
ID Selectors
Inline styles
!important
In order, 1 is the lowest specificity and 5 is the highest.
https://youtu.be/NqDb9GfMXuo will shown details to demo it.
What you are interested in is specificity.
Firebug is a great tool to help inspect this. But other browsers also have built in tools for inspecting the applied CSS rules.
You can refer the full answer here Mozilla documentation
Start from the most specific:
id selectors > class selectors > type selectors(normal h1, p tag and so on..)
!important always wins, but it is considered a bad practice.See the link above.
The best way is to experiment with it:
<!-- start class vs id -->
<p class="class1" id="id1">.class vs #id: The winner is #id</p>
<!-- upper vs bottom -->
<p id="id2">the very bottom is the winner</p>
<!--most specific is the winner -->
<p id="id3">the most specific</p>
<!--pseudo and target selector -->
<h3>pseudo vs type selector</h3>
<!-- !important is more important! -->
<h1 id="very-specific">HI! I am very important!</h1>
</body>
CSS:
#id1{
color: blue;
}
.class1{
color: red;
}
#id2{
color: yellow;
}
#id2{
color : green;
}
body p#id3{
color :orange;
}
body p{
color : purple;
}
body{
color : black;
}
h3::first-letter {
color: #ff0000;
}
h3{
color: CornflowerBlue ;
}
h1{
color: gray !important;
}
body h1#very-specific{
color: red;
}
Here's a test case.
I'd like to understand how CSS selectors work with property collisions. How is one property selected over another one?
div {
background-color: red;
}
div.my_class {
background-color: black;
}
div#my_id {
background-color: blue;
}
body div {
background-color: green;
}
body>div {
background-color: orange;
}
body>div#my_id {
background-color: pink;
}
<div id="my_id" class="my_class">hello</div>
How does selector priority work?
I'll just toss in a link to the CSS 2.1 spec itself, and how browsers are supposed to calculate specificity:
CSS 2.1 Section 6.4.3:
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.
Concatenating the four numbers a-b-c-d (in a number system with a large base) gives the specificity.
If the specificities are equal, then CSS 2.1 Section 6.4.1 comes into play:
Finally, sort by order specified: if two declarations have the same weight, origin and specificity, the latter specified wins. Declarations in imported style sheets are considered to be before any declarations in the style sheet itself.
Note that this is talking about when the style is defined, not when it is used. If classes .a and .b have equal specificity, whichever is defined last in the stylesheet(s) wins. <p class="a b">...</p> and <p class="b a">...</p> will be styled identically, based on the definition order of .a and .b.
Element
Class selectors
ID Selectors
Inline styles
!important
In order, 1 is the lowest specificity and 5 is the highest.
https://youtu.be/NqDb9GfMXuo will shown details to demo it.
What you are interested in is specificity.
Firebug is a great tool to help inspect this. But other browsers also have built in tools for inspecting the applied CSS rules.
You can refer the full answer here Mozilla documentation
Start from the most specific:
id selectors > class selectors > type selectors(normal h1, p tag and so on..)
!important always wins, but it is considered a bad practice.See the link above.
The best way is to experiment with it:
<!-- start class vs id -->
<p class="class1" id="id1">.class vs #id: The winner is #id</p>
<!-- upper vs bottom -->
<p id="id2">the very bottom is the winner</p>
<!--most specific is the winner -->
<p id="id3">the most specific</p>
<!--pseudo and target selector -->
<h3>pseudo vs type selector</h3>
<!-- !important is more important! -->
<h1 id="very-specific">HI! I am very important!</h1>
</body>
CSS:
#id1{
color: blue;
}
.class1{
color: red;
}
#id2{
color: yellow;
}
#id2{
color : green;
}
body p#id3{
color :orange;
}
body p{
color : purple;
}
body{
color : black;
}
h3::first-letter {
color: #ff0000;
}
h3{
color: CornflowerBlue ;
}
h1{
color: gray !important;
}
body h1#very-specific{
color: red;
}
Here's a test case.
I have a case where I have a .menu within a #header and when I accessed .menu's children via a css selector like .menu a, it is using the #header a instead.
I was expecting the .menu a to override the #header a as it is closer to the a element. Why isn't this happening? I'm assuming it has with it being a class compared to an id based on the example below.
In the example, is there a good way override #red span css within .blue span without otherwise restricting the parent style?
By "good way" I suppose I mean flexible. For example .blue could be an element created by a php framework that is used in many places (possibly not within an id styled parent element, or possibly within a parent styled on a different id).
Here is an example. All except #green will still be red:
HTML:
<div id="red">
<span>red</span>
<div class="blue">
<span>blue(class) - should be blue</span>
</div>
<div id="green">
<span>green(id) - should be green</span>
</div>
<div class="green">
<span>green(class) - should be green</span>
</div>
<div>
<span>no child div style - should still be red</span>
</div>
</div>
CSS:
#red span {
color: red;
}
.blue span {
color: blue;
}
.green, #green span {
color: green;
}
The priority of applying a CSS rule (without !important) is:
Number of IDs in the selector. If draw,
Number of attributes and classes. If draw,
names or pseudo-elements. If draw,
last declaration on the CSS file. This, of course, never draws.
Since #red span has an ID, and .green doesn't have any, #red span applies.
For further explanation of which CSS rule is apply first, check this nice article on smashing magazine
To work around, you can use a more specific rule. This way it gets tie on number one, but since it have extra classes, your rule wins due the number two.
Selector specificity dictates that id had priority over class. Even though the blue class is after red in the Cascade, red takes priority because of specificity. You can use the Selector #red .blue span if needed
the simplest and cleanest:
http://jsfiddle.net/f4ke2/7/
#red {
color: red;
}
.blue span {
color: blue;
}
.green, #green span {
color: green;
}
OR What if you do this? :)
#red > span {
color: red;
}
OR
#red .blue span {color: blue;}
OR
.blue span {
color: blue !important;
}
OR for "flexibility"
#red .blue span, .blue span, #someotherID .blue span {color: blue;}
OR something as horrid as this
var id = $("#red");
id.addClass(id.attr("id")).removeAttr("id");
If you are using style sheets (in a framework or otherwise) that assign properties to elements by class, i.e. using class selectors, you simply have to take this into account when writing other CSS rules. So this is a matter of disciplined coding (HTML and CSS), not about using some trick to get rid of normal CSS principles.
Basically, set properties only on those elements that you want to have affected, without using selectors with too wide coverage. Say, if you want to set the text inside some element red, set color: red on that element only, not on its descendants, unless you really want to override whatever settings they might have.
For example, if there is a style sheet with .foo { color: blue }, then this will affect any element in class foo, unless overridden by another rule, as per the CSS cascade. So if you don’t want it to be overridden in a situation like <div id=xxx>...<span class=foo>...</span>...</div>, you just can’t set #xxx span { color: red }, because then you would override the rule, by virtue of a more specific selector. Using #xxx { color: red } would be safe in this sense, since the span (having its color set) will not inherit its parent’s color.
Using !important as in .foo { color: blue !important } might seem to solve the problem, but !important makes style sheets difficult to manage and maintain. It also creates problems when you need a tool for overriding the effect of specificity but can’t, because you’ve already fired the weapon. The rule .foo { color: blue !important } is not effective against #xxx span { color: red !important }.
In HTML, When more than one style rule applies to an element, what is the order of precedence?
Rules that apply to an element identified by an id
Rules that apply to all elements of a particular class
Rules that apply to one or more specified tags
I think is id>class>tags, am I right?
Explanation
There are multiple things in play (as usual…), but the important order for you is this:
styles with highest specificity are used
if more have the same specificty, the latest is used
Order of selectors [and/or usage of css, for completness] (and what they add to specificity value is):
tag
class
id
inline styles (via style="")
!important
tag + !important
class + !important
id + !important
inline styles + !important
There were tests which showed that 256 classes on one element/selector have higher specificity then id. But in real life, you'll mostly (if you ever do CSS 'right') deal with number of classes + position in css file (you shouldn't style with #id, as it gives you no advantage over classes, and tags are mostly used only for generic styles)
Read more about specificity here: http://coding.smashingmagazine.com/2007/07/27/css-specificity-things-you-should-know/
Example
HTML:
<div id="johnny" class="walker whisky"> -- </div>
CSS:
/* example one */
div { border-color: red; } // border is red
.whisky { border-color: brown; } // now it's brown
#johnny { border-color: black; } // now it's black
div#johnny { border-color: red; } // it's red again
.walker { border-color: green !important; } // it's green
/* example two */
.whisky {border-color: brown; }
.whisky.walker {border-color: green; }
/* green */
/* example two */
.whisky.walker {border-color: brown; }
.whisky {border-color: green !important; }
/* green */
Hope this helps.
I think is id>class>tags, am I right?
Yes, you are.
This is called specificity; refer to this and this for details.
For playing around with style formatting rules, I'd advise using e.g.: Chrome, as it's Web Developer Plugin gives you insight on how rules are actually applied to a specific node...
I have this problem in css where i have two different states in css for example
#koolbutton .active {
color: #fff
}
#koolbutton{
color: #ccc //not active
}
When i try this html
<button id ="koolbutton" class="active">
It gives me the the normal grey koolbutton not the active one which is white! thanks
You need to omit the space between #koolbutton and .active.
#koolbutton { /*not active*/ }
#koolbutton.active { /*active*/ }
The issue is with your first selector:
#koolbutton .active
Since there is a space between the id and class selector, this applies to every element with a class of active and an ancestor with an id of koolbutton. What you want is to select every element with a class of active and an id of koolbutton:
#koolbutton.active
Although the order of your selectors doesn't matter due to CSS Specificity rules, in terms of creating more maintainable CSS I would recommend you put the default styles first, followed by any variations to that style:
#koolbutton { /* default styles */ }
#koolbutton.active { /* .active styles */ }
#koolbutton.foo { /* Another class styles */ }
If you are really wanting to style active/focus states, you should probably look at the :focus and :active pseudo selectors.
You may try this one also;
#koolbutton:active {
color: #fff; //when user click the button
}
#koolbutton{
color: #ccc; //normal display of button
}
Here is the working Live Demo.