CSS specificity precedence - html

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

Related

Why does the background turn black but the text remains purple (HTML CSS)?

For some reason, a black background shows up out of nowhere on the p tags under the div when you put the CSS selector to #div1. If I fix it and change the selector from #div1 to #div1 > h4 like my little tutorial text was explaining, it fixes itself. Why is that? I just need to know if it's a glitch or not. Thanks!
Please advise. Thanks.
body {
}
h2 {
color: red;
}
p {
color: pink;
}
p {
color: green;
}
p {
color: purple;
}
.orange > p {
color:orange;
}
.blue {
color: blue;
}
#red {
color: red;
}
#div1 > h4 {
background-color: black;
color: white;
}
<!DOCTYPE html>
<html>
<head>
<title>CSS Basics</title>
<link rel="stylesheet" type="text/css" href="basics.css">
</head>
<body>
<p>This is the color purple not pink or green because CSS always takes the selector that is last in the cascade.</p>
<div class="orange">
<h1>This will not be orange</h1>
<p>This will be orange because our selector in CSS for the class="orange" is like this: .orange > p making the h1 unchanged even though it is under the same class="orange" and the p will be the only one that changes to orange text!</p>
</div>
<p class="blue">This will be blue.</p>
<p class="blue">This will also be blue, because you can use classes more than once unlike ID's.</p>
<p id="red">This is an ID stating it is red.</p>
<p id="red">This is using the same ID to say it is red, and as you can see it still works. But, be warned, using the same ID to multiple elements is invalid HTML and should be avoided!</p>
<div id="div1">
<p>This paragraph is wrapped in a div with the id of "div1" which gives a black background and white text.</p>
<p>This paragraph is also wrapped in the div with the id of "div1". Notice that neither this paragraph or the paragraph before this one has white text or a black background. This is because we didn't specify in the selector to give p tags white text by using a > symbol between #div1 and p. In fact, it remained purple since that is the last thing applicable that the cascade found to work.</p>
<h4>This h4 text on the other hand (which is also inside of the div as the other two paragraphs above it) works because we specified it to be #div1 > h4 for its selector. (side note: the two paragraphs above this h4 element do in fact get a black background until we write in #div > h4. I do not know why the text remains purple but the background changed to black...It fixed itself to not having a black background after we wrote in the code "#div1 > h4" so idk what to make of it...)
</h4>
</div>
</body>
</html>
#div1 is the parent of the p elements. This means that some properties (such as background) of #div1 will be applied to the child element(s). However, when you add the > h4 it is specifying that those properties should only apply to the h4 child element of #div1 element. So no, it is not a glitch but is intended CSS behavior.
To note, you have 3 distinct p {} statements, each with a different color...only the final one will be used (because they all have the same specificity) and you can delete the top two.
If I'm understanding your question correctly, the reason the black background only applies to the h4 element once you add the angled bracket is because the angled bracket is a CSS child selector.
In this instance, #div1 > h4 applies styling to all h4 that are children of the #div1 div, whereas #div1 itself applies styling to everything contained in the div (including p)
I hope this answers your question my friend.
#div1 is the part element that your p tags contain. since that p tags are inside the div, the back ground color will be black. because it applies its styles to all the child elements.
when you give #div1 > h4 ; this styles only affects on h4 tag since it only applies to #div1 's child h4 elements.

What is 'parent' in HTML or CSS?

