cssargumentslessless-mixins

Add argument into @keyframes property Less


I have a property @keyframes, I compiled with autoprefixer to add the needed prefixes.

What I would like to do, is to add an argument to the animation name (or wherever is possible) to change a value of properties into the keyframes key.

This is what I have right now :

@keyframes loader {
  0% { transform: translate(0, -50%) rotate(0deg); }
  100% { tranform: translate(0, -50%) rotate(360deg); }
}

And basically what I would like to do :

@keyframes loader(@transform) {
  0% { transform: @transform rotate(0deg); }
  100% { tranform: @transform rotate(360deg); }

Solution

  • Passing arguments to @keyframes cannot be done directly in Less. We can however wrap the whole @keyframes rule within a parent mixin, pass the argument to that mixin and use it within the frames.

    .loader(@transform){ /* wrapper mixin which accepts input parameter */
       @keyframes loader {
         0% { transform: @transform rotate(0deg); }
         100% { transform: @transform rotate(360deg); }
       }
    }
    
    .loader(translate(0, -50%)); /* mixin call */
    

    (Curt had provided an answer initially but had deleted it for reasons unknown to me.)


    Just in case you are interested, generic keyframe mixins can also be written in Less like given below.

    Sample 1:

    .generickeyframe(@name; @from; @to){ /* takes name, from frame rules, to frame rules */
      @keyframes @name{
        0% { @from();}
        100% { @to();}
      }
    }
    .generickeyframe(loader; {transform: translate(0,-50%) rotate(0deg)}; 
                {transform: translate(0,-50%) rotate(360deg)});
    

    Sample 2:

    .keyframefromto(@name; @from; @to){
      @keyframes @name{
        0% { transform: @from;}
        100% { transform: @to;}
      }
    }
    .keyframefromto(loader; translate(0,-50%) rotate(0deg); translate(0,-50%) rotate(360deg));
    

    If multiple frames are required to be present within the @keyframes rule, we could make use of array-list and loops like in the below snippet. This mixin takes the name of the animation, the list of frames (their percentage numbers) and the properties for each frame (in the form of rulesets) as parameters.

    .generickeyframe(@name; @framelist; @frameprops){
      @keyframes @name{
        .loop-framelist(@index) when (@index <= length(@framelist)){
          @framepos: extract(@framelist, @index) * 1%;
          @{framepos}{
            @props: extract(@frameprops, @index);
            @props();
          }
          .loop-framelist(@index + 1);
        }
        .loop-framelist(1);
      }
    }
    .generickeyframe(loader; 
                    0,25,50,75,100; 
                    {transform: translateX(10px);},
                    {transform: translateX(20px);},
                    {transform: translateX(50px);},
                    {transform: translateX(20px);},
                    {transform: translateX(10px);}
                    );
    

    Compiled CSS:

    @keyframes loader {
      0% {transform: translateX(10px);}
      25% {transform: translateX(20px);}
      50% {transform: translateX(50px);}
      75% {transform: translateX(20px);}
      100% {transform: translateX(10px);}
    }