2

Consider the following code:

<h2>
  Working example
</h2>
<div class="test">
  <button>FirstChild (Yellow)</button>
  <button>Middle</button>
  <button>Middle</button>
  <button>LastChild (Red)</button>
</div>

<div class="test">
  <h2>
  Not working example - no DIVs
  </h2>
  <button>FirstChild (Yellow)</button>
  <button>Middle</button>
  <button>Middle</button>
  <button>LastChild (Red)</button>
</div>

<div class="test">
  <h2>
  Not working example - Divs
  </h2>
  <div>
    <button>FirstChild (Yellow)</button>
  </div>
  <div>
    <button>Middle</button>
  </div>
  <div>
    <button>Middle</button>
  </div>
  <div>
    <button>LastChild (Red)</button>
  </div>
</div>

And the following CSS:

.test button:first-child {
  background: yellow;
}

.test button:last-child {
  background: red;
}

.test button:not(:last-child):not(:first-child) {
  background: cyan;
}

The result:

enter image description here

Why my CSS if not finding the child button element if it is inside a div or has another element (h2) in the middle ? There are no other button elements in the test div.

How to make this CSS consider the 3 given situations with the correct behaviour (Working example) ?

JSFiddle here

Mendes
  • 17,489
  • 35
  • 150
  • 263
  • It will not work because they are not the first/last child of their **same** parent-container. – Dekel Aug 29 '17 at 00:44
  • `button:first-child` means: the first child and the element that is a button. Both requirements must be fulfilled. – zerkms Aug 29 '17 at 00:45
  • Thanks @zerkms for the hint. What I need is the "first button found in the child tree" or something similar... Is there a way to accomplish that ? – Mendes Aug 29 '17 at 00:53
  • 1
    @Mendes `first-of-type` is what you want instead of `first-child` – ESR Aug 29 '17 at 01:30

3 Answers3

2

.test button:first-child this works on 1st one but failed on 2nd since first child of .test is h2 not button

SOLUTION:

Order matters in CSS so first set all button under .test to green, then set first/last to their color.

You should use first-of-type and last-of-type to target first of type (button or div) in siblings, or last in siblings, if you not sure about siblings, you should really read this:

Adjacent sibling selectors

https://developer.mozilla.org/en/docs/Web/CSS/Adjacent_sibling_selectors

.test button {
  background: green;
}

.test > button:first-of-type,
.test div:first-of-type button {
  background: yellow;
}

.test > button:last-of-type,
.test div:last-of-type button {
  background: red;
}
<h2>
  Working example
</h2>
<div class="test">
  <button>FirstChild (Yellow)</button>
  <button>Middle</button>
  <button>Middle</button>
  <button>LastChild (Red)</button>
</div>

<div class="test">
  <h2>
    Not working example - no DIVs
  </h2>
  <button>FirstChild (Yellow)</button>
  <button>Middle</button>
  <button>Middle</button>
  <button>LastChild (Red)</button>
</div>

<div class="test">
  <h2>
    Not working example - Divs
  </h2>
  <div>
    <button>FirstChild (Yellow)</button>
  </div>
  <div>
    <button>Middle</button>
  </div>
  <div>
    <button>Middle</button>
  </div>
  <div>
    <button>LastChild (Red)</button>
  </div>
</div>
Dalin Huang
  • 11,212
  • 5
  • 32
  • 49
0

Apparently you are mistaking what :last-child and the rest means and how it works. It is not the content of the button but the last element in a group of child elements. Your usage is incorrect.

You can try .test div:last-child button {color:red;} as an example.

Rob
  • 14,746
  • 28
  • 47
  • 65
  • Got it. What I need is the "first button element found"... Is there a way to find it and fix my code ? The suggestion does not work property also... – Mendes Aug 29 '17 at 00:50
0

Find the child element

.test button:first-child or .test button:nth-child(1)

.test button:nth-child(2)
.test button:nth-child(3)

.test button:last-child or  .test button:nth-child(4) 
bdalina
  • 503
  • 10
  • 16