Repetindo um conjunto de cores em divs aninhadas com CSS

8

Eu tenho um conjunto de quatro cores e quero aplicá-las aos divs aninhados, para que cada próximo filho tenha uma cor diferente. Se houver um quinto nível de aninhamento, quero começar de novo na primeira cor e manter isso em andamento, mesmo que eu tenha infinitos níveis profundos de aninhamento . Isso é possível apenas com seletores CSS e evita JavaScript ?

Atualmente, estou preso ao código a seguir - como você pode ver o rosa continua sendo aplicado a todos os divs aninhados após o quarto.

div {
  border: 1px solid black;
  font-weight: bold;
  padding: 30px;
}

div {
  color: red;
}

div>div {
  color: blue;
}

div>div>div {
  color: green;
}

div>div>div>div {
  color: pink;
}
<div>
  1
  <div>
    2
    <div>
      3
      <div>
        4
        <div>
          1
          <div>
            2
            <div>
              3
              <div>
                4
              </div>
            </div>
          </div>
        </div>
      </div>
    </div>
  </div>
</div>

easwee
fonte
Tente com : nth- selectors
sumeshsn1 1/10/19
2
Não acho que isso seja possível sem JavaScript, mas ficaria muito feliz em provar que estou errado.
David diz que restabelece Monica
@DavidThomas same here :)
easwee
está mudando o HTML uma possibilidade? Use um sectionou nome da classe para os top então seus seletores devem ser contidasection > div
collardeau
Infelizmente, o @ collardeau não é uma opção - caso contrário, eu os renderizaria com a classe de cores já aplicada.
easwee

Respostas:

8

Podemos usar hue-rotatepara dar o efeito desejado. Ao definir o filtro, 90degele repetirá a cada 4 crianças. Ao especificar a cor inicial como azul e girar o matiz 90 graus, obtemos o vermelho.

Eu não acho que é possível especificar quatro cores diferentes da maneira que você está usando usando CSS puro, a menos que esteja disposto a repetir div > div > ...para um ninho máximo teórico?

div {
  border: 1px solid black;
  font-weight: bold;
  padding: 30px;
  color: blue;
  filter: hue-rotate(90deg) saturate(2.5);
}
<div>1
  <div>2
    <div>3
      <div>4
        <div>1
          <div>2
            <div>3
              <div>4
                <div>1
                  <div>2
                    <div>3
                      <div>4
                      </div>
                    </div>
                  </div>
                </div>
              </div>
            </div>
          </div>
        </div>
      </div>
    </div>
  </div>
</div>

Exemplo com texto de lorem ipsum:

Richard Parnaby-King
fonte
As cores azul e roxo parecem mudar a cada rotação completa. Caso contrário, esta é uma solução engenhosa.
TylerH em 02/10
Qual navegador você está usando? Estou vendo vermelho, verde, azul, rosa repetido.
Richard Parnaby-King
Estou usando o Firefox 69.0.1 - as cores também se repetem, mas a sombra do azul e do roxo muda após a primeira iteração: i.stack.imgur.com/QZsEO.png De fato, agora que estou mais de perto, acho que as cores vermelho e verde também ficam mais claras após a primeira iteração. As cores parecem não mudar no Chrome (embora as caixas pareçam se sobrepor dependendo do espaço, enquanto elas são dimensionadas corretamente no Firefox).
TylerH
Causado por um problema de ponto flutuante introduzido com saturate. Ao aumentar a saturação saturate(3), obtemos exatamente as mesmas cores a cada loop, mas notei uma espécie de sombra ou sangramento quando empurro a saturação para o alto, o que torna MUITO difícil ler os personagens. Aumentei a saturação nos meus exemplos de código para 2,5 para reduzir a diferença entre as cores por loop.
Richard Parnaby-King
Heh, isso muda a cor da primeira iteração, mas ainda é diferente no FF - acho que provavelmente é seguro aceitar que só vai parecer diferente desde que o FF lide com isso dessa maneira.
TylerH
5

Aqui está uma idéia de solução baseada em algum truque de segundo plano. É mais uma aproximação do que uma solução robusta, pois considerarei o fato de que você terá apenas uma linha de texto em cada nível.

div {
  border: 1px solid black;
  border-bottom:0;
  font-weight: bold;
  padding: 30px 10px 0;
  line-height:1.2em;
  box-sizing:border-box;
  color:transparent;
}

.first {
  --l:calc(30px + 1.2em + 1px); /* The height of one line + the padding */
  background-image:
    repeating-linear-gradient(to bottom, 
      red    0                calc(1*var(--l)),
      blue   calc(1*var(--l)) calc(2*var(--l)),
      green  calc(2*var(--l)) calc(3*var(--l)),
      purple calc(3*var(--l)) calc(4*var(--l))
    );
  -webkit-background-clip:text;
  background-clip:text;
}
<div class="first">
  1
  <div>
    2
    <div>
      3
      <div>
        4
        <div>
          1
          <div>
            2
            <div>
              3
              <div>
                4
                <div>
                  5
                  <div>
                    6
                    <div>
                      7
                    </div>
                  </div>
                </div>
              </div>
            </div>
          </div>
        </div>
      </div>
    </div>
  </div>
</div>

Temani Afif
fonte