CSS + JSMIT licensed

Skewed Isometric Perspective Slider

An innovative slider that appears to lie flat on a tilted isometric desktop plane via CSS 3D transforms, with a grid-line surface, perspective shadow beneath the thumb, and three live metric cards for power, speed, and efficiency.

Live Demo
Plain CSSTailwind v4
Try it

Build interactive UI like this from scratch: 20 HTML, CSS & JavaScript projects

ZTM · JavaScript Web Projects · 30‑day money-back guarantee · Affiliate link

10% off at checkout with code
Check ZTM Course

The code

<div class="rs-15">
  <div class="rs-15__stage">
    <div class="rs-15__label-row">
      <div class="rs-15__title">3D Isometric Slider</div>
      <div class="rs-15__val-display">
        <div class="rs-15__val-big"><span id="rs-15-val">65</span>%</div>
        <div class="rs-15__val-label">INTENSITY</div>
      </div>
    </div>
    <div class="rs-15__iso-wrap">
      <div class="rs-15__iso-surface"></div>
      <div class="rs-15__track-container">
        <div class="rs-15__track-outer">
          <div class="rs-15__track-bg">
            <div class="rs-15__track-fill" id="rs-15-fill" style="width:65%"></div>
            <input class="rs-15__input" type="range" min="0" max="100" value="65" id="rs-15-inp">
          </div>
        </div>
        <div class="rs-15__shadow" id="rs-15-shadow" style="width:65%;margin-left:0"></div>
        <div class="rs-15__ticks-iso">
          <span class="rs-15__tick-iso">0</span>
          <span class="rs-15__tick-iso">25</span>
          <span class="rs-15__tick-iso">50</span>
          <span class="rs-15__tick-iso">75</span>
          <span class="rs-15__tick-iso">100</span>
        </div>
      </div>
    </div>
    <div class="rs-15__metrics">
      <div class="rs-15__metric">
        <div class="rs-15__metric-val" id="rs-15-pow">65W</div>
        <div class="rs-15__metric-label">POWER</div>
      </div>
      <div class="rs-15__metric">
        <div class="rs-15__metric-val" id="rs-15-spd">4.2m/s</div>
        <div class="rs-15__metric-label">SPEED</div>
      </div>
      <div class="rs-15__metric">
        <div class="rs-15__metric-val" id="rs-15-eff">A+</div>
        <div class="rs-15__metric-label">EFFICIENCY</div>
      </div>
    </div>
  </div>
</div>
.rs-15,
.rs-15 *,
.rs-15 *::before,
.rs-15 *::after {
  box-sizing: border-box;
  margin: 0;
  padding: 0;
}

.rs-15 ::selection {
  background: #8b5cf6;
  color: #fff;
}

.rs-15 {
  --bg: #0d0d1f;
  --violet: #8b5cf6;
  --violet-glow: rgba(139,92,246,0.5);
  --cyan: #22d3ee;
  --text: #f0f0ff;
  --muted: #555580;
  --grid: rgba(139,92,246,0.12);
  background: var(--bg);
  min-height: 100vh;
  display: flex;
  align-items: center;
  justify-content: center;
  padding: 60px 24px 40px;
  font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', sans-serif;
  perspective: 800px;
}

.rs-15__stage {
  width: 100%;
  max-width: 460px;
}

.rs-15__label-row {
  display: flex;
  justify-content: space-between;
  align-items: flex-end;
  margin-bottom: 20px;
}

.rs-15__title {
  font-size: 20px;
  font-weight: 800;
  color: var(--text);
}

.rs-15__val-display {
  text-align: right;
}

.rs-15__val-big {
  font-size: 36px;
  font-weight: 900;
  letter-spacing: -1px;
  color: var(--violet);
  text-shadow: 0 0 20px var(--violet-glow);
  font-variant-numeric: tabular-nums;
}

.rs-15__val-label {
  font-size: 11px;
  color: var(--muted);
  letter-spacing: 1px;
}

