#1896·stylex

[babel-plugin] `stylex.keyframes` and `stylex.viewTransitionClass` add `px` to unitless numbers like `fontWeight: 700`

Author: Om-singhaICreated Sep 18, 2026Updated Sep 18, 2026

Describe the issue

Inside stylex.keyframes() and stylex.viewTransitionClass(), a number on a unitless property gets px added when the property name has more than one word. fontWeight: 700 compiles to font-weight:700px and zIndex: 2 to z-index:2px. Those aren't valid values, so the browser drops them and the weight or stacking never changes during the animation. lineHeight: 1.5 becomes line-height:1.5px, which is valid, so the browser keeps it and the lines collapse.

The types ask for numbers here (zIndex is 'auto' | number) and the same values compile fine in stylex.create(). One word properties like opacity and scale aren't affected.

Expected behavior

The same values stylex.create() gives: font-weight:400, line-height:1.2, z-index:1 and so on in the keyframes, and animation-iteration-count:2 on the view transition group.

Steps to reproduce

  1. On main (20f2a50, @stylexjs/babel-plugin 0.19.1, Node 25.6.1), compile the test case below with the babel plugin and its default options.
  2. Pass metadata.stylex to processStylexRules(rules, { useLayers: false }).

Test case

javascript
import * as stylex from '@stylexjs/stylex';

const pulse = stylex.keyframes({
  from: { fontWeight: 400, lineHeight: 1.2, zIndex: 1 },
  to: { fontWeight: 700, lineHeight: 1.5, zIndex: 2 },
});

export const vt = stylex.viewTransitionClass({
  group: { animationIterationCount: 2 },
});

export const styles = stylex.create({
  root: {
    animationName: pulse,
    fontWeight: 700,
    lineHeight: 1.5,
    zIndex: 2,
    animationIterationCount: 2,
  },
});

What I get:

css
@keyframes x1q2p22t-B{from{font-weight:400px;line-height:1.2px;z-index:1px;}to{font-weight:700px;line-height:1.5px;z-index:2px;}}
::view-transition-group(*.x1lb59x2){animation-iteration-count:2px;}
.xuij49y:not(#\#){animation-iteration-count:2}
.xcru9ll:not(#\#){animation-name:x1q2p22t-B}
.x1xlr1w8:not(#\#){font-weight:700}
.x1evy7pa:not(#\#){line-height:1.5}
.xhtitgo:not(#\#){z-index:2}

Additional comments

Both functions dashify the keys before they call transformValue, and getNumberSuffix only knows the camelCase names. So font-weight misses the unitless list and falls back to px. stylex.create() passes the camelCase key, which is why it's fine there. I've got a small fix with tests and will open a PR.