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>



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:


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>

Ao utilizar nosso site, você reconhece que leu e compreendeu nossa Política de Cookies e nossa Política de Privacidade.
Licensed under cc by-sa 3.0 with attribution required.