Cannot select first child in css - html

Here is my code
div p:first-child{
border-left: 5px solid #bdc3c7;
}
<div>
<h3>1 January 2018</h3>
<h1>This is my first Article</h1>
<p>First</p>
<p>Second</p>
<p>Third</p>
</div>
I want the first paragraph to have a left border. According to this MDN page, this can be done using first-child but mine doesn't work for some reason.
What's wrong with it?

The :first-child selector only selects the first child of its parent regardless of type. Your <p> is the third child of its <div> parent. To select the first child of a given type, use the :first-of-type instead:
div p:first-of-type {
border-left: 5px solid #bdc3c7;
}
<div>
<h3>1 January 2018</h3>
<h1>This is my first Article</h1>
<p>First</p>
<p>Second</p>
<p>Third</p>
</div>
EDIT To clarify how :first-child works, when you say div p:first-child, you're not selecting the first p child of any div. You're still selecting the first child of any div, but only if that child happened to be p. So it is kind of additional restriction.
In the example below, I used a cyan background for :first-child. You can see that it got applied to the two titles even though they have different types. Then I used a red border for p:first-child. You can see that this time it only got applied to the second title because it is p, and it didn't apply to the first title because it is not p (i.e. it is h3):
div :first-child {
background-color: #0ff;
}
div p:first-child {
border: 1px solid #f00;
}
<div>
<h3>This is my first Article</h3>
<p>First</p>
<p>Second</p>
<p>Third</p>
</div>
<div>
<p>This is my second Article</p>
<p>First</p>
<p>Second</p>
<p>Third</p>
</div>

:first-child only selects elements that are the first child of their parents. Your <p> is the third child of your <div>, so it doesn't work.
Try using :first-of-type instead:
div p:first-of-type {
border-left: 5px solid #bdc3c7;
}

You're close, but the <p> isn't the first child of the <div> -- the <h3> is, so the
<p> won't be selected by first-child.
Try it using nth-child:
div p:nth-child(3) {
border-left: 5px solid #bdc3c7;
}
<div>
<h3>1 January 2018</h3>
<h1>This is my first Article</h1>
<p>First</p>
<p>Second</p>
<p>Third</p>
</div>

The paragraph is not the first child.
Try with:
div p:first-of-type {
border-left: 5px solid #bdc3c7;
}
Or, what is the same:
div p:nth-of-type(1) { ... }

You can either use div p:nth-child(3) or you can use div p:first-of-type either way it will work.
The :first-of-type CSS pseudo-class represents the first element of its type among a group of sibling elements.
The :nth-child() CSS pseudo-class matches one or more elements based on their position among a group of siblings.
Documentation for :nth-child() here.
Documentation for :first-of-type here.
For using :first-of-type use:
div p:first-of-type {
border-left: 5px solid #bdc3c7;
}
Or for using :nth-child(3) use:
div p:nth-child(3) {
boder-left: 5px solid #bdc3c7;
}

Related

sass style for immediate consequence div

For example, let's say my code looks like below.
Same from css all divs vs direct child divs but, need in SASS.
<div class="Root">
<div>ddddddd</div>
<div>
<div>pppppppppp</div>
<div>pppppppppp</div>
</div>
<div>ddddddd</div>
</div>
I want to put borders on the divs that contain ddddddd, and I want to set the text color on all divs to green.
There are two rules:
I can't add class attributes.
I have to write selectors that start with .Root.
Any Ideas?
It could be like this (SASS):
.Root
padding: 1em
color: green
> div:not(:nth-of-type(2))
border: 1px solid red
which compiles to:
.Root {
padding: 1em;
color: green;
}
.Root > div:not(:nth-of-type(2)) {
border: 1px solid red;
}
<div class="Root">
<div>ddddddd</div>
<div>
<div>pppppppppp</div>
<div>pppppppppp</div>
</div>
<div>ddddddd</div>
</div>
Also the last <div> should be </div>.

Can't use first-of-type selector with child selector

I'm trying to target the first instance of a .row directly in it's .page-container parent. I can't get the :first-of-type selector to properly target the first instance of .row.
.page-container > .row:first-of-type {
background: blue;
}
<div class="page-container">
<div class="row">Target This Row</div>
<div class="row">Don't Target</div>
<div class="row">Don't Target
<div class="row">Don't Target</div>
</div>
</div>
Please help me target only the first instance of .row that is a direct descendant of .page-container.
I ran across this issue relatively recently.
The issue is that :first-of-type specifically means first-of-this-type-of-element and it cannot (and does not) apply to classes.
In order to have a selector that applies to classes, we will need either a :first-of-class or a :first-of-query (which can select anything - including classes) - and, so far, neither exist.
Consequently you need something like this:
.page-container div:first-of-type.row
which means:
the first div nested inside .page-container - but only if it
also happens to have the class .row.
I think what you want is
.page-container > .row:first-child {
background: blue;
}
I usually ignore class or id all together and focus on the tag names, then if it's too broad, I narrow it down by adding class or id to parent.
div > div:first-of-type {
background: blue;
}
div.page-container > div:first-of-type {
border: 3px solid red;
}
p:first-of-type {
color: blue
}
p:last-of-type {
color: red;
}
<p>Example #1 in blue background</p>
<p>Example #2 in red border</p>
<div class="page-container">
<div class="row">Target This Row</div>
<div class="row">Don't Target</div>
<div class="row">Don't Target
<div class="row">Don't Target</div>
</div>
</div>

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

