3

I have an animation that fills a table cell with a color. I want the animations keyframes to.width to be a variable that is controlled by an angular 2 component.

CSS:

#passing {
  display: block;
  height: 100%;
  background-color: #81C784;
  animation-duration: 2s;
  animation-name: slideright;
}

@keyframes slideright {
  from {
    margin-right: 0%;
    width: 0%;
  }
  to {
    margin-right: 50%;
    width: 50%;
  }
}

HTML:

<div id="passing"
     [style.width.%]="cells[id].width"
     [style.keyframes.slideright.to.width.%]="cells[id].width">
</div>

The [style.width.%] works fine but I want to do something like the above to set the animation width dynamically for each cell but I am not sure how to access that attribute.

2 Answers 2

10

I was able to solve this by removing the to declaration in the CSS and setting the value with [ngStyle] in the view.

New CSS:

#passing {
  display: block;
  height: 100%;
  background-color: #81C784;
  animation-duration: 2s;
  animation-name: slideright;
}

@keyframes slideright {
  from {
    margin-right: 0%;
    width: 0%;
  }
}

New HTML:

<div id="passing"
     [style.width.%]="cells[id].width"
     [ngStyle]="{'to': cells[id].width}">
</div>
Sign up to request clarification or add additional context in comments.

2 Comments

how can angular understand what keyframe is the rule referring to? An element can have different keyframes. Sounds like a hack to me
CSS variables together with Angular 9+ allow cleaner solution. @CristianTraìna have a look at my answer: https://stackoverflow.com/a/63506012/5135171
10

Here's a solution based on CSS variables, that get updated by Angular dynamically via @HostBinding.

The CSS declaration stays almost the same, but uses a CSS variable to determine the target width of the keyframe (with an optional default value of 50%).

#passing {
  display: block;
  height: 100%;
  background-color: #81C784;
  animation-duration: 2s;
  animation-name: slideright;
}

@keyframes slideright {
  from {
    margin-right: 0%;
    width: 0%;
  }
  to {
    margin-right: 50%;
    width: var(--target-width, 50%);
  }
}

To update the value of --target-width, add a variable to your Angular component and annotate it with @HostBinding():

@HostBinding('style.--target-width')
private targetWidth: string = '60%';

This will add the CSS variable to the component host element. Since CSS variables cascade down you can use it anywhere within the host component's template styling.

You can now use the member to update the CSS variable at runtime and assign it any value.

Sidenotes:

  • Be aware that bindings to camelCase properties will be converted to camel-case.
  • According to this Github issue this approach only works for Angular 9+.

2 Comments

whill the animation be updated everytime the variable gets updated?
A wonderful solution <3

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.