3

I wanna be able to do something like so:

.myTransitionableElement {
  transition: all .5s;

  .subChild { transition: all 1s }

  @include transitionKeyframes(
    start: {
      opacity: 0;
      transform: tranlsate(50px);

      .subChild {
        transform: rotate(45deg);
      }
    },
    end: {
      opacity: 1;
      transform: tranlsate(0);

      .subChild {
        transform: rotate(0);
      }
    }
  )
}


@mixin transitionKeyframes($args) {
  &.transitionStartKeyframe {
    @include map_get($args, "start");
  }
  &.transitionEndKeyframe {
    @include map_get($args, "end");
  }
}

Which should at the end be equivalent to:

.myTransitionableElement {
  transition: all .5s;

  .subChild { transition: all 1s }

  &.transitionStartKeyframe {
    opacity: 0;
    transform: tranlsate(50px);

    .subChild {
      transform: rotate(45deg);
    }
  }
  &.transitionEndKeyframe {
    opacity: 1;
    transform: tranlsate(0);

    .subChild {
      transform: rotate(0);
    }
  }
}

The reason behind this is that I wanna find a way to not have to remember those classes names every time I use a JS abstraction that uses those classes.

Daniel Birowsky Popeski
  • 8,752
  • 12
  • 60
  • 125

2 Answers2

2

You can't pass different content as arguments in SASS mixins. Below is example of what you can achieve using SASS. Can you specify what you want to achieve here?

@mixin rtl() {
  &.ltr {
    @content;
    direction: ltr;
  }
  &.rtl {
    @content;
    direction: rtl;
  }
}

.parent {
  @include rtl {
   display: flex;
  }
}
puja singhal
  • 131
  • 7
0

You can try different approaches here. In this particular one I'm using map to hold the data for me. But if attributes and class names are fixed; you can even simplify it.

$map: (Start: (self: (opacity: '0', transform: 'tranlsate(50px)'), child: (transform: rotate(45deg))), End: (self: (opacity: '1', transform: 'tranlsate(0)'), child: (transform: rotate(0))));
$prefix: transition; $postfix: Keyframe;

@mixin transitionKeyframes($map) {
    @each $key, $val in $map {
    &.#{$prefix}#{$key}#{$postfix} {
      @each $attr, $prop in map-get($val, self) {
        #{$attr}: #{$prop};
      }

      .subChild {
        @each $attr, $prop in map-get($val, child) {
          #{$attr}: #{$prop};
        }
      }
    }
  }
}


.myTransitionableElement  {
  @include transitionKeyframes($map);
  transition: all .5s;
  .subChild { transition: all 1s }
}

Use mixins for a repetitive task. Modify the mixin or $frames if you have many variations. Breakdown opacity and transistion further to smaller mixins and invoke them conditionally.

$prefix: transition; $postfix: Keyframe;
$frames: 'Start', 'End';
$opcity-main: ('Start': 0, 'End': 1);
$translate-main: ('Start': 50, 'End': 0);

@mixin transitionKeyframes($frame) {
    @each $key in $frame {
    &.#{$prefix}#{$key}#{$postfix} {
      $opacity: map-get($opcity-main, $key);
      $translate: map-get($translate-main, $key);
      opacity: $opacity;
      transform: tranlsate($translate + px);
    }
  }
}


.myTransitionableElement  {
  @include transitionKeyframes($frames);
  transition: all .5s;
  .subChild { transition: all 1s }
}
Sumit Ridhal
  • 1,359
  • 3
  • 14
  • 30
  • Notice how in my example `.subChild` is within the argument-content-block. That means that everything inside it is dynamic. So `.subChild` cannot be part of the mixin itself. Imagine how the consumer of this mixin might wanna have 5 sub-childs with different animation behavior. Thanx for the effort! – Daniel Birowsky Popeski Oct 16 '19 at 16:23
  • @Birowsky I understand your problem. But I don't think this is the right usage for mixins here. Breakdown your code to smaller chunks and use mixins if there is a repetitive task rather than using it as Panacea. I would suggest use maps to handle data used for each class you are creating. – Sumit Ridhal Oct 17 '19 at 06:36
  • @Birowsky if you can post the entire code. I might be able to help you out. – Sumit Ridhal Oct 17 '19 at 06:36