About this snippet

Replace boring default inputs with this custom magnetic range slider. We built a beautiful floating tooltip that pops up and follows your cursor exactly as you drag the handle.

Size
4.0 KB
Uses
HTML, CSS, JavaScript
Loads
Nothing external
Views
166
<div class="slider-box">
  <div class="slider-header">
    <h3>Investment Amount</h3>
  </div>
  
  <div class="custom-slider-container" id="slider-container">
    <div class="slider-track" id="slider-track">
      <div class="slider-fill" id="slider-fill"></div>
    </div>
    
    <div class="slider-thumb" id="slider-thumb">
      <!-- The magnetic floating value popup -->
      <div class="slider-tooltip" id="slider-tooltip">$5,000</div>
    </div>
  </div>
  
  <div class="slider-labels">
    <span>$0</span>
    <span>$10,000</span>
  </div>
</div>
*, *::before, *::after {
  box-sizing: border-box;
}

body {
  font-family: system-ui, "Segoe UI", Roboto, Helvetica, Arial, sans-serif, "Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol";
  margin: 0;
  background: #f8fafc;
  display: flex;
  justify-content: center;
  align-items: center;
  min-height: 100vh;
  padding: 20px;
}

.slider-box {
  background: #ffffff;
  padding: 40px;
  border-radius: 20px;
  width: 100%;
  max-width: 500px;
  box-shadow: 0 20px 40px -10px rgba(0, 0, 0, 0.1);
  border: 1px solid #e2e8f0;
}

.slider-header h3 {
  margin: 0 0 40px 0;
  color: #0f172a;
  text-align: center;
}

.custom-slider-container {
  position: relative;
  height: 30px;
  display: flex;
  align-items: center;
  cursor: pointer;
  touch-action: none;
}

.slider-track {
  width: 100%;
  height: 8px;
  background: #e2e8f0;
  border-radius: 4px;
  position: relative;
}

.slider-fill {
  position: absolute;
  top: 0;
  left: 0;
  height: 100%;
  width: 50%;
  background: #3b82f6;
  border-radius: 4px;
  pointer-events: none;
}

.slider-thumb {
  position: absolute;
  top: 50%;
  left: 50%;
  transform: translate(-50%, -50%);
  width: 24px;
  height: 24px;
  background: #ffffff;
  border: 3px solid #3b82f6;
  border-radius: 50%;
  box-shadow: 0 4px 6px rgba(0,0,0,0.1);
  transition: transform 0.2s, box-shadow 0.2s;
  z-index: 10;
}

.custom-slider-container:active .slider-thumb {
  transform: translate(-50%, -50%) scale(1.2);
  box-shadow: 0 8px 15px rgba(59, 130, 246, 0.3);
}

.slider-tooltip {
  position: absolute;
  bottom: 40px;
  left: 50%;
  transform: translateX(-50%) scale(0);
  background: #0f172a;
  color: #ffffff;
  padding: 8px 12px;
  border-radius: 8px;
  font-weight: 600;
  font-size: 0.9rem;
  opacity: 0;
  transition: transform 0.2s cubic-bezier(0.34, 1.56, 0.64, 1), opacity 0.2s;
  pointer-events: none;
}

.slider-tooltip::after {
  content: "";
  position: absolute;
  top: 100%;
  left: 50%;
  transform: translateX(-50%);
  border-width: 6px;
  border-style: solid;
  border-color: #0f172a transparent transparent transparent;
}

.custom-slider-container:active .slider-tooltip,
.custom-slider-container:hover .slider-tooltip {
  transform: translateX(-50%) scale(1);
  opacity: 1;
}

.slider-labels {
  display: flex;
  justify-content: space-between;
  margin-top: 16px;
  color: #64748b;
  font-weight: 500;
  font-size: 0.9rem;
}
const container = document.getElementById("slider-container");
const thumb = document.getElementById("slider-thumb");
const fill = document.getElementById("slider-fill");
const tooltip = document.getElementById("slider-tooltip");

let isDragging = false;

function updateSlider(e) {
  const rect = container.getBoundingClientRect();
  let x = e.clientX - rect.left;
  
  /* Clamp bounds safely */
  if (x < 0) x = 0;
  if (x > rect.width) x = rect.width;
  
  const percentage = (x / rect.width) * 100;
  
  thumb.style.left = percentage + "%";
  fill.style.width = percentage + "%";
  
  /* Calculate value based on 10000 max */
  const value = Math.round((percentage / 100) * 10000);
  
  /* Format number with commas securely */
  tooltip.innerText = "$" + value.toLocaleString();
}

container.addEventListener("pointerdown", function(e) {
  isDragging = true;
  container.setPointerCapture(e.pointerId);
  updateSlider(e);
});

container.addEventListener("pointermove", function(e) {
  if (isDragging) {
    updateSlider(e);
  }
});

container.addEventListener("pointerup", function() {
  isDragging = false;
});

container.addEventListener("pointercancel", function() {
  isDragging = false;
});
Esc
↑↓ moveEnter select

Start from a template

Open an .html file, or HTML, CSS, JS, Markdown, Less or TypeScript files. You can also drop them here. Styles and scripts go into their panes.

Share

Source

Keyboard shortcuts

Save