I was introduced to the following code:
<!DOCTYPE html>
<html>
<head>
<style>
span {
color: blue;
border: 1px solid black;
}
.extra span {
color: inherit;
}
</style>
</head>
<body>
<div>
Here is <span>a span element</span> which is blue, as span elements are set to be.
</div>
<div class="extra" style="color:green">
Here is <span>a span element</span> which is green, because it inherits from its parent.
</div>
<div style="color:red">
Here is <span>a span element</span> which is blue, as span elements are set to be.
</div>
</body>
</html>
Link: https://www.w3schools.com/cssref/tryit.asp?filename=trycss_inherit
I'm not sure why the colour of the extra span is green. When they use the 'inherit' value, do they take a colour similar to the first one introduced? Is that what it is?
What's the 'parent' and 'child' referring to here? What's their definition?
If we have a <p> inside a <div> element, the <div> is the parent of the <p> and the <p> is the child of the <div>
<div>
<p></p>
</div>
You can read this web: https://www.w3schools.com/js/js_htmldom_navigation.asp it explains perfectly.
The nodes in the node tree have a hierarchical relationship to each other.
The terms parent, child, and sibling are used to describe the relationships.
In a node tree, the top node is called the root (or root node)
Every node has exactly one parent, except the root (which has no
parent)
A node can have a number of children
Siblings (brothers or sisters) are nodes with the same parent
CSS uses this structure to make specific selectors like first-child, :nth-child(n), :last-child...
You can see all CSS selectors here
The value inherit of a CSS attribute applied to an HTML node, simply takes the parent value of the attribute.
So if I have an html like this:
<div>
<p></p>
<p class="red"></p>
</div>
And css like:
div {
background-color: red;
}
div > p {
background-color: blue;
}
.red {
background-color: inherit;
}
The div with the red class, using inherit will take the value red of the parent.
Since the <span></span> elements are nested within their 'parent' <div></div> elements, they are said to be 'children' of the 'parent' div.
<div id="parent">
<span id="child1"></span>
<span id="child2"></span>
<span id="child3"></span>
</div>
The 3 spans are children of the parent div, and siblings of each other. Much like a family. When a child inherits styles from its parent, it uses the same style as its parent uses for that particular style.
color: inherit;
means that when assigning the span its color, it will defer to whatever the parent color is, which in this case was green.
inherit summary: from https://developer.mozilla.org/en/docs/Web/CSS/inherit
The inherit CSS-value causes the element for which it is specified to
take the computed value of the property from its parent element. It is
allowed on every CSS property.
Brake down your code to single parts to understand what's going on like:
span {
color: blue;
border: 1px solid black;
}
This means every span has a blue color.
Moving on to next lines:
.extra span {
color: inherit;
}
This means every span inside an element with a class="extra" will inherit the color. Means all the <span>s inside .extra will take it's parent color.
Now as you see in your result every span has blue color, except the one inside the div with class extra which has an inline style on color saying it is green.
In this, you have used both Internal and Inline styling at the same time. Since Inline styling has the highest precedence over Internal and External Styling that is why that extra span turns out to be Green.

Confusion between inheritance and specificity in CSS

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.

CSS one class to ignore another

I have something like this
<div class="text-holder">
<h2>this is text-holder</h2>
<p>this is text</p>
</div>
<a href="#" class="ignore">
<div class="text-holder">
<h2>this is text-holder</h2>
<p>this is text</p>
</div>
</a>
<a href="#">
<div class="text-holder">
<h2>this is text-holder</h2>
<p>this is text</p>
</div>
</a>
And CSS that does this
.text-holder {
color: green;
}
a {
color: red;
other css
}
.ignore {
other css
}
Is there a way that the link can ignore the css style for the global a style, and just use the ignore? I don't want to use !important because there will be other instances of text-holder that will want to use the global a style.
EDIT
Thanks for all the replies, but let me be a little more clear so hopefully you understand better. (Not the best at explaining)
The problem is text-holder has it's text styling from global p, h2 and etc. Which are above a in the hierarchy of the stylesheet. so p, h2, a, .ignore, .text-holder etc
a has a lot of info on it, hover, visited, focus, color, font-weight and etc. Now for all the divs I wanted to ignore this info I was looking to see if there was a simpler way of just creating an ignore rule, rather than for all the divs I want to ignore it to overwrite them with all the rewritten information.
CSS doesn't support "ignoring", but part of its nature (the Cascading part of Cascading Style Sheets) supports "overwriting"; Newer CSS properties will overwrite older CSS properties of the same name, so you just need to give .ignore a different color value than your previous a selector's color value.
Is there a way that the link can ignore the css style for the global a style, and just use the ignore?
No. If a selector matches then all applicable rules in it will be applied.
.ignore is at least as specific as all preceding rules, so you just need to set the properties you want to override to the desired value.
Yes, basically what you're trying to do is already how CSS works.
The key to understand is the concept of specificity.
CSS rules applied through the style="" attribute have a weight of 1000.
Rules applied against an #id selector have a weight of 100.
Rules applied against a .class selector have a weight of 10.
And rules applied against an element tag name or :pseudo-selector get a weight of 1.
So for example, if you have...
a { color: red; }
.ignore { color: black; }
The weight of the red links is 1, while the weight of black text is 10, so the black has higher specificity and would win.
The important concept is that .ignore doesn't tell it to ignore its old assignment, it is instead a way to override the assignment.
EDIT
I should also add that cascading rules have no weight, so any definition in a child element will override them.
For example:
a { color: red; }
.ignore { color: black; }
div { color: blue; }
<a class="ignore"><div>hello world</div></a>
The text will be blue, not black, because the div tag has a rule applied to it which overrides the cascading black from the .ignore class.
You can try:
:not(.ignore) .text-holder {
color: green;
}
Or if you move your ignore class to .text-holder element
.text-holder:not(.ignore) {
color: green;
}

Style (h and p) tags inside div. Only access inside <body>

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;
}