Pen Settings

HTML

CSS

CSS Base

Vendor Prefixing

Add External Stylesheets/Pens

Any URLs added here will be added as <link>s in order, and before the CSS in the editor. You can use the CSS from another Pen by using its URL and the proper URL extension.

+ add another resource

JavaScript

Babel includes JSX processing.

Add External Scripts/Pens

Any URL's added here will be added as <script>s in order, and run before the JavaScript in the editor. You can use the URL of any other Pen and it will include the JavaScript from that Pen.

+ add another resource

Packages

Add Packages

Search for and use JavaScript packages from npm here. By selecting a package, an import statement will be added to the top of the JavaScript editor for this package.

Behavior

Auto Save

If active, Pens will autosave every 30 seconds after being saved once.

Auto-Updating Preview

If enabled, the preview panel updates automatically as you code. If disabled, use the "Run" button to update.

Format on Save

If enabled, your code will be formatted when you actively save your Pen. Note: your code becomes un-folded during formatting.

Editor Settings

Code Indentation

Want to change your Syntax Highlighting theme, Fonts and more?

Visit your global Editor Settings.

HTML

              
                <p>Ideally, we want progress to always be in the middle of the thumb.</p>
<input id="checkbox" type="checkbox"><label for="checkbox">Use clamp()</label>
<div class="slider-box">
  <div class="slider-progress"></div>
  <input class="slider-input" id="range" autocomplete="off" type="range" min="20" max="100" value="80" step="1" oninput="document.documentElement.style.setProperty('--range', this.value);">
  <div class="slider-tooltip"></div>
</div>
              
            
!

CSS

              
                * {
  margin: 0;
  padding: 0;
  font-weight: normal;
}

:root {
  --input-width: 300px;
  --range: 80;
  --range-min: 20;
  --range-max: 100;
  --slider-thumb-size: 48px;
  --slider-track-height: 30px;
  --slider-progress-bg: linear-gradient(
    45deg,
    rgba(59, 173, 227, 1) 0%,
    rgba(87, 111, 230, 1) 25%,
    rgba(152, 68, 183, 1) 51%,
    rgba(255, 53, 127, 1) 100%
  );
}

body,
input,
textarea {
  font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", "Noto Sans",
    Helvetica, Arial, sans-serif, "Apple Color Emoji", "Segoe UI Emoji";
}

body {
  display: flex;
  flex-direction: column;
  align-items: center;
  padding-top: 50px;
}

h1 {
  margin-bottom: 16px;
  font-size: 26px;
}

.slider-box {
  margin-top: 20px;
  position: relative;
  z-index: 9;
  width: var(--input-width);
  min-height: 130px;
  /*   border: 1px solid blue; */

  container-type: inline-size;
  align-items: center;
  display: grid;
  /* 防止 Safari 中内部元素高度计算超出 */
  grid-template-rows: 1fr;
  grid-template-columns: 0fr 1fr;
  grid-template-areas: "left right";
}

.slider-input {
  background-color: transparent;
  justify-self: center;
  position: absolute;
  top: 0;
  height: 100%;
  width: calc(100% + var(--slider-thumb-size));
  cursor: grab;
}

/* 使用伪元素在 Safari 中宽度会计算不对,必须改成单独的元素 */
/* .slider-box:before {  */
.slider-progress {
  content: "";
  height: var(--slider-track-height);

  /* 计算进度条宽度 */
  /* 传统算法 */
  --p1: calc(
    (var(--range) - var(--range-min)) / 
    (var(--range-max) - var(--range-min))
  );
  --clamp-min: calc(var(--slider-thumb-size) / 2);
  --clamp-max: calc(100cqi - var(--slider-thumb-size) / 2);
  --w1: clamp(var(--clamp-min), calc(100cqi * var(--p1)), var(--clamp-max));

  /* 基于 cqi 直接算出宽度 */
  --w2: calc(
    100cqi * ( var(--range) - var(--range-min) )
    / ( var(--range-max) - var(--range-min) ) 
    + var(--slider-thumb-size) / 2
  );
  width: var(--w2);
  
  position: relative;
  z-index: 99;
  pointer-events: none;

  /* 模拟进度的背景 */
  background: var(--slider-progress-bg) no-repeat center;
  margin-left: calc(var(--slider-thumb-size) / -2);
  /* 进度条右侧圆角设为 0,防止拖动到最左时挤压导致左侧圆角溢出 */
  border-radius: 99em 0 0 99em;
  max-width: calc(100cqi + var(--slider-thumb-size));
}

