csscss-selectorspseudo-class

How to have CSS affect every other element that's not invisible


I'm trying to work with CSS to alternate background color in my divs. I can do that, but which divs display changes. I'd like to be able to alternate only what's currently visible. Otherwise it's pretty random what background color appears based on unrelated factors for which divs are visible.

This is what I'm currently trying:

.dialog {
  display:flex;
  flex-direction:row;
  align-items:center;
  background-color: #FFFFFF22;
}
#output-table > .dialog:not([style*="none"]):nth-child(odd) {
  background-color: #FFFFFF11;
}

And the html:

<div id="output-table">
  <div class="dialog">stuff1</div>
  <div class="dialog">stuff2</div>
  <div class="dialog">etc....</div>
</div>

Currently when the page loads all divs are visible, and background-color alternates, but it looks like nothing changes when some divs become invisible (i.e. the order of color alternation is the same and not alternating properly according to visibility).
.dialog is set to display:flex by default. JavaScript may set each individual element as display:flex or display:none, but the elements aren't individually set when the page is loaded. Thus why I try not(\[style\*="none"\]) rather than [style="flex"] as I'm not sure if CSS treats those two cases differently.
I'm sure I could solve things by having js add/remove classes when it changes the display. I just am wondering if there's some CSS-only solution.

EDIT I've conceded and have had js add classes. It's displaying some odd behavior though.

.dialog {
  display: flex;
  flex-direction: row;
  align-items: center;
}

#output-table>.show:nth-child(odd) {
  background-color: #FFFFFF11;
}

#output-table>.show:nth-child(even) {
  background-color: #FFFFFF22;
}
<div class="output-table">
  <div class="dialog show"></div>
  <div class="dialog show"></div>
  <div class="dialog hide"></div>
  <div class="dialog hide"></div>
  <div class="dialog hide"></div>
  <div class="dialog show"></div>
  <div class="dialog show"></div>
  <div class="dialog show"></div>
  <div class="dialog hide"></div>
</div>

background-color is alternating but ONLY for divs that are adjacent in the html. That is, "even" and "odd" are resetting every time they have div.hide between them. In the example above, it's displaying: color1 color2 (hidden divs) color1 color2 color1 And so forth. Of course this is not what I'm after.

EDIT EDIT Thank you everyone I understand now. My current, working css:

.hide{
    display:none;
}
#output-table > div:nth-child(odd of div.show){
    background-color: #FFFFFF11;
}
#output-table > div:nth-child(even of div.show){
    background-color: #FFFFFF22;
}

Took some understanding that nth-child applies to every single child, and .show:nth-child was still doing so. But nth-child(even of div.show) can filter it to only some children.


Solution

  • you can use .dialog:nth-child(odd of :not(.noDisplay)):

    #output-table > .dialog:nth-child(odd of :not(.noDisplay)) {
      background : lightgreen;
      }
    
    .noDisplay {
      display: none;
      }
    
      
    <div id="output-table">
      <div class="dialog">stuff1</div>
      <div class="dialog">stuff2</div>
      <div class="dialog">stuff3</div>
      <div class="dialog">stuff4</div>
      <div class="dialog noDisplay">stuff---5</div>
      <div class="dialog">stuff6</div>
      <div class="dialog">stuff7</div>
      <div class="dialog">stuff8</div>
    </div>