.rs-15__iso-wrap {
  transform: rotateX(30deg) rotateZ(-10deg);
  transform-style: preserve-3d;
  position: relative;
  padding: 32px 24px;
}

.rs-15__iso-surface {
  position: absolute;
  inset: 0;
  background: linear-gradient(rgba(139,92,246,0.06) 1px, transparent 1px), linear-gradient(90deg, rgba(139,92,246,0.06) 1px, transparent 1px);
  background-size: 24px 24px;
  border: 1px solid rgba(139,92,246,0.2);
  border-radius: 8px;
}

.rs-15__iso-surface::before {
  content: '';
  position: absolute;
  left: 0;
  right: 0;
  bottom: -8px;
  height: 8px;
  background: rgba(139,92,246,0.12);
  transform: rotateX(-90deg);
  transform-origin: top;
}

.rs-15__track-container {
  position: relative;
  z-index: 2;
}

.rs-15__track-outer {
  background: rgba(0,0,0,0.6);
  border: 1px solid rgba(139,92,246,0.3);
  border-radius: 8px;
  padding: 10px;
  box-shadow: 0 8px 32px rgba(0,0,0,0.5), inset 0 1px 0 rgba(255,255,255,0.05);
}

.rs-15__track-bg {
  height: 10px;
  background: rgba(0,0,0,0.5);
  border-radius: 5px;
  position: relative;
}

.rs-15__track-fill {
  position: absolute;
  left: 0;
  top: 0;
  height: 100%;
  background: linear-gradient(90deg, var(--violet), var(--cyan));
  border-radius: 5px;
  box-shadow: 0 0 20px var(--violet-glow);
  transition: width 0.05s;
}

.rs-15__input {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  -webkit-appearance: none;
  appearance: none;
  background: transparent;
  cursor: ew-resize;
  outline: none;
  z-index: 2;
}