.slider-tooltip {
  grid-area: 1 / 2;
  position: absolute;
  top: 50%;
  transform: translate(-50%, -50%);
  padding: 0.3em 0;
  border-radius: 999px;
  border: 2px solid rgba(59, 173, 227, 0.8);
  /* background-color: #673AB7; */

  box-sizing: border-box;
  height: var(--slider-thumb-size);
  width: var(--slider-thumb-size);
  max-width: 80px;

  transition: border 0.1s ease, background-color 0.1s ease;
  pointer-events: none;
}

input:focus + .slider-tooltip {
  /* background-color: rgba(103, 58, 183, 0.5); */
}

input:active + .slider-tooltip:before {
  animation: scale_in 0.1s ease-in both;
}

input:focus + .slider-tooltip:before {
  visibility: visible;
  opacity: 1;
  animation: scale_in 0.1s ease-in both;
}

.slider-tooltip:before {
  counter-reset: number var(--range);
  content: counter(number);

  /* 使用 attr() 可以显示小数 */
  /* content: attr(data-value); */
  min-width: 3em;
  /* 避免数字抖动 */
  width: max-content;
  text-align: center;
  color: #fff;
  font-size: 18px;
  transform-origin: left center;

  position: absolute;
  padding: 0.3em 0;
  border-radius: 99px;
  top: -10px;
  left: 50%;
  transform: translate(-50%, -100%);
  background-color: #673ab7;
  animation: scale_out 0.1s ease-out both;
}

input[type="range"] {
  appearance: none;
}

@supports selector(::-moz-range-thumb) {
  .slider-tooltip {
    z-index: 99;
  }
}

@supports selector(::-webkit-slider-thumb) {
  .slider-tooltip {
    transition: none;
    width: 2px;
    border-color: transparent;
  }
}

input[type="range"]::-moz-range-thumb {
  box-sizing: border-box;
  appearance: none;
  height: var(--slider-thumb-size);
  width: var(--slider-thumb-size);
  max-width: 80px;
  background: none;
  /* background-color: #673AB7; */
  border: 2px solid transparent;
  border-radius: 50%;
}

input[type="range"]::-webkit-slider-thumb {
  appearance: none;
  height: var(--slider-thumb-size);
  width: var(--slider-thumb-size);
  max-width: 80px;
  position: relative;
  z-index: 2048;
  top: 50%;
  transform: translateY(-50%);

  border: 2px solid rgba(59, 173, 227, 0.8);
  border-radius: 50%;
  background-color: rgba(103, 58, 183, 0.5);
}

input[type="range"]::-moz-range-track {
  appearance: none;
  height: var(--slider-track-height);
  border-radius: 999px;

  background-repeat: no-repeat;
  background-position: 0 50%;
  background: #e6e6e6;
  box-shadow: inset 0px 1px 3px rgba(0, 0, 0, 0.3);
}

input[type="range"]::-webkit-slider-runnable-track {
  appearance: none;
  height: var(--slider-track-height);
  border-radius: 999px;

  background-repeat: no-repeat;
  background-position: 0 50%;
  background: #e6e6e6;
  box-shadow: inset 0px 1px 3px rgba(0, 0, 0, 0.3);
}

@keyframes scale_in {
  0% {
    scale: 0;
    opacity: 0;
  }

  to {
    scale: 1;
    opacity: 1;
  }
}

@keyframes scale_out {
  0% {
    scale: 1;
    opacity: 1;
  }

  to {
    scale: 0;
    opacity: 0;
  }
}

#checkbox {
  margin-top: 12px;
}

:root:has(#checkbox:checked) :is(.slider-input) {
  width: 100%;
}

:root:has(#checkbox:checked) :is(.slider-progress) {
   margin-left: 0;
  width: calc(var(--w1));
}

              
            
!

JS

              
                // 404
              
            
!
999px

Console