CSS - selector nth-child - html

why all elements were colored on red?
<div class="parent">
<span>1</span>
<p>2</p>
<h1>3</h1>
</div>
.parent:nth-child(1) {
color: red;
}
.parent:nth-child(2) {
color: green;
}
.parent:nth-child(3) {
color: blue;
}
I thought that the elements would be properly colored. span, p, h1 are the children of the element div?

.parent:nth-child(1) means "An element that is the first child of its parent and which is a member of the parent class".
It won't match the span, p or h1 because they do not have class="parent".
The inherit the red colour from their parent which does have that class and is the first child in its parent.
You need a child or descendant combinator in there:
.parent > :nth-child(1)
.parent :nth-child(1)

Related

In this piece of code, why are both paragraphs blue?

.red p {
color: red;
}
.blue p {
color: blue;
}
<div class="blue">
<p> first </p>
<div class="red">
<p> second </p>
</div>
</div>
I assumed the first would have been blue and the second as red, but that isn't the case. Why are both paragraphs blue?
Both paragraphs are blue due to the "C" in CSS - which stands for cascading. Review the MDN docs to see how CSS rules are applied and inherited.
In your case all of <p> elements are blue because the .blue p selector is the last rule in your CSS and it overrides the .red p selector.
You can restructure your CSS like this to ensure that the <p> elements within the .red div are red.
.blue p {
color: blue;
}
.blue .red p {
color: red;
}
As you know:
.blue p matches any p tags within a .blue class.
.red p matches any p tags within a .red class.
Your <p> first </p> is within a blue class, so it matches the .blue p rule, and is rendered as blue.
<div class="red"> is within both a red class and a blue class, so we have a dilemma. The way CSS resolves this is by using whichever rule appeared last. In this case the .blue p rule appears last, and the text is rendered as blue.
CSS fix
If p tags are always going to be an immediate child of your color classes, you could do the following. The > is a descendant selector that only matches immediate descendants.
.red > p {
color: red;
}
.blue > p {
color: blue;
}
CSS fix 2
You can also do as Tom suggested. The reason why it works is because CSS rules that are more specific will overwrite CSS rules that are less specific. Even though the blue rule comes second because div .red p has two classes, it is more specific than .blue p.
.red p,
.blue .red p {
color: red;
}
.blue p,
.red .blue p {
color: blue;
}
However, this only takes your problem one level deeper. The red class in the following HTML will still be rendered blue.
<div class="blue">
<div class="blue">
<p> first </p>
<div class="red">
<p> second </p>
</div>
</div>
</div>
HTML fix
This is the method I would suggest you use. You can simply move your classes to the p tags:
<div>
<p class="blue"> first </p>
<div>
<p class="red"> second </p>
</div>
</div>
Other items to watch out for
There are other ways a CSS rule can get overridden. I would suggest you research CSS specificity.
Because you have given blue color to the parent div. This should be your structure.
<div class="blue">
<p>first</p>
</div>
<div class="red">
<p>second</p>
</div>
CSS code will be :
.red {
color: red;
}
.blue {
color: blue;
}

How can I color text in <p> that it contains in a <div>

