Drive Dozens of Layers from One Slider: After Effects Expressions in Practice
Stop re-keyframing a dozen layers when the client wants a faster fade. One Slider Control plus a three-line expression lets a single value drive opacity, scale, or audio-reactive motion across an entire composition.
08 Apr 2026, 12:30 UTC

You've built a lower-third animation with twelve text layers, each fading in with a slight stagger. The client wants the fade 20% faster. Without expressions, that's twelve layers of keyframe edits. With expressions, it's one slider drag. That's the real pitch for expressions: not flashy generative art, but collapsing repetitive keyframing into a single control point.
What an expression actually is
An expression is a small JavaScript snippet attached to a property (opacity, position, rotation, and so on) that computes the property's value every frame instead of reading it from keyframes. You add one by Alt-clicking (Option-clicking on macOS) the stopwatch next to a property in the Timeline panel. The expression editor opens, and whatever the code evaluates to becomes the property's value for that frame.
Because the value is computed live, an expression can reference other layers, composition time, or effect controls. Change the thing it references, and every dependent property updates — no re-keyframing.
Worked example: one slider, many fades
The maintainable pattern is to put an Expression Control on a single "controller" layer and have everything else read from it. Slider Control is the workhorse: it's just a number you can scrub, found under Effect > Expression Controls.
- Create a new composition and add a null object (Layer > New > Null Object). Rename it
CTRL. - With
CTRLselected, apply Effect > Expression Controls > Slider Control. Rename the effectFadeSpeedin the Effect Controls panel so the expression reads clearly later. - Add a text or shape layer. Alt-click the Opacity stopwatch and enter:
// On the target layer's Opacity property
var speed = thisComp.layer("CTRL").effect("FadeSpeed")("Slider");
var t = time - inPoint; // seconds since this layer starts
linear(t, 0, speed, 0, 100); // ramp 0→100 over 'speed' secondsDuplicate that layer as many times as you like and stagger the layers' start times. Because each expression reads inPoint, every copy fades in relative to its own start, and all of them obey the same FadeSpeed slider. Drag the slider from 1.0 to 0.5 and the whole sequence tightens instantly.
Two details worth knowing:
linear(t, 0, speed, 0, 100)maps an input range to an output range — here, "as t goes from 0 tospeedseconds, opacity goes from 0 to 100." It clamps by default, so opacity holds at 100 after the fade.- Using
inPointinstead of hardcoded times is what makes the layers reusable. Move a layer in the timeline and its animation follows.
Verifying it works
Set FadeSpeed to 1, scrub the playhead across the first two seconds, and confirm each layer's opacity ramps from 0 to 100 in the Timeline's value readout. Then open the Graph Editor with the opacity property selected — you should see a clean linear ramp per layer, offset by each layer's start time. If a layer shows an error icon instead, open Window > Expression Console to see which reference failed; the most common cause is a renamed layer or effect that no longer matches the string in the expression.
Render a short work area (a few seconds is enough) and check that preview playback stays smooth. For a handful of layers with simple math like this, it will. That check matters more for the next pattern.
Beyond sliders: audio-reactive motion
The same reference mechanism powers the classic beat-reactive trick. Use Animation > Keyframe Assistant > Convert Audio to Keyframes on a layer with audio; After Effects creates an "Audio Amplitude" null whose Slider channels hold per-frame amplitude. Then an expression like this on a layer's Scale pulses it with the music:
var amp = thisComp.layer("Audio Amplitude").effect("Both Channels")("Slider");
var s = linear(amp, 0, 30, 100, 140); // tune 30 to your track's peak
[s, s];Note the array return: Scale is a two-dimensional property, so the expression must return [x, y], not a single number. Returning the wrong dimension is a frequent first-expression bug.
The trade-offs
Expressions are evaluated every frame, per layer. A heavy expression — loops over many layers, recursive references, sampleImage() over large areas — multiplies into real render cost on long compositions. Keep the math simple and bake results to keyframes (Animation > Keyframe Assistant > Convert Expression to Keyframes) once a section is finalized.
Two more practical cautions. First, debugging is blunt: a syntax error disables the property and shows a warning banner, and a typo in a shared controller name can break every layer that references it at once. Build and test in a small sandbox comp before wiring up a full project. Second, portability: expressions that reference layers by name break silently-ish when someone renames things, and references to external footage break if assets go missing when the project is shared. Prefer descriptive, stable names for controller layers, and document them on a locked "README" layer if the project will change hands.
Where to go next
Start with the slider-driven opacity example on one comp you're currently maintaining — pick the property you adjust most often and move it to a controller. Once that feels natural, explore wiggle() for organic motion and loopOut() for repeating keyframed cycles. The habit that pays off isn't memorizing functions; it's asking "will I ever need to change this in more than one place?" and reaching for an expression when the answer is yes.
0 replies
A thoughtful contribution can make all the difference. Be the first to share one.