Estilizar irmãos com base na contagem e no índice

Antes, para aplicar estilos exclusivos a cada irmão em uma lista, era necessário usar loops :nth-child complexos ou JavaScript para injetar estilos inline. O CSS moderno oferece sibling-index() e sibling-count() para realizar esses cálculos diretamente na folha de estilo, permitindo layouts dinâmicos e sistemas de cores que se adaptam automaticamente conforme os elementos são adicionados ou removidos.

Sistemas de cores dinâmicas

É possível criar um espectro de cores em um grupo de irmãos calculando um valor exclusivo de matiz ou de luminosidade para cada filho. Isso garante um efeito de gradiente consistente, independentemente do número de itens.

.swatch {
  /* Calculate hue by dividing the full 360deg circle by total siblings */
  /* and multiplying by the current element's 1-based index */
  background-color: hsl(
    calc(360deg / sibling-count() * sibling-index()),
    70%,
    50%
  );
}

Layout simétrico e efeitos de ventilador

Para criar efeitos simétricos (como um "leque" ou centralizar itens), use a contagem total para encontrar o ponto médio da lista.

.card {
  /* Find the center index (e.g., 3 if there are 5 siblings) */
  --center: calc((sibling-count() + 1) / 2);

  /* Rotate items away from the center: negative for left, positive for right */
  /* center element gets 0deg rotation */
  transform: rotate(calc(10deg * (sibling-index() - var(--center))));
}

Posicionamento circular e complexo

Ao combinar essas funções com a trigonometria CSS (sin(), cos()), é possível posicionar elementos em um círculo perfeito sem coordenadas manuais.

.orb {
  /* Calculate the angle for this item's position on a 360deg circle */
  --angle: calc(360deg / sibling-count() * sibling-index());
  --radius: 150px;

  /* Set the pre-transformed position for all items to be centered */
  position: absolute;
  place-self: center;


  /* Position each element around the parent center */
  transform: translate(
    calc(cos(var(--angle)) * var(--radius)),
    calc(sin(var(--angle)) * var(--radius))
  );
}

Estratégias de fallback

Se sibling-index() e sibling-count() não forem compatíveis, forneça um substituto injetando propriedades personalizadas de CSS via JavaScript. OBRIGATÓRIO: use a detecção de recursos com CSS.supports() para garantir que o script seja executado apenas quando necessário.

/* MANDATORY: Check for native support before applying fallback */
if (!CSS.supports('top: calc(sibling-index() * 1px)')) {
  const items = document.querySelectorAll('.item');
  items.forEach((item, index) => {
    /* MANDATORY: Injected index must be 1-based to match native function */
    item.style.setProperty('--sibling-index', index + 1);
    item.style.setProperty('--sibling-count', items.length);
  });
}

No CSS, use essas variáveis como base e as substitua por funções nativas em um bloco @supports. OBRIGATÓRIO: você PRECISA unir as substituições de função nativa em @supports para garantir que as variáveis permaneçam válidas em navegadores mais antigos.

.item {
  /* 1. Set base values using variables (from JS fallback) */
  --index: var(--sibling-index);
  --count: var(--sibling-count);

  /* 2. Use the computed variables - replace this with your implementation-specific styles */
  background-color: hsl(calc(360deg / var(--count) * var(--index)), 70%, 50%);
}

@supports (top: calc(sibling-index() * 1px)) {
  .item {
    /* 3. Override with native functions ONLY if supported */
    --index: sibling-index();
    --count: sibling-count();
  }
}