CSS: How to select only the first non-adjacent sibling after the element

I have an HTML page like this:
<p></p>
<p></p>
<p></p>
<div></div>
<p></p>
<p></p>
<p></p>
<div></div>
and this pattern continues.
Normally the div elements should not display so:
div{display:none;}
But when a paragraph is hovered, the first div element after that should be displayed:
p:hover+div{display:block;}
but this works only for the previous p . and this:
p:hover~div{display:block;}
shows all divs after the hovered p not just the first one after.
How could I display only the first non-adjacent div after the hovered p?
here is the demo
Actually I am looking for a selector like first-sibling.
You should use the below setting:
p:hover ~ div ~ div {
display:none;
}
This would set the display back to none for all div after the first div following the hovered paragraph.
div {
display: none;
}
p:hover ~ div {
display: block;
}
p:hover ~ div ~ div {
display: none;
}
<p>p1</p>
<p>p2</p>
<p>p3</p>
<div>d1</div>
<p>p1</p>
<p>p2</p>
<p>p3</p>
<div>d2</div>
<p>p1</p>
<p>p2</p>
<p>p3</p>
<div>d3</div>
Have you tried using this:
div {
display: none;
background: blue;
color: #fff;
}
p:hover+div,
p:hover+p+div,
p:hover+p+p+div {
display: block;
}
<p>lorem</p>
<p>lorem</p>
<p>lorem</p>
<div>Ipsum</div>
<p>lorem</p>
<p>lorem</p>
<p>lorem</p>
<div>Ipsum</div>
There is no "first-sibling" selector, but you can override the style for subsequent div elements using the same technique described in this answer:
div,
p:hover ~ div ~ div {
display: none;
}
p:hover ~ div {
display: block;
}
This is preferred if you do not know the maximum number of p elements that can separate div elements in advance, or you would rather not have to hardcode all the adjacent selectors necessary as shown in Aaron's answer.
I would place your blocks between section tags. Then <p> tags and <div> tag are siblings from the same element. Also if these tags belong to each other its also good to reflect this in your markup.
JSFIDDLE DEMO
<section>
<p>hello</p>
<p>world</p>
<p>bar</p>
<div></div>
</section>
<section>
<p>hello</p>
<p>world</p>
<p>bar</p>
<div></div>
</section>
css
section p:hover~div{display:block;}

How to find second <p> element in a <div>?

Which CSS selector matches the second paragraph without using an ID?
<div>
<p>Apple</p>
<p>Mango</p>
</div>
You could use the nth-child selector, set to find the second child. This will select all <p> elements that are the second child of their parent:
p:nth-child(2) {
background-color: lightblue;
}
<div>
<p>Apple</p>
<p>Mango</p>
</div>
<div>
<p>Apple</p>
<p>Mango</p>
</div>
Alternatively, if you want to find the second child in a specific set of elements, you could wrap those elements in a <div>:
#wrapper p:nth-child(2) {
background-color: lightblue;
}
<div>
<p>Apple</p>
<p>Mango</p>
</div>
<div id="wrapper">
<p>Apple</p>
<p>Mango</p>
</div>
My preference in this situation would be to use the :nth-of-type pseudo-class:
div p:nth-of-type(2)
Why choose :nth-of-type over :nth-child?
Because :nth-of-type is explicitly intended for situations (like the one you describe) where you wish to select the nth of a specific element type within a given context.
See this Working Example:
div p:nth-of-type(2) {
display: inline-block;
padding: 6px;
color: rgb(255, 255, 255);
background-color: rgb(255, 0, 0);
}
<div>
<h2>Fruit Bowl</h2>
<p>Apple</p>
<p>Mango</p>
</div>
But I can still use :nth-child instead, right?
Yes you can - but it might not always give you the result you are expecting.
The syntax div p:nth-child(2) doesn't mean every second p in a given context inside the div (like div p:nth-of-type(2) does).
Instead it means an element which is a p and which is also a second child.
Knowing that, which p do you guess will be highlighted in the example below?
div p:nth-child(2) {
display: inline-block;
padding: 6px;
color: rgb(255, 255, 255);
background-color: rgb(255, 0, 0);
}
<div>
<h2>Fruit Bowl</h2>
<p>Apple</p>
<p>Mango</p>
</div>
Did you guess right?
Do you now understand the difference between :nth-of-type(2) and :nth-child(2)?
You should use nth-child.
p:nth-child(2) {
color: #ccc;
}
REF: How nth child works