0

I dont know why the selector :first-child working for 'p' element and NOT :last-child and the same happening for the following span element where :last-child works but not the :first-child. (I suppose that the default parent for all of them is the body element). I found that if I place any element following paragraph element it (p:last-child) doesn't work, even acts weirdly for the following elements(span), why is it not working when I m specifically telling it to select last/first child of the 'p' (or span) element of the parent (in this case the body)?

<html>
<head>
<style> 
p:first-child  {
  background: red;
}
span:last-child  {
  background: red;
}
</style>
</head>
<body>

<p>The first paragraph.</p>
<p>The second paragraph.</p>
<p>The second paragraph.</p>
<span>A..</span><span>B.. </span><span>C.. </span>

</body>
</html>

EDIT: I just found dat the SPEC for all these :first-of-type, last-of-type, first-child and :last-child says- "the selected element had to have a parent. Beginning with Selectors Level 4, this is no longer required", Which means there's a glitch in their spec. if they DONT need any parent, then it must work, even if they needed, they have one in my case (the body element). Firstly, as per SPEC, they don't need to be a child anymore, secondly, they are indeed children of the default body element. Hence, all these should work (relative to the parent body).

Tanvir
  • 1,642
  • 8
  • 32
  • 53
  • it's working correctly! Are you sure your testing environment works properly? – Joey Jan 06 '22 at 05:54
  • I just tried it in the w3schools editor – Tanvir Jan 06 '22 at 06:22
  • `:first-child` and `last-child` are conditions which must match on their own. Preceding a selector in front of it like `p` or `span` just further constrains the list of elements already matched by. So `p:first-child` reads as **Find all elements which are the first child elements of their parent; then from those found, give me only the `p` elements**. – connexo Jan 06 '22 at 07:38

2 Answers2

3

Because third p is not the last child, and first span is not first child of the parent.

Third p is p:last-of-type, but not p:last-child.
As well, first span is span:first-of-type, but not span:first-child.

p:first-child  {
  color: red;
}
p:last-child {
  color: blue;  /*This doesn't work*/
}
p:last-of-type {
  color: green;
}
span:first-child  {
  color: red;  /*This doesn't work*/
}
span:first-of-type {
  color: blue;
}
span:last-child {
  color: green;
}
<div>
  <p>The first paragraph.</p>
  <p>The second paragraph.</p>
  <p>The second paragraph.</p>
  <span>A..</span>
  <span>B.. </span>
  <span>C.. </span>
</div>
Sato Takeru
  • 1,092
  • 1
  • 5
  • 16
  • thanks but can u explain, WHY? If first-child works, it means its first-child of the parent (body element), the same way the last child shud be the last p of parent (body element). These children are relative to the parent body element, as I understand. Hence, the last p element of parent body is the last p element, why is it NOT? can u explain? At least that's what the SPEC says. But if I give these p another specific parent (e.g. div ), then the same works. SPEC says it should work WITH ANY CHILD OF ANY PARENT. In my case, the parent is Body element. – Tanvir Jan 06 '22 at 06:30
  • I just found dat the SPEC for all :first-of-type, last-of-type, :first-child and :last-child says- "the selected element had to have a parent. Beginning with Selectors Level 4, this is no longer required", Which means there's a glitch in their spec. if they DONT need any parent, then it must work, even if they needed, they have one in my case (the body element). In what sense, did u say, "third p is not the last child, and first span is not first child of the parent.". Firstly, as per SPEC, they don't need to be a child anymore, secondly, they are indeed child of body element. – Tanvir Jan 06 '22 at 06:45
1

You fail to understand how those selectors are meant to work, and do work.

:first-child and :last-child are conditions which must match on their own. Preceding it with a selector like p or span just further constrains the list of elements already matched by :first-child and :last-child.

So p:first-child actually means Find all elements which are the first child elements of their parent; then from those found, give me only the p elements.

connexo
  • 53,704
  • 14
  • 91
  • 128