How to color a text in a <p> that it contains in a <div> when the user hovers with the mouse.
Suppose I have this html code:
<div id="riga_ristorante_1" >
<div>
<p>HI</p>
</div>
<div><p>HOME</p></div>
<div><p>DOG</p></div>
</div>
I want color the "hi","HOME","DOG" in black when the user go on the <p> element, so I use CSS:
#riga_ristorante_1:hover > p {
text-align: center;
color: black;
}
But it doesn't work. Anyone can help me?
You are using a child combinator (a greater than sign: >), but the div with the id your selector matches is the grandparent of the paragraphs, not the parent.
Use a descendant combinator (a space: ) instead.
You are targeting the paragraph directly after your ID div which in your html you don't have a paragraph tag that is a immediate child of your riga_ristorante_1
for more info on > selector
https://developer.mozilla.org/en/docs/Web/CSS/Child_selectors
With your given html you can do
#riga_ristorante_1:hover p { ... }
or
#riga_ristorante_1:hover div > p { ... }
or
#riga_ristorante_1 div:hover > p { ... }
or even
#riga_ristorante_1 p:hover { ... }
css selector will be riga_ristorante_1:hover > div > p {}
#riga_ristorante_1:hover > div > p {
text-align: center;
color: blue;
}
<div id="riga_ristorante_1" >
<div>
<p>HI</p>
</div>
<div><p>HOME</p></div>
<div><p>DOG</p></div>
</div>
You have your p as second level in deep, so you can't use > as it applies to first level only. Use
#riga_ristorante_1:hover p {
color: red;
}
#riga_ristorante_1:hover p {
color: red;
}
<div id="riga_ristorante_1" >
<div>
<p>HI</p>
</div>
<div><p>HOME</p></div>
<div><p>DOG</p></div>
</div>
Try with #riga_ristorante_1 p:hover just give toggle effect
#riga_ristorante_1 p:hover {
text-align: center;
color: blue;
}
<div id="riga_ristorante_1" >
<div>
<p>HI</p>
</div>
<div><p>HOME</p></div>
<div><p>DOG</p></div>
</div>
Leave the HTML Code but change your css selector to #riga_ristorante_1 div > p:hover then set your preferred styles
HTML Code
<div id="riga_ristorante_1" >
<div><p>HI</p></div>
<div><p>HOME</p></div>
<div><p>DOG</p></div>
</div>
The css selector should be #riga_ristorante_1 div > p:hover so the css will look like below and add more styles if you like like the text-align in the original css code.
CSS Code
#riga_ristorante_1 div > p:hover {
color: blue;
}

Use :not selector to exclude a div and all its descendants

I have a situation where a style of purple font color with a light yellow background needs to be applied to all divs outside a div having a class of RadDiv.
This means all divs that are nested within the div with class of RadDiv should be excluded.
I tried using :not selector as shown below but it does not work. Demo of my situation
Question: How would I specify the :not selector to exclude a div with a class of RadDiv and all nested divs inside this div?
:not selector that does not work
div:not(.RadDiv) div {
background-color:lightyellow;
color:purple;
}
Complete code that I tried
<div>This is a div </div>
<div class="RadDiv newDiv outerDiv">
<div class="header">
This is the header
</div>
This is an outer div
<div class="alert highlight">
This div stands out
</div>
<div class="footer disclaimer">
This is the footer part
</div>
<table>
<tr>
<td>
<div>This is div inside a table element</div>
</td>
</tr>
</table>
</div>
<div id="div1">This is div1</div>
<div id="div2">This is div2</div>
<style>
div:not(.RadDiv) div {
background-color:lightyellow;
color:purple;
}
.outerDiv {
border:1px solid red;
font-family:Arial;
}
.footer {
color:lightgray;
font-size:small;
font-style:italic;
}
.header {
font-weight:bold;
}
:not selector is not so powerful and it doesn't work the way you would like it to in more complicated situations. The easiest way to achieve what you want will probably be to override .RadDiv styles:
div {
background-color:lightyellow;
color:purple;
}
.RadDiv, .RadDiv div {
background: transparent;
color: black;
}
Treat all divs of the same level as siblings. Therefore, start by selecting the parent:
body > div:not(.RadDiv) {
background-color: lightyellow;
color: purple;
}
Using the child combinator (>), only one level is targeted, and the :not selector can be used to exclude any sibling (including its descendants).
Revised Fiddle
References:
6.6.7. The negation pseudo-class
8.2. Child Combinators

Order of CSS rules applied to child elements

