Frontend-Entwicklung, UX Engineering
B2B-Marktplatz
2024
Ein Power-Curve-Range-Slider für einen Preisfilter von €0 bis €50 Mio.
Ein B2B-Marktplatz brauchte einen Preisfilter über fünf Größenordnungen, von wenigen hundert Euro bis über 50 Millionen. Der eingebaute lineare Slider war praktisch unbrauchbar: 99% des Tracks gehörten dem oberen Bereich, und in den gängigsten Preisklassen war eine gezielte Auswahl so gut wie unmöglich.
Ein linearer Slider in einer nicht-linearen Welt
Lineare Zuordnung hieß: Der komplette Bereich von €0 bis €500k, in dem die meisten Einträge lagen, quetschte sich in rund 10 Pixel auf einem 1.000px breiten Slider. Einen Wert gezielt treffen? Aussichtslos. Der Kunde wollte etwas, das sich über die gesamte Spanne natürlich anfühlt, ohne auf mehrere Eingabefelder oder manuelle Zahleneingabe auszuweichen.
99 % des Slider-Tracks gehörten dem oberen Bereich. In den gängigsten Preisklassen war die Auswahl reines Glücksspiel.
Eine konfigurierbare Potenzkurve
Statt einer logarithmischen Skala mit ihren eigenen Tücken habe ich auf eine Potenzkurve gesetzt. Die Slider-Position wird auf 0-1 normalisiert und mit einem konfigurierbaren Steepness-Exponenten potenziert. Bei Steepness 5 deckt die untere Hälfte des Tracks nur rund 3 % des Gesamtbereichs ab, also genau da feine Kontrolle, wo sie gebraucht wird. Weil der Exponent als Data-Attribut am Element liegt, kann jede Slider-Instanz eine andere Kurve fahren, und A/B-Tests kommen ohne eine Zeile Code aus.
Bildet eine Slider-Position (0 bis Resolution) über die Potenzkurve auf einen realen Wert ab:
const toLogValue = (position, maxValue, resolution, steepness) => {
if (position === 0) return 0;
const normalized = position / resolution;
return Math.round(Math.pow(normalized, steepness) * maxValue);
};Interaktive Demo
Kurvenparameter ändern und die Auswirkung in Echtzeit beobachten, inklusive Steepness-Vergleich und Schrittweiten-Visualisierung.
Die Slider-Position (0 bis Resolution) wird auf 0-1 normalisiert und dann mit dem Steepness-Exponenten potenziert. Das ergibt feine Kontrolle am unteren Ende und zunehmend größere Sprünge nach oben. Bei Steepness 5 bildet die erste Hälfte des Sliders nur rund 3 % des Wertebereichs ab, die letzten 10 % decken etwa 40 % ab. roundToNiceStep() rundet die Werte anschließend auf saubere, gut lesbare Zahlen.
Die Umkehrung: Aus einem realen Wert die passende Slider-Position berechnen:
const toSliderPosition = (value, maxValue, resolution, steepness) => {
if (value === 0) return 0;
const normalized = Math.pow(value / maxValue, 1 / steepness);
return normalized * resolution;
};Unsichtbare Präzision
Nachdem der Power-Curve-Slider live ging, stieg die Filternutzung spürbar. Leute, die den Preisfilter vorher ignoriert hatten, griffen plötzlich darauf zu. Support-Tickets zum Thema "Slider funktioniert nicht" fielen auf null. Die gesamte Umsetzung hat unter 30 Zeilen und keinen Performance-Overhead.
Rundet Rohwerte auf gut lesbare Zahlen, die mit der Größenordnung skalieren:
const roundToNiceStep = (num) => {
if (num === 0) return 0;
const magnitude = Math.floor(Math.log10(num));
const step = Math.pow(10, magnitude) / 20;
return Math.round(num / step) * step;
};