Severin Spörri
Severin Spörri

Reputation: 120

How can I use calculated values as keyframes?

I want to make my train run in a 60 minutes cycle. Therefore, 60 Minutes are 100% of the cycle. I want to do a calculation and use the result as a keyframe.

div {
  width: 50px;
  height: 20px;
  background-color: blue;
  position: relative;
  animation-name: example;
  animation-duration: 60s;
  animation-iteration-count: infinite;
}

@keyframes example { # 
  (1/0.6)%   {left:300px; top:0px;} # neunkirch
  (3/0.6)%   {left:200px; top:0px;} # hallau
  (4/0.6)%   {left:200px; top:0px;} # hallau
  (3/0.6)%   {left:100px; top:0px;} # trasadingen
  (4/0.6)%   {left:100px; top:0px;} # trasadingen
  (8/0.6)%   {left:0px; top:0px;} # erzingen
  (18/0.6)%   {left:0px; top:0px;} # erzingen
  (19/0.6)%   {left:100px; top:0px;} # trasadingen
  (20/0.6)%   {left:100px; top:0px;} # trasadingen
  (22/0.6)%   {left:200px; top:0px;} # hallau
  (24/0.6)%   {left:200px; top:0px;} # hallau
  (26/0.6)%   {left:300px; top:0px;} # neunkirch
  (30/0.6)%   {left:400px; top:0px;} # beringen
  (32/0.6)%   {left:500px; top:0px;} # beringerfeld
  (35/0.6)%   {left:600px; top:0px;} # neuhausen bad
  (39/0.6)%   {left:700px; top:0px;} # schaffhausen
  (49/0.6)%   {left:700px; top:0px;} # schaffhausen
  (52/0.6)%   {left:600px; top:0px;} # neuhausen bad
  (54/0.6)%   {left:500px; top:0px;} # beringerfeld
  (55/0.6)%   {left:500px; top:0px;} # beringerfeld
  (56/0.6)%   {left:400px; top:0px;} # beringen
  (57/0.6)%   {left:400px; top:0px;} # beringen
  (60/0.6)%   {left:300px; top:0px;} # neunkirch
}
<h1>CSS Animation</h1>

<div></div>

PS: sorry, but I didn't manage to post the html as a html, because if I want to indent 4 spaces with shift, it will just jump to the next window on this website (the tag section).

Upvotes: 2

Views: 1031

Answers (3)

Severin Sp&#246;rri
Severin Sp&#246;rri

Reputation: 120

Welp, if I have to use a preprocessor, I can use python to print me CSS code just as well :/

I guess I can only automate this on a website, once I know Angular/React/Vue

Upvotes: 0

kmp
kmp

Reputation: 802

TL;DR

You can't. Use a preprocessor like sass. SASS is cool, CSS is not.

The Problem

CSS works as a templating system. You can declare a selector which then selects an element on which you are able to change it's props, right?

Yeah.. not really. You can't do whatever you like. The available selectors as of now are pretty strict in terms of dynamics. So to overcome this weakness, they introduced variables (below there's sample on how you'd use them).

:root {
  --bgColor: #fafafa;
}

/* 
some styling
...
*/

.my-class {
  background-color: var(--bgColor);
}

Well.. not the solution you're looking for, because it only works on properties (eg. background-color, font-size, width etc.) and will be evaluated at runtime. Same goes for calc().

The Solution

Since we cannot use dynamic variables or calculated values as selectors or as part of a selector, you cannot implement this in pure CSS. However, you can use a preprocessor such as sass or less to be able to use many features including string interpolation -> #{myCalculatedValue}%

CSS preprocessors transpiles the features they've provided for you into valid CSS code before the browser runs it so basically every variable you've declared (including string interpolation, but excluding CSS vars since it wasn't provided by the preprocessor) will be transpiled into a static value which CSS can use (eg. 1/0.6% will evaluate to 1.67%). It doesn't really matter what you're doing as long as it transpiles. You can also mix the two. Example: in sass you can use CSS variables as well as SCSS variables.

Requirements

This is great. We have dynamic values, we have loops, we have functions. All we need is a compiler or transpiler that turns our scss, sass or less code into real CSS for the browsers to be able to read it and apply.

If you're using a frontend framework (such as Angular, React or Vue), you don't have to do anything besides initializing the project with scss styling.

Otherwise you'll need to have something like node-sass or sass, but you'll have to transpile it manually before you start your server.

node-sass is the best IMO eg. if you use server-side rendering, but there's several sass transpiler on npm.

EDIT: You can find several transpilers on npm.

BONUS TIP: If you're using VSCode, there's an extension called Live Sass Compiler(ritwickdey.live-sass) which, as the name suggests, will compile your sass files to css files automatically (same can be achieved with the --watch tag if you're using a transpiler).

Upvotes: 3

Brooke Hart
Brooke Hart

Reputation: 4049

If you're using CSS directly, then you will have to do these calculations first and use the final values directly in your CSS.

However, if you use a CSS preprocessor such as Sass then you can do this. For example, in Sass you can interpolate values using the syntax #{}:

@keyframes example {
    #{1/0.6}% { /* ... */ }
    #{2/0.6}% { /* ... */ }
    // ...
}

Using a preprocessor would also allow you to create a CSS animation using a loop, which could be pretty useful for certain animations.

Upvotes: 1

Related Questions