.rs-15__input::-webkit-slider-thumb {
  -webkit-appearance: none;
  width: 24px;
  height: 30px;
  background: linear-gradient(180deg, #c4b5fd, #8b5cf6);
  border: none;
  border-radius: 4px 4px 0 0;
  box-shadow: 0 -4px 12px var(--violet-glow), 0 4px 0 rgba(0,0,0,0.4);
  cursor: ew-resize;
  transition: transform 0.15s;
}

.rs-15__input:active::-webkit-slider-thumb {
  transform: scaleY(1.1);
}

.rs-15__input::-moz-range-thumb {
  width: 24px;
  height: 30px;
  border-radius: 4px;
  border: none;
  background: var(--violet);
  cursor: ew-resize;
}

.rs-15__shadow {
  height: 4px;
  background: radial-gradient(ellipse at center, rgba(139,92,246,0.4) 0%, transparent 70%);
  margin-top: 4px;
  transition: width 0.05s, margin-left 0.05s;
  position: relative;
}

.rs-15__ticks-iso {
  display: flex;
  justify-content: space-between;
  margin-top: 14px;
}

.rs-15__tick-iso {
  font-size: 10px;
  color: var(--muted);
}

.rs-15__metrics {
  display: flex;
  gap: 12px;
  margin-top: 20px;
  transform: rotateX(0deg);
}

.rs-15__metric {
  flex: 1;
  background: rgba(139,92,246,0.08);
  border: 1px solid rgba(139,92,246,0.2);
  border-radius: 10px;
  padding: 12px;
  text-align: center;
}

.rs-15__metric-val {
  font-size: 18px;
  font-weight: 800;
  color: var(--violet);
}

.rs-15__metric-label {
  font-size: 10px;
  color: var(--muted);
  letter-spacing: 1px;
}

@media (prefers-reduced-motion: reduce) {
  .rs-15__track-fill,
    .rs-15__shadow {
    transition: none;
  }

  .rs-15__iso-wrap {
    transform: none;
  }
}
(function(){
  const inp = document.getElementById('rs-15-inp');
  const fill = document.getElementById('rs-15-fill');
  const valEl = document.getElementById('rs-15-val');
  const pow = document.getElementById('rs-15-pow');
  const spd = document.getElementById('rs-15-spd');
  const eff = document.getElementById('rs-15-eff');
  const grades = ['D','C','C+','B','B+','A','A+'];
  function update(){
    const v = +inp.value;
    fill.style.width = v+'%';
    valEl.textContent = v;
    pow.textContent = v+'W';
    spd.textContent = (v/100*8).toFixed(1)+'m/s';
    eff.textContent = grades[Math.floor(v/100*6)];
  }
  inp.addEventListener('input', update);
  update();
})();
Paste this into ChatGPT, Claude, Cursor, or any coding assistant. The block below is pre-framed with everything the AI needs to integrate this demo into your project — markup, styles, scoping notes, and the source URL. Hit Copy and paste straight into your chat.
Here's a working CSS Range Slider from CodeFronts. Use it as-is or adapt to your framework. All classes are scoped under a unique prefix so the code won't collide with your existing styles. MIT licensed.
Demo: Skewed Isometric Perspective Slider
Source: https://codefronts.com/components/css-range-sliders/skewed-isometric-perspective-slider/

An innovative slider that appears to lie flat on a tilted isometric desktop plane via CSS 3D transforms, with a grid-line surface, perspective shadow beneath the thumb, and three live metric cards for power, speed, and efficiency.
## HTML
```html
<div class="rs-15">
  <div class="rs-15__stage">
    <div class="rs-15__label-row">
      <div class="rs-15__title">3D Isometric Slider</div>
      <div class="rs-15__val-display">
        <div class="rs-15__val-big"><span id="rs-15-val">65</span>%</div>
        <div class="rs-15__val-label">INTENSITY</div>
      </div>
    </div>
    <div class="rs-15__iso-wrap">
      <div class="rs-15__iso-surface"></div>
      <div class="rs-15__track-container">
        <div class="rs-15__track-outer">
          <div class="rs-15__track-bg">
            <div class="rs-15__track-fill" id="rs-15-fill" style="width:65%"></div>
            <input class="rs-15__input" type="range" min="0" max="100" value="65" id="rs-15-inp">
          </div>
        </div>
        <div class="rs-15__shadow" id="rs-15-shadow" style="width:65%;margin-left:0"></div>
        <div class="rs-15__ticks-iso">
          <span class="rs-15__tick-iso">0</span>
          <span class="rs-15__tick-iso">25</span>
          <span class="rs-15__tick-iso">50</span>
          <span class="rs-15__tick-iso">75</span>
          <span class="rs-15__tick-iso">100</span>
        </div>
      </div>
    </div>
    <div class="rs-15__metrics">
      <div class="rs-15__metric">
        <div class="rs-15__metric-val" id="rs-15-pow">65W</div>
        <div class="rs-15__metric-label">POWER</div>
      </div>
      <div class="rs-15__metric">
        <div class="rs-15__metric-val" id="rs-15-spd">4.2m/s</div>
        <div class="rs-15__metric-label">SPEED</div>
      </div>
      <div class="rs-15__metric">
        <div class="rs-15__metric-val" id="rs-15-eff">A+</div>
        <div class="rs-15__metric-label">EFFICIENCY</div>
      </div>
    </div>
  </div>
</div>
```
## CSS
```css
.rs-15,
.rs-15 *,
.rs-15 *::before,
.rs-15 *::after {
  box-sizing: border-box;
  margin: 0;
  padding: 0;
}

.rs-15 ::selection {
  background: #8b5cf6;
  color: #fff;
}

.rs-15 {
  --bg: #0d0d1f;
  --violet: #8b5cf6;
  --violet-glow: rgba(139,92,246,0.5);
  --cyan: #22d3ee;
  --text: #f0f0ff;
  --muted: #555580;
  --grid: rgba(139,92,246,0.12);
  background: var(--bg);
  min-height: 100vh;
  display: flex;
  align-items: center;
  justify-content: center;
  padding: 60px 24px 40px;
  font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', sans-serif;
  perspective: 800px;
}

.rs-15__stage {
  width: 100%;
  max-width: 460px;
}

.rs-15__label-row {
  display: flex;
  justify-content: space-between;
  align-items: flex-end;
  margin-bottom: 20px;
}

.rs-15__title {
  font-size: 20px;
  font-weight: 800;
  color: var(--text);
}

.rs-15__val-display {
  text-align: right;
}

.rs-15__val-big {
  font-size: 36px;
  font-weight: 900;
  letter-spacing: -1px;
  color: var(--violet);
  text-shadow: 0 0 20px var(--violet-glow);
  font-variant-numeric: tabular-nums;
}

.rs-15__val-label {
  font-size: 11px;
  color: var(--muted);
  letter-spacing: 1px;
}

.rs-15__iso-wrap {
  transform: rotateX(30deg) rotateZ(-10deg);
  transform-style: preserve-3d;
  position: relative;
  padding: 32px 24px;
}

.rs-15__iso-surface {
  position: absolute;
  inset: 0;
  background: linear-gradient(rgba(139,92,246,0.06) 1px, transparent 1px), linear-gradient(90deg, rgba(139,92,246,0.06) 1px, transparent 1px);
  background-size: 24px 24px;
  border: 1px solid rgba(139,92,246,0.2);
  border-radius: 8px;
}

.rs-15__iso-surface::before {
  content: '';
  position: absolute;
  left: 0;
  right: 0;
  bottom: -8px;
  height: 8px;
  background: rgba(139,92,246,0.12);
  transform: rotateX(-90deg);
  transform-origin: top;
}

.rs-15__track-container {
  position: relative;
  z-index: 2;
}

.rs-15__track-outer {
  background: rgba(0,0,0,0.6);
  border: 1px solid rgba(139,92,246,0.3);
  border-radius: 8px;
  padding: 10px;
  box-shadow: 0 8px 32px rgba(0,0,0,0.5), inset 0 1px 0 rgba(255,255,255,0.05);
}

.rs-15__track-bg {
  height: 10px;
  background: rgba(0,0,0,0.5);
  border-radius: 5px;
  position: relative;
}

.rs-15__track-fill {
  position: absolute;
  left: 0;
  top: 0;
  height: 100%;
  background: linear-gradient(90deg, var(--violet), var(--cyan));
  border-radius: 5px;
  box-shadow: 0 0 20px var(--violet-glow);
  transition: width 0.05s;
}

.rs-15__input {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  -webkit-appearance: none;
  appearance: none;
  background: transparent;
  cursor: ew-resize;
  outline: none;
  z-index: 2;
}

.rs-15__input::-webkit-slider-thumb {
  -webkit-appearance: none;
  width: 24px;
  height: 30px;
  background: linear-gradient(180deg, #c4b5fd, #8b5cf6);
  border: none;
  border-radius: 4px 4px 0 0;
  box-shadow: 0 -4px 12px var(--violet-glow), 0 4px 0 rgba(0,0,0,0.4);
  cursor: ew-resize;
  transition: transform 0.15s;
}

.rs-15__input:active::-webkit-slider-thumb {
  transform: scaleY(1.1);
}

.rs-15__input::-moz-range-thumb {
  width: 24px;
  height: 30px;
  border-radius: 4px;
  border: none;
  background: var(--violet);
  cursor: ew-resize;
}

.rs-15__shadow {
  height: 4px;
  background: radial-gradient(ellipse at center, rgba(139,92,246,0.4) 0%, transparent 70%);
  margin-top: 4px;
  transition: width 0.05s, margin-left 0.05s;
  position: relative;
}

.rs-15__ticks-iso {
  display: flex;
  justify-content: space-between;
  margin-top: 14px;
}

.rs-15__tick-iso {
  font-size: 10px;
  color: var(--muted);
}

.rs-15__metrics {
  display: flex;
  gap: 12px;
  margin-top: 20px;
  transform: rotateX(0deg);
}

.rs-15__metric {
  flex: 1;
  background: rgba(139,92,246,0.08);
  border: 1px solid rgba(139,92,246,0.2);
  border-radius: 10px;
  padding: 12px;
  text-align: center;
}

.rs-15__metric-val {
  font-size: 18px;
  font-weight: 800;
  color: var(--violet);
}

.rs-15__metric-label {
  font-size: 10px;
  color: var(--muted);
  letter-spacing: 1px;
}

@media (prefers-reduced-motion: reduce) {
  .rs-15__track-fill,
    .rs-15__shadow {
    transition: none;
  }

  .rs-15__iso-wrap {
    transform: none;
  }
}
```

## JavaScript
```js
(function(){
  const inp = document.getElementById('rs-15-inp');
  const fill = document.getElementById('rs-15-fill');
  const valEl = document.getElementById('rs-15-val');
  const pow = document.getElementById('rs-15-pow');
  const spd = document.getElementById('rs-15-spd');
  const eff = document.getElementById('rs-15-eff');
  const grades = ['D','C','C+','B','B+','A','A+'];
  function update(){
    const v = +inp.value;
    fill.style.width = v+'%';
    valEl.textContent = v;
    pow.textContent = v+'W';
    spd.textContent = (v/100*8).toFixed(1)+'m/s';
    eff.textContent = grades[Math.floor(v/100*6)];
  }
  inp.addEventListener('input', update);
  update();
})();
```

How this works

The isometric illusion uses transform: rotateX(30deg) rotateZ(-10deg) on the .rs-15__iso-wrap container with transform-style: preserve-3d to maintain the 3D context. The grid surface is a background pattern using two overlapping linear-gradient instances creating perpendicular lines, and a ::before pseudo-element with transform: rotateX(-90deg) simulates the side depth panel of the isometric surface. The track and input live inside this transformed container, inheriting the 3D tilt naturally.

The gradient track fill uses linear-gradient(90deg, var(--violet), var(--cyan)) with a box-shadow: 0 0 20px bloom. The thumb is styled as a tall rectangular prism using asymmetric heights in the ::-webkit-slider-thumb pseudo-element, with a top highlight gradient to fake the top face of a 3D peg. Metric cards below the isometric stage exist in normal 2D flow, allowing readable text while the slider itself is rotated.

Make it yours

  • Adjust the viewing angle by changing rotateX(30deg) — increase toward 45° for a more top-down isometric view, or decrease toward 15° for a more side-on cinematic perspective.
  • Add a cast shadow beneath the isometric surface by creating an absolutely positioned div with a blurred radial gradient background placed directly below the wrapper element.
  • Change the efficiency grade mapping in the grades[] array — add more tiers like S and SS for a gaming-style rating system.
  • Animate the surface grid lines by adding a CSS animation that shifts background-position on the grid pattern, creating a moving conveyor belt effect beneath the slider.
  • Add a depth axis by rendering a second vertical slider inside the 3D container with writing-mode: vertical-lr, creating a full isometric X/Y control surface.

Gotchas — read before shipping

  • transform-style: preserve-3d is required on the parent for child elements to participate in the 3D space — without it, rotateX/rotateZ on children flatten to 2D and the depth panel disappears.
  • Range input event handling can be unreliable inside heavily transformed elements on some mobile browsers — if the slider feels unresponsive, add a touch-action: none to the input and handle touch events manually.
  • The @media (prefers-reduced-motion) block removes the 3D transform entirely (transform: none) — this flattens the isometric view to a standard 2D slider, which is the accessible fallback for vestibular disorder users.

Browser support

ChromeSafariFirefoxEdge
80+14+78+80+

CSS 3D transforms with preserve-3d are well-supported; Safari may render the rotated input thumb interaction area slightly offset from the visual — test carefully on iOS.

Techniques used in this demo

Search CodeFronts

Loading…