There is one <p> tag with class .eleclass and id #eleid and i have specified 3 css to the <p> tag one specified with class second with id and third with just p declared.
p#eleid{
color:yellow;
}
p.eleclass{
color:blue;
}
p{
color:red;
}
<p id="eleid" class="eleclass">
hello para.
</p>
Now i wonder why the rule applied to p#eleid is working when css runs from top to bottom nature and at bottom color red is specified so <p> should be red in color.
Is there any css rules hidden behind it??
This problem inclues use of id not only class.
It comes down to CSS specificity.
From MDN:
Specificity is the means by which browsers decide which CSS property values are the most relevant to an element and, therefore, will be applied.
As it happens, an ID based selector has higher priority than a tag based selector. This is because an ID is more specific than a tag. In other words, the tag selector applies to all p elements, while the ID will only apply to the p with the ID.
There are ways around specificity, such as the !important keyword - however, I mostly recommend against working around specificity, as it can lead to bugs.
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 am well aware of CSS specificity rules (I have gone through this page: https://developer.mozilla.org/en-US/docs/Web/CSS/Specificity), but I have an example where specificity of two elements should NOT be equal, and yet CSS rules are being applied differently depending on the nesting ordering of the html elements.
h4 small {
color: red;
}
<!-- will be red -->
<h4>
<a href="www.example.com">
<small>test</small> .
</a>
</h4>
<!-- will be blue -->
<h4>
<small>
test
</small>
</h4>
Reproduced here: https://jsfiddle.net/u39zsmx1/
h4 small should be more specific than a, yet, when the a element is the most inner nested element, its style wins. Why?
How does the nesting ordering of HTML elements affect CSS specificity?
It doesn't.
h4 small should be more specific than a, yet, when the a element is the most inner nested element, its style wins. Why?
h4 small matches the <small> element. It doesn't match the <a> element. Specificity only matters when multiple rules match the same element.
The a is blue (or purple depending on if it is visited or not). This comes from the CSS rules in the browser stylesheet.
The small is red. This comes from the CSS rules in the author stylesheet.
The text node is the colour of the element it is a child of.
After a little more digging in https://developer.mozilla.org/en-US/docs/Web/CSS/Specificity, it turns out that while ordering is not taken into account, what matters is which elements are being targeted.
Specificity is not calculated if one of the CSS rules directly targets an element and the other does not. Inheritance is not applied in such a case.
Here is the official documentation for the CSS3 :not() pseudo-class:
http://www.w3.org/TR/css3-selectors/#negation
and the proposed CSS Selectors Level 4 enhancement:
http://dev.w3.org/csswg/selectors4/#negation
I've been searching the implementation and browser support for :not(), but the only examples I found were with a single element or with a direct child of an element, e.g.:
div *:not(p) { color: red; }
The example above works when <p> is a direct child of <div>, but it does not work when <p> is a more distant descendant of <div>.
div :not(p) {
color: red;
}
<div>
<ul>
<li>This is red</li>
</ul>
<p>This is NOT</p>
<blockquote><p>This is red but is not supposed to be!</p></blockquote>
</div>
If the answer is in the official documentation above, then I didn't find/understand it. As I said, I have searched this site and the web but couldn't find any discussion about the support or lack thereof of :not() as grand-children of another element.
Is this supposed to work like I think it should?
Is this supposed to work like I think it should?
No, the behavior you're seeing is correct.
In your last example, although the <blockquote> contains a <p>, it's the <blockquote> itself that's matching *:not(p), as well as the condition that it must be a descendant of the <div>, which it is. The style is applied only to the <blockquote>, but it is then inherited by the <p> inside it.
The <p> element itself still counts against the negation, so the <p> itself is still being excluded from your selector. It's just inheriting the text color from its parent, the <blockquote> element.
Even if none of its relatively close ancestors matched the selector, you have elements like html and body to worry about as well — although you could probably just tack on a body selector in the very beginning:
body div...
This is why I often strongly advise against using the :not() selector for filtering descendants, especially when not qualified with a type selector (like div in your example). It doesn't work the way most people expect it to, and the use of inherited properties like color only serves to compound the problem, on top of making it even more confusing for authors. See my answers to these other questions for more examples:
Why doesn't this CSS :not() declaration filter down?
CSS negation pseudo-class :not() for parent/ancestor elements
The solution to the problem described is to simply apply a different color to <p> elements. You won't be able to simply exclude them with a selector because of inheritance:
/* Apply to div and let all its descendants inherit */
div {
color: red;
}
/* Remove it from div p */
div p {
color: black;
}
On Selectors Level 4: yes, :not() has indeed been enhanced to accept full complex selectors that contain combinators. Essentially, this means (once browsers begin implementing it) you will be able to write the following selector and have it do exactly what you want:
p:not(div p) {
color: red;
}
In case anyone is interested, this works in jQuery today.
The color is assigned to the blockquote, and is then inherited by the p.
:not(p) just makes it so that the styles are not directly applied. They are still inherited though.
I have a very bad CSS rule (high specifity, use of !important) which sets color of text in a paragraph:
#wrapper .article .text {
color: green !important;
}
Then I put a simple span element in that paragraph and set color of the span text via simple class:
.black {
font-weight: bold;
color: black;
}
How come, that this simple class with low specifity and no !important flag overrides the parent rule?
Full snippet on codepen.io here: http://codepen.io/Jarino/pen/oXYeQZ?editors=110
This is simply because there is no more specific rule for that <span> than what you have declared in .black. Even though it is a child element of the <p> that has an important! flagged rule, it only inherits the color from it if it can find no more specific other color definition. Inheritance from a parent context is the least specific "rule" possible. Also, the !important part of a rule is not inherited, afaik.
If this were not the case, you would be very commonly forced to either use !importantwhenever an element takes a style that it already inherited from the parent, or you would have to constantly use very long selectors to make sure your child element selector does not have a lower specificity than the definition it inherits.
Also, compare what Mozilla says on the subject:
Styles for a directly targeted element will always take precedence
over inherited styles, regardless of the specificity of the inherited
rule.
https://developer.mozilla.org/en-US/docs/Web/CSS/Specificity#directly-targeted-elements
The high-specificity rule applies only to the parent class. When it comes to it's children, the high-specificity of the parent class mellows down to a parent style that is inherited by the child.
And, when it comes to styling the child, all CSS rules specifically targeting it get precedence over the high-specificity rule of the parent.
If you do 'Inspect Element' for this child span tag in the Developer Console of your browser, you'll see how preference is given to CSS rules targeting that particular element that overrides all the parent styling that appears way down the list.
if you don't want your .black class to override the parent rule you can simply remove the color property from your .black class, the class mentioned in span will always have high specificity regardless of parent rule.
Because !important applies only for current element style not for child elements with specified same property.
How come, that this simple class with low specifity and no !important
flag overrides the parent rule?
Well, because they are two different rules.
You have your text class which is pretty strictly called but only a class without selector.
After you addded a span with a different class it will not be overwritten, because it's another rule. It gets applied to the span. And .text get applied to the paragraph.
Is there any difference between this
#id {
}
and this
div#id {
}
Yes. There is mainly two differences:
The first selector matches any element with id="id", while the second only matches div elements with that id.
The second selector is more specific, so if you have both and they match the same element, the styles from the second will have precedence.
Normally you would use the first selector. As the id should be unique in the page it would only target a single element.
The second selector would be useful if you use the same style sheet for several pages, and you either want to target the id under certain conditions, or if you want to override another rule by making it more specific.
The selectors behave differently:
#id is same as writing *#id (the asterisk selector is implied if tag name is omitted).
It matches any element that has an id of id.
div#id matches an element that is a div and has an id of id.
It is more specific than the above example.
In general, using #id selector is sufficient since ids are (supposed to be) unique inside a page. However, there are certain situations where you could use div#id.
Example 1
You use different elements for similar purpose therefore you want to assign them same id but style them differently, then you must be more specific:
<!-- page 1 -->
<ul id="features" title="All amenities">
<li>Spa</li>
<li>Pool</li>
</ul>
<!-- page 2 -->
<ol id="features" title="Top 3 amenities">
<li>Spa</li>
<li>Pool</li>
</ol>
Example 2
You can add a tag name to add weight to your selector. Consider this example:
<div id="header">
<img>
<div id="logo"><img></div>
<img>
</div>
/* file 1 */
#logo img { border: thin solid; }
/* file 2 */
#header img { border: 0; }
The first rule adds a thin border to images inside logo, the other rule removes border from all images inside header (including the one inside logo). In order to force the thin border rule you can change it to div#logo img so that it becomes more specific than the other rule.
Short answer: Yes.
#id {} targets a single ID selector wherever applied in a single HTML document. For example, <span id="id">...</span>, or <p id="id">...</p>
div#id {} will look for a <div> element that has an ID of #id, for example: <div id="id"></div> and cannot be used on any other tag except a <div>.
Note that ID selectors should only be used once semantically in a HTML document.
On a larger scale and more constructed case to this question, you should look at CSS Specificity; a well written and best-practise approach to specificity in CSS.
Also, take a look a CSSGuidelin.es, another well-written document on dealing with CSS selectors and their differences.
#elementid selector will select all elements having the id "elementid"
On the other hand, div#elementid selector will select only divs having id "elementid"