noUiSlider Vertical EQ Sliders — Free JS Snippet

noUiSlider Vertical EQ Sliders with Live Curve · Forms · Plain HTML, CSS & JS · Live preview

CategoryForms

What's included

Features

Ten independent vertical noUiSlider instances with a shared range
Vertical orientation with rtl direction so higher values sit at the top
Live canvas curve using a Catmull-Rom spline converted to Bézier segments
Preset buttons that drive every slider through set()
Presets deselect as soon as the user drags away from them
Half-decibel steps and signed dB readouts
Double-click to reset a band and full keyboard support
Ready to connect to Web Audio BiquadFilterNode peaking filters

About this UI Snippet

noUiSlider Vertical EQ Sliders — HTML, CSS & JavaScript

Screenshot of the noUiSlider Vertical EQ Sliders with Live Curve snippet rendered live

Vertical sliders are where most range-input code falls apart. Native range inputs can be rotated with a CSS transform, but the rotated box still occupies its old layout, keyboard direction is inconsistent across browsers and the styling hooks are a mess of vendor pseudo-elements. noUiSlider has real vertical support built in through orientation: 'vertical', which is why an equalizer — ten identical vertical controls that have to look and behave the same — is a good showcase for it.

Two options matter and one trap is worth naming. orientation: 'vertical' switches the track to run top to bottom, and direction: 'rtl' flips it so the highest value is at the top, which is what everyone expects from a fader. The trap is that a vertical noUiSlider has no intrinsic height — the library styles the track but takes its size from CSS, so a slider with no height rule renders as a zero-pixel line and looks like the component failed to initialise. Here the height comes from the .eq-slider rule.

Each band is its own noUiSlider instance with a range of -12 to +12 dB in half-decibel steps. A single draw() function reads every instance's current value and paints the frequency response on a canvas. The ten gains become points, and a Catmull-Rom spline converted to cubic Bézier segments joins them into a smooth curve, with a filled area to the zero line — the same visual language real audio plug-ins use. Because update fires continuously while dragging, the curve follows the fader in real time.

The presets call set() on every slider, and the active preset button is cleared the moment a drag starts, since the curve no longer matches it. Double-clicking a band resets it to 0 dB, a small convention that audio-software users expect. Nothing here produces sound — the same gain array can be applied to a chain of Web Audio BiquadFilterNode peaking filters if you want to wire it to real audio.

Build with AI

Build, Understand, Optimize, and Extend It With AI

Ask an AI assistant like Claude to wire the sliders to Web Audio BiquadFilterNodes with a looping audio source, add a bypass toggle, or save custom presets to local storage.

Prompt to recreate it

Copy this into your AI assistant of choice to build the effect from scratch, or as a jumping-off point for your own variant:

text
Build a ten-band vertical equalizer with noUiSlider 15 loaded from a CDN.

Requirements:
- Create ten sliders with orientation: 'vertical', direction: 'rtl', range -12 to +12, step 0.5 and an explicit CSS height on each track.
- Show a signed dB readout above each slider and the band frequency below it.
- Draw the combined response on a canvas by joining the ten gains with a Catmull-Rom spline converted to cubic Bezier segments, plus a filled area to the zero line.
- Add preset buttons (Flat, Bass boost, Vocal, Treble, Smile) that call set() on every slider, and clear the active preset as soon as the user starts dragging.
- Double-clicking a slider resets it to 0 dB.

Want to tighten it up first? Run this prompt through the AI Prompt Studio to score it across 8 quality dimensions, catch anti-patterns, and tune the wording for Claude, ChatGPT, or Gemini before you paste it in.

Source Code

<div class="eq-wrap">
  <div class="eq-top">
    <h3>10-Band Equalizer</h3>
    <div class="eq-presets" role="group" aria-label="Presets">
      <button type="button" data-p="flat">Flat</button>
      <button type="button" data-p="bass">Bass boost</button>
      <button type="button" data-p="vocal">Vocal</button>
      <button type="button" data-p="treble">Treble</button>
      <button type="button" data-p="smile" class="on">Smile</button>
    </div>
  </div>
  <canvas id="eqCurve" width="640" height="120" aria-label="Frequency response curve"></canvas>
  <div class="eq-bands" id="eqBands"></div>
  <p class="eq-foot">Drag a band, or focus one and use the arrow keys. Double-click a band to reset it to 0 dB.</p>
</div>

Step by step

How to Use

  1. 1
    Drag a faderDrag any band up or down. Its dB readout changes and the curve reshapes instantly.
  2. 2
    Load a presetClick Bass boost, Vocal, Treble or Smile to move every fader at once and highlight the preset.
  3. 3
    Fine-tune with the keyboardTab to a band and use the arrow keys to nudge it in half-decibel steps.
  4. 4
    Reset a bandDouble-click a fader to return that one band to 0 dB.
  5. 5
    Watch the preset clearStart dragging after choosing a preset — the highlight drops because the curve is now custom.

Real-world uses

Common Use Cases

Audio and music apps
Front-end for a web player or synth. Pair it with the dual-handle price slider to see the same library in a horizontal, two-handle setup.
Mixing and control panels
Any bank of related levels: lighting channels, per-region weights, scoring rubrics.
Image editor adjustments
Vertical sliders for brightness, contrast and curves alongside a live preview.
Learning vertical slider layout
Shows the explicit-height requirement and orientation/direction pairing that trips people up.

Got questions?

Frequently Asked Questions

The library does not size vertical sliders itself. Give the element an explicit height in CSS, as the .eq-slider rule does here.

For a vertical slider rtl puts the maximum at the top and the minimum at the bottom, which matches how faders work.

The ten gains are treated as points and joined with a Catmull-Rom spline, converted into cubic Bézier segments that canvas can draw.

No. It only produces gain values. Map each to a Web Audio BiquadFilterNode of type peaking at the band frequency to hear the effect.

Call get() on each slider instance. This snippet collects them in gains() every time the curve is redrawn.

Add entries to BANDS and PRESETS. The layout, curve and reset behaviour are all driven by those arrays.

Yes. Use the JSX, Vue, Angular or Tailwind export buttons on this page to convert the markup and styles. The behaviour comes from noUiSlider, so in a framework project install it with npm install nouislider instead of the CDN tag, create it in useEffect / onMounted / ngAfterViewInit on the element, and release it with noUiSlider destroy() when the component unmounts.