28

Is there some way (without javascript) to make the nth-child affect the CSS?

For example when I have 10 images loaded, I would fade the opacity in, and give each image an animation delay of N seconds.

I can do this manually with nth-child(1){}, nth-child(2){} and so on, but that's obviously messy and has a finite amount of elements.

I have also tried loops and while that works out well for (10n+1), it breaks if i try to stray from the an+b formula (100n+10n). Also I doubt it would work to add 1 second for every n and 10 seconds for every 10n because one of those would overwrite the other.

This question is similar to this one from 2011 which is still open but a lot of time has passed and maybe there's a better answer these days.

PixelSnader
  • 552
  • 1
  • 4
  • 9

3 Answers3

19

Please remember that you can assign variables in CSS too.

:nth-child(1) { --nth-child: 1 }
:nth-child(2) { --nth-child: 2 }
:nth-child(3) { --nth-child: 3 }

Then you can apply it like this:

animation: fade-in calc(var(--nth-child) * 1s) 1s forwards;

And here come some demo.

Audi Nugraha
  • 640
  • 7
  • 7
  • 6
    While this might be useful for people looking for similar/related css issues, this does not get at the core of my particular question. You'd still have to set the variable manually for each object. In fact if I were to use css variables, it'd probably be more efficient to generate them via php. (Both in terms of lines of code, DRY, computation time, data transfer and perhaps flexibility/robustness) – PixelSnader Apr 20 '20 at 21:37
  • 1
    You can reuse those variable with different objects or components I believe and there is always more ways for a solution to be more efficient. However, what is the core of your particular question anyway? Do you want somekind of standard or built-in CSS feature to solve your problem? – Audi Nugraha Jun 20 '20 at 17:45
  • The core of my question is "can I *calculate* this in CSS". Because then it'd be possible to efficiently work with variable grids, and you'd have support for infinite elements, rather than a fixed amount. It'd be nice if there were some sort of CSS standard for it, yes, given that there are already calculations possible. But I can understand if it falls outside of the scope. Pragmatically, many effects can be done with JS/preprocessing, but that feels like a lot of extra work and data saved. – PixelSnader Jan 04 '22 at 10:36
11

CSS does not support using the current value of n, or the index of the child element currently being matched, from an :nth-child() expression as a variable, neither in calc() expressions nor var() expressions nor any other part of a property value.

The closest you can get is automating the manual process using a preprocessor that does support interpolating variables within selectors. This will work if you know the number of rules you need to build in advance, but only then.

BoltClock
  • 700,868
  • 160
  • 1,392
  • 1,356
2

Set a an inline css variable on the element style="--i: 0" Then add delay like calc((var(--duration)) * var(--i))

.ball {
  height: 5vmin;
  width: 5vmin;
  left: 50vw;
  border-radius: 50%;
  background: red;
  --duration: 1s;
  animation: move-right var(--duration) calc((var(--duration)) * var(--i)) forwards;
  animation-timing-function: linear;
}

@keyframes move-right {
  from {
    transform: none;
  }
  to {
    transform: translateX(20vw);
  }
}
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
</head>
<body>
          <div class="container">
        <div class="ball" style="--i: 0"></div>
        <div class="ball" style="--i: 1"></div>
        <div class="ball" style="--i: 2"></div>
        <div class="ball" style="--i: 3"></div>
        <div class="ball" style="--i: 4"></div>
        <div class="ball" style="--i: 5"></div>
      </div>
</body>
</html>
Bar Horing
  • 5,337
  • 3
  • 30
  • 26