Following is the html file I am working to understand difference between these two rules in CSS.
<!DOCTYPE HTML>
<html>
<head>
<meta charset="UTF-8">
<title>specificity</title>
<!--[if lt IE 9]>
<script src="http://html5shiv.googlecode.com/svn/trunk/html5.js"></script>
<![endif]-->
<style>
aside,
article,
section,
header,
footer,
nav {
display: block;
}
body {
font-family: Georgia;
font-size: 120%;
}
/*add styles here*/
#mainContent p {
color: red;
}
p {
color: blue;
}
.green {
color: green;
}
/**/
</style>
</head>
<body>
<section id="mainContent">
<p>I am a paragraph nested inside a section. I also have a <strong class="green">strong tag</strong> nested inside of me.</p>
</section>
</body>
</html>
And following is the statement I didn't understand quite clearly:
Specificity works just fine until inheritance is involved. If a child
element has a style that differs or conflicts with the parent styles,
the child styles always win. So for strong element above, we are seeing inheritance and not specificity.
But if I apply green class to <p> element, I am observing specificity since style green is ignored and style with id applied to paragraph.
My question is, since <p> is a child of <section> shouldn't inheritance be observed here according to above statement, just like it's observed with <strong> element?
Every CSS rule only applies to the subject of its selector.
For p { ... } the subject is all p elements
For #mainContent p { ... } the subject is all p elements which are inside the element with id mainContent.
if a p element is inside the element with id mainContent, the #mainContent p { ... } rule wins because it is a more specific rule.
The strong element is not the subject of either rule, so neither applies directly.
In the example, the strong element is the subject of the .green { ... } rule. So that is the rule that applies to that element.
So where does inheritance come in?
Inheritance of a property to an element can happen in one of two ways.
First, there can be an explicit rule whose subject is the element and the property setting is inherit. So strong { color:inherit; } will, if it is the highest priority rule with the color property in the cascade for a strong element, force the color of that element to be taken from that of its parent.
Alternatively, if there is no rule anywhere in the cascade for which a given strong element has a particular property defined, that element will take a default value. Some properties are defined as "inherited" and others are not. The color property is defined as inherited.
So, in this alternative case, only when that there is no rule whose subject is a given element and has a color property, does the color of that given element get inherited from the color of the containing element.
In your example. there are multiple rules for which the p element is the subject and the color element is defined, so no inheritance is effective on that.
Related
I am getting red background-color for both h1. For the first h1, ID has the highest precedence and for the second h1, the inline has the highest precedence. Why?
#myid { background-color: pink; }
.main h1 { background-color: red; }
div h1 { background-color: blue; }
h1 { background-color: green; }
<!-- the background-color expected
to be pink for the following h1 -->
<div class="main" id="myid">
<h1>This is paragraph one!</h1>
</div>
<!-- the background-color expected
to be brown for the following h1 -->
<div style="background-color:brown;" class="main" >
<h1>This is paragraph two!</h1>
</div>
Both of these have to do with whether the style is applied directly to the element or to the parent element.
In both cases, your intuition is correct for the outer div.main element. However, there are rules that apply to the h1s that, while less specific, apply directly to the h1s so they take precedence over the more specific rules that apply to the divs.
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_vs._inherited_styles
You are not applying the background to h1 element but to its parent element. Considering this, there is no specificity here because we only consider the rules applied to h1 and if no rules we consider inheritance (the styles applied to parent element that get inherited by childs). Also background is not a value that get inherited by default so inheritance will not apply here even if you don't specify a background to h1.
So in this case the red will always win because it's the rule with highest specificity applied directly to h1.
The pink background is present, but it's being hidden by the red background of the H1 that's sat on top of it.
If you add some padding to the #myid styles the you will see a pink outline around the red of the H1
I have a html page which has a div looking like this:
<div class="get-this"> blah blah </div>
I have a before pseudoelement on the div and I am trying to apply CSS style only to the div which will not be applicable to the pseudo element.
.get-this:not(::before) {
padding-top:2px;
}
The style is applied to the entire div. IS it possible to restrict the style only to the div and not the pseudo element?
This is a straightforward use of the cascade.
The CSS cascade is intended to enable you to apply general styles to more general selectors and overriding styles to more specific selectors.
Hence:
.get-this {
padding-top:2px;
}
.get-this::before {
padding-top:0;
}
Working Example:
.paragraph-one {
color: red;
}
.paragraph-two {
color: blue;
}
.paragraph-one::before {
content: 'Paragraph One: ';
}
.paragraph-two::before {
content: 'Paragraph Two: ';
color: green;
}
<p class="paragraph-one">This is paragraph one. It is red.</p>
<p class="paragraph-two">This is paragraph two. It is blue.</p>
<p>The <code>::before</code> pseudo-element preceding Paragraph Two <em>isn't the same color</em> as the rest of Paragraph Two, because, further down the cascade, an overriding style has been declared for the more specific <code>.paragraph-two::before</code> selector.</p>
if you already applied all of your div element to have before or after css they would require you to type content: ""; in order to show style applied to DOM:before or DOM:after
Which means if you set content to none it won't show that.
to overwrite your div style you can simply do
.get-this:before {
content: none;
}
But I would avoid applying before or after properties to all of your div element of your application. div element is often used on many situation, therefore you will run into problem you are now facing on every div element. which mean writing css to overwrite css. that's just not a good practice in most of case.
Also if your DOM element that has before, after its position is related with parent DOM, that being said, if your DOM's padding, margin, positioning, size changes will effect to before or after of that DOM
According to the specification, second rule has more specificity and text must be blue, but it's red.
/** specificity = 10 */
.my{
background-color: red;
}
/** specificity = 12 */
html body div b i strong em span font strike ul li{
background-color: blue;
}
<html>
<body>
<div>
<b><i><strong><em><span><font><strike><ul><li class="my">SUPER</li></ul></strike></font></span></em></strong></i></b>
</div>
</body>
</html>
See these rules from CSS Tricks:
For each class value (or pseudo-class or attribute selector), apply 0,0,1,0 points
For each element reference, apply 0,0,0,1 point
https://css-tricks.com/specifics-on-css-specificity/
Therefore your first example has 0,0,1,0 points. Whereas your second has 0,0,0,12 points.
0,0,1,0 > 0,0,0,12
Basically it doesn't matter how many elements you have referenced in your selector, if you don't have an ID or class referenced then your class selector will always win.
CSS Tricks
Second rule has more specificity only if the rule has the same hierarchy selector. If you have a class (which is more specific) it will take over.
You can use li.my:
/** specificity = 10 */
.my{
background-color: red;
}
/** specificity = 12 */
html body div b i strong em span font strike ul li.my {
background-color: blue;
}
<html>
<body>
<div>
<b><i><strong><em><span><font><strike><ul><li class="my">SUPER</li></ul></strike></font></span></em></strong></i></b>
</div>
</body>
</html>
This is more of a theoretical question.
Is the stack of overrides for CSS ad-infinitum? For instance, is there always a CSS override for every override?
Lets say I have written this:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8">
<title>title</title>
<style>
.a {
color: red;
}
/* Override it again */
div.a {
color: blue;
}
/* Again! */
body div.a {
color: yellow;
}
/* Again!! :) */
html body div.a {
color: yellow;
}
/* AND AGAIN!! */
html body div.a {
color: pink !important;
}
</style>
</head>
<body>
<div class="a">a</div>
</body>
</html>
Is !important combined with html body div.a the absolute highest level override for div.a?
Must there always exist something with a higher override?
In theory you can simply repeat a rule to increase the specificity.
.foo.foo.foo { }
In practise, browsers eventually treat a selector as having too many components and ignore it.
(There is also the style attribute, which is more specific than any selector)
inline styling with !important applied is the highest override I've ever used.
Example:
<div class="a" style="color: blue !important">a</div> Will override all other css applied
If you declare an inline style rule for div.a with the !important declaration it'll still override the rule declared in the <style> tag.
Any inline rule generally over-qualifies internally or externally declared styles, regardless of the number of selectors used to specify that rule. The only time an inline rule is over-qualified by internal or external styles is when the !important declaration is used - but if that declaration is used on an inline style you want to overwrite you'll be cursing.
In this case you'd need to apply some javascript to reset the attribute.
I need to style h1, h2, h3... and p tags inside a div but I only have access to the content area.
If it where possible, this would be what I'd use:
<div style="h1{padding:0;}p{font-size:1.4em;color:#000}">
Is there a solution to do this ? Apart from adding the style to every element.
Thanks
Although HTML syntax restricts style elements to the head part, this requirement is not enforced in practice. It works inside body, too. You just need to take into account that the effects are global to the document. Thus, to limit the effect to elements inside a certain element, you need to use suitable selectors. Example (I have added a color setting because the effect of just padding: 0 as in the question in not noticeable: it equals the default):
<h1>Heading outside the div</h1>
<p>A paragraph outside the div.</p>
<div class=mydiv>
<style>
.mydiv h1 { padding: 0; color: green; }
.mydiv p { font-size: 1.4em; color: #000; }
</style>
<h1>Heading inside the div</h1>
<p>A paragraph inside the div.</p>
</div>
There isn't a good solution.
Style elements may only appear in the head.
Inline style only applies to the element the attribute appears on.
The closest you can come is to use JavaScript to dynamically modify the stylesheet.
You would be better fixing whatever problem is preventing you from modifying the head section.
To avoid unwanted changes inside divs i will be using to divs with 2 unique id's:red and green
If you want different style for specific divs:
<div id="red"><h1>red</h1><p>red</p>
<div id="green"><h1>green</h1><p>green</p>
body #red > h1,body #red >p{
color:red;
}
body #green > h1,body #green > p{
color:green;
}