skip to Main Content

I’m trying to get each child of a div translated a different percent:

#letters:nth-child(n){
    transition: all 1s ease;
    transform: translateX(calc(n*10%));
    transition-delay: calc(n*200ms);
}

None of transform and transition-delay seems to work (the delay is equal for all the letters), but the value of transform also returns an error `mismatched parameters (). How to fix it?

3

Answers


  1. The issue with your code is that the calc() function needs numerical values. In your case, you’re using n*10% as an argument to calc(), but the n is not a numerical value with a unit. It represents the index of the child element, and you can’t use it directly in the calc() function. You can use css variables to store the translateX values for each child element and then use those in the transform property. Like this:

    #letters {
        --translate-x: 10%; /* Default translation value for the first child */
    }
    
    #letters:nth-child(2) {
        --translate-x: 20%;
    }
    
    #letters:nth-child(3) {
        --translate-x: 30%;
    }
    
    /* Add more if needed */
    
    #letters > div {
        transition: all 1s ease;
        transform: translateX(var(--translate-x));
        transition-delay: calc(var(--translate-x) * 0.2s); /* Delay in seconds (200ms = 0.2s) */
    }
    

    Hope this helps

    Login or Signup to reply.
  2. There is no way to use the n from nth-child() as you intend in CSS as it is not a numerial value you can use in calc().
    The only way to achieve your aim (until the sibling-index() is implemented, see the answer by Temani Afif) is to manually set each child it’s own properties like this :

    .letters:nth-child(1){
        transition: all 1s ease;
        transform: translateX(calc(1*10%));
        transition-delay: calc(1*200ms);
    }
    
    .letters:nth-child(2){
        transition: all 1s ease;
        transform: translateX(calc(2*10%));
        transition-delay: calc(2*200ms);
    }
    ...
    

    You could use a CSS preprocessor to generate such code (ex: SCSS or LESS).
    Here is what it could look like with SCSS :

    $letters : 50;
    
    @for $i from 1 through $letters {
      .letters:nth-child(#{$i}) {
        transition: all 1s ease;
        transform: translateX($i*10%);
        transition-delay: $i*200ms;
      }
    }
    

    That would generate the CSS for 50 .letters elements.

    On a side note, your CSS code seems to imply you have several elements with the id #letters in your HTML. ids should be unique in a HTML document. That is why I used a class instead of id in my examples.

    Login or Signup to reply.
  3. In the near future (https://github.com/w3c/csswg-drafts/issues/4559#issuecomment-1642880894) you can do this:

    #letters * {
      transition: all 1s ease;
      transform: translateX(calc(sibling-index()*10%));
      transition-delay: calc(sibling-index()*200ms);
    }
    
    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search