I wonder how the CSS rules applied to the child elements.
The h2's gray style is been overriding because there is a parent level style .level2 h2with blue color.
But the .level1 h2 is not applying the same way.
Please see the below example.
.level1 h2 {
color: green;
}
.level2 h2 {
color: blue;
}
h2 {
color: gray;
}
<div class="level1">
<div class="level2">
<h2>test</h2>
</div>
</div>
It's all about specificity and inheritance.
The notion of a “cascade” is at the heart of CSS (just look at its
name). It ultimately determines which properties will modify a given
element. The cascade is tied to three main concepts: importance,
specificity and source order. The cascade follows these three steps to
determine which properties to assign to an element. By the end of this
process, the cascade has assigned a weight to each rule, and this
weight determines which rule takes precedence, when more than one
applies.
It also depend of the order in the stylesheet if both selectors have the same specificity.
.level2 h2 {
color: blue;
}
.level1 h2 {
color: green;
}
h2 {
color: gray;
}
<div class="level1">
<div class="level2">
<h2>test</h2>
</div>
</div>
Source : https://www.smashingmagazine.com/2010/04/css-specificity-and-inheritance/
This is a matter of CSS Specificity
The concept
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 CSS selectors of different sorts.
How is it calculated?
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 specificity is equal to any of the multiple
declarations, 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 element will
always take precedence over rules that an element inherits from an
ancestor.
Where :
.level1 h2 and .level2 h2 will have a specificity of : 0 0 1 1
While:
h2 only has a specificity of: 0 0 0 1
therefore h2 is less specific.
It will prevail the latest style applied if having the same specificity
You can test/calculate specificity here
Snippet with level2 as last style applied
.level1 h2 {
color: green;
}
.level2 h2 {
color: blue;
}
h2 {
color: gray;
}
<div class="level1">
<div class="level2">
<h2>test</h2>
</div>
</div>
Snippet with level1 as last style applied
.level2 h2 {
color: blue;
}
.level1 h2 {
color: green;
}
h2 {
color: gray;
}
<div class="level1">
<div class="level2">
<h2>test</h2>
</div>
</div>
.level2 h2 is given more importance as it's declared further down in the stylesheet. And it's also more important than h2, because it's composed of a tag name AND a class name.
Since the specifity here is the same for ".level1 h2" and ".level2 h2", the browser looks at the order it is declared in the CSS.
The "h2" tag that makes the tag gray has lower specifity, so that will alwayss be overridden by the other declarations.
h2 {
color: gray;
}
/* Situation 1, level 2 declared first */
.situation1.level2 h2 {
color: blue;
}
.situation1.level1 h2 {
color: green;
}
/* Situation 1, level 2 declared last */
.situation2.level1 h2 {
color: green;
}
.situation2.level2 h2 {
color: blue;
}
Level 2 declared <b>first</b>
<div class="level1 situation1">
<div class="level2 situation1">
<h2>test</h2>
</div>
</div>
Level 2 declared <b>last</b>
<div class="level1 situation2">
<div class="level2 situation2">
<h2>test</h2>
</div>
</div>

use 1 css class to swap style for children

I want to toggle a single class .active on a div id="slot1".
The div has 2 child divs. When .active is NOT applied to the div, one child1 is yellow, child2 is green.
When I apply do something like $("#slot").addClass("active"), I want child1 to be blue and child2 to be red.
How do I write the css for the "children" so that toggling .active on their parent "slot" makes them switch states
.normal{}
.active{}
.a{color:yellow;}
.b{color:green;}
.a [when .active is applied to my daddy] {color:blue;}
.b [when .active is applied to my daddy] {color:red;}
<div id="slot1" class="normal">
<div class="a">normal I'm yellow, with active I'm blue</div>
<div class="b">normal I'm green, with active I'm red</div>
</div>
<div id="slot2" class="normal active">
<div class="a">normal I'm yellow, with active I'm blue</div>
<div class="b">normal I'm green, with active I'm red</div>
</div>
Normal
.normal .a {
background: yellow;
}
Active
.normal.active .a {
background: blue;
}
For the other children it's equivalent, see JSFiddle
If you want the to select on the direct ancestor only (daddy), you must use the child selector >
.normal > .a {
background: yellow;
}
.normal.active > .a {
background: blue;
}
.a{color:yellow;}
.b{color:green;}
#slot1.active .a, #slot2.active .a {color:blue;} /*No daddy selector, but you can just get the child of .active*/
#slot1.active .b, #slot2.active .b {color:red;}