D
P
0
← All articles Baca dalam Bahasa Indonesia

JavaScript, DOM & Browser Animation

`transform` Silently Dropped by the Browser? `calc()` Still References a Renamed CSS Variable

· · 4 min read
`transform` Silently Dropped by the Browser? `calc()` Still References a Renamed CSS Variable

The symptom

On a client site there was a product-showcase carousel: one large slide in the center, and beneath it a thumbnail strip that was supposed to slide sideways as you advanced, keeping the active thumbnail centered. The strip never moved. Whatever slide was active, the thumbnails kept showing the exact same neighbors, as if the position were locked at index 0. The main slide changed smoothly; only the strip underneath stayed frozen.

The maddening part: zero console errors. No Uncaught, no warning, no CSS line struck out in red in DevTools. And it turned out this had been quietly broken for several versions, ever since a rename in v1.7.14, with nobody noticing until the client asked why the thumbnails never scrolled.

The dead ends

My first suspect was obvious: the index math was wrong. The strip slides via a translate3d whose offset depends on the active index, so if the index were stuck at 0, nothing moving would make sense. I logged the index on every slide change:

console.log("active index:", indexMV);

It climbed cleanly: 0, 1, 2, 3. So the JS knew the right index. Not it.

Second suspect: maybe the handler was not firing, or I was targeting the wrong element. I dropped a log inside the handler and checked the element reference. The handler ran on every change, the element was correct. The JS really was executing the code that set the transform. Yet the strip stayed put.

What finally cracked it: I opened the strip element in DevTools and looked at its inline style. The JS was clearly computing and assigning a transform, but the element's style attribute was empty. No transform at all. I tried setting it manually from the console, pasting the exact string the code produced:

el.style.transform = "calc(-1 * (var(--wg-thumb-w) + var(--wg-thumb-gap)))";
console.log(el.style.transform); // "" (empty)

It came back an empty string. The browser rejected the value without a sound. That was the lightbulb: the assignment was not failing on a JS error, it was failing because the value was invalid and the CSSOM silently discarded it.

The root cause

I looked closely at the string being produced: it contained var(--wg-thumb-w) and var(--wg-thumb-gap). I grepped the theme's CSS for those two names:

grep -rn -- "--wg-thumb" src/

Nothing. Those names no longer existed anywhere. Back in v1.7.14 there had been a big namespace rename: every --wg-* custom property (a leftover from an older component called WearableGallery) was renamed to --folio-*. The rename was clean on the CSS side; every variable definition had been updated. But one reference was missed: a template string in animations.js:1432 was still assembling a calc() with the old variable names.

And this is the crux of why it failed silently. A calc() whose terms include an undefined custom property is invalid as a whole. When you set element.style.transform to an invalid value, the CSSOM does not throw; it simply ignores the assignment and leaves the property as it was, empty in this case. So there is no console error, no red line, nothing. The transform just never exists, and the strip sits at its starting position forever.

This is a different animal from the other CSS-variable bug class, like a variable dropped because a build tool tree-shook it out. Here the build was fine; the new --folio-* variables existed and were valid. The only thing wrong was a single JS string still pointing at a dead name.

The fix

The core fix is one line: point the JS reference at the new variable names.

// before (broken: vars undefined, calc invalid, transform discarded):
`calc(${-indexMV} * (var(--wg-thumb-w) + var(--wg-thumb-gap)))`
// after:
`calc(${-indexMV} * (var(--folio-thumb-w) + var(--folio-thumb-gap)))`

Once swapped, the calc() became valid, the transform was accepted again, and the thumbnail strip immediately tracked the active slide the way it should.

But fixing one line was not enough to relax. This bug happened precisely because a rename I thought was finished had left one stray reference behind. So my last step was to prove there were no others. I grepped the whole theme for the old names, not just in CSS but in JS too:

grep -rn -e "--wg-" -e "wgallery" src/

Zero hits. Only then was I confident the rename was actually clean.

Takeaways