Search code examples
htmlcsscss-selectors

Using nth-child for inconsistent formatting?


What is the most economical way to write this code?

.colHeaders div:nth-child(2),
.colHeaders div:nth-child(3),
.colHeaders div:nth-child(4),
.colHeaders div:nth-child(11),
.colHeaders div:nth-child(12),
.colHeaders div:nth-child(14),
.colHeaders div:nth-child(15),
.colHeaders div:nth-child(16) {background: lightgrey;}

And why can I tell nth-child to skip children at the start, but not the end, of my parent element?

For example:

.colHeaders div:nth-child (2,3,4,11,12,14,15,16) {background: lightgrey;}

.colHeaders div:nth-child (2-4,11-12,14-16) {background: lightgrey;}

.colHeaders div:nth-child (n+2,4) {background: lightgrey;}
.colHeaders div:nth-child (n+11,12) {background: lightgrey;}
.colHeaders div:nth-child (n+14,16) {background: lightgrey;}

Solution

  • From your statements, you want

    2/3/4, 11/12, and the last 3.

    You can "merge" selectors using :is() and target individual ranges with nth-child and nth-last-child.

    For ranges you can state these like "nth-child(n+X):nth-child(-n+Y)" where X is the first to be selected and Y the last.

    Like so:

    .wrap {
      display: grid;
      grid-template-columns: repeat(4, 70px);
      gap: 0.25em;
    }
    
    .item {
      padding: .5em;
      border: 1px solid grey;
    }
    
    .item:is(:nth-child(n+2):nth-child(-n+4),
    /*2, 3 & 4 */
    
    :nth-child(n+11):nth-child(-n+12),
    /*11 & 12 */
    
    :nth-last-child(-n + 3))
    /* last 3 */
    
    {
      background: lightgreen;
    }
    <div class="wrap">
      <div class="item">Item 1</div>
      <div class="item">Item 2</div>
      <div class="item">Item 3</div>
      <div class="item">Item 4</div>
      <div class="item">Item 5</div>
      <div class="item">Item 6</div>
      <div class="item">Item 7</div>
      <div class="item">Item 8</div>
      <div class="item">Item 9</div>
      <div class="item">Item 10</div>
      <div class="item">Item 11</div>
      <div class="item">Item 12</div>
      <div class="item">Item 13</div>
      <div class="item">Item 14</div>
      <div class="item">Item 15</div>
      <div class="item">Item 16</div>
    </div>

    Of course there are many ways to write this, I'm sure someone can come up with something better. Naturally, adding a class to those items and targeting that would be optimal...and quicker, probably.