如何制作移动响应式垂直范围滑块

Posted

技术标签:

【中文标题】如何制作移动响应式垂直范围滑块【英文标题】:How to make mobile responsive vertical range slider 【发布时间】:2020-01-25 08:57:45 【问题描述】:

我已将范围滑块位置设置为垂直。但它没有响应。我签入了 chrome 默认移动设备。调整范围滑块时,它将滚动页面

我在这里添加了我的代码。

.slido   
 -webkit-appearance: none;
  width: 100%;
  height: 15px;
  border-radius: 5px;
  background: #d3d3d3;
  outline: none;
  opacity: 0.7;
  -webkit-transition: .2s;
  transition: opacity .2s;
  -webkit-transform: rotate(90deg);


.slido::-webkit-slider-thumb 
   -webkit-appearance: none;
  appearance: none;
  width: 25px;
  height: 25px;
  border-radius: 50%;
  background: #4CAF50;
  cursor: pointer;
<input type="range" class="slido" min="1" max="100" step="1">

【问题讨论】:

【参考方案1】:

在元素上仅使用transform 根本不会影响其父元素或任何其他元素的大小或位置。绝对没有办法改变转换如何工作的事实。所以在父级添加div(可以处理旋转溢出)是一种解决方案。

代码更新:

.slido 
  -webkit-appearance: none;
  width: 100vh;
  height: 15px;
  border-radius: 5px;
  background: #d3d3d3;
  outline: none;
  opacity: 0.7;
  -webkit-transition: .2s;
  transition: opacity .2s;
  transform: rotate(90deg);


.slido::-webkit-slider-thumb 
  -webkit-appearance: none;
  appearance: none;
  width: 25px;
  height: 25px;
  border-radius: 50%;
  background: #4CAF50;
  cursor: pointer;


.rotation-wrapper-outer 
  display: table;


.rotation-wrapper-inner 
  padding: 50% 0;
  height: 0;


.element-to-rotate 
  display: block;
  transform-origin: top left;
  /* Note: for a CLOCKWISE rotation, use the commented-out
         transform instead of this one. */
  transform: rotate(-90deg) translate(-100%);
  /* transform: rotate(90deg) translate(0, -100%); */
  margin-top: -50%;
  /* Not vital, but possibly a good idea if the element you're rotating contains
         text and you want a single long vertical line of text and the pre-rotation
         width of your element is small enough that the text wraps: */
  white-space: nowrap;
<div id="container">
  <div class="rotation-wrapper-outer">
    <div class="rotation-wrapper-inner">
      <input type="range" class="slido" min="1" max="100" step="1">
    </div>
  </div>
</div>

【讨论】:

宽度width: 100%;? % 什么?你为什么不使用vh 单位呢? 80vh 时的宽度,始终与设备视口高度相关。 编辑后 - 您忘记了元素已旋转。还有PS为什么用display: table; 更新了请查收。 用于响应式的东西。由于父 div 也可用,因此对高度没有影响。根据不同的设备进行调整,他可以使用媒体查询。【参考方案2】:

您已将水平滑块转换为垂直滑块,这将不起作用,因此您只能使用垂直滑块检查 sn-p。

let app = (() => 

  function updateSlider(element) 
    if (element) 
      let parent = element.parentElement,
        lastValue = parent.getAttribute('data-slider-value');

      if (lastValue === element.value) 
        return; // No value change, no need to update then
      

      parent.setAttribute('data-slider-value', element.value);
      let $thumb = parent.querySelector('.range-slider__thumb'),
        $bar = parent.querySelector('.range-slider__bar'),
        pct = element.value * ((parent.clientHeight - $thumb.clientHeight) / parent.clientHeight);

      $thumb.style.bottom = `$pct%`;
      $bar.style.height = `calc($pct% + $$thumb.clientHeight/2px)`;
      $thumb.textContent = `$element.value%`;
    
  
  return 
    updateSlider: updateSlider
  ;

)();

(function initAndSetupTheSliders() 
  const inputs = [].slice.call(document.querySelectorAll('.range-slider input'));
  inputs.forEach(input => input.setAttribute('value', '50'));
  inputs.forEach(input => app.updateSlider(input));
  // Cross-browser support where value changes instantly as you drag the handle, therefore two event types.
  inputs.forEach(input => input.addEventListener('input', element => app.updateSlider(input)));
  inputs.forEach(input => input.addEventListener('change', element => app.updateSlider(input)));
)();
*,
*:before,
*:after 
  box-sizing: border-box;


html,
body 
  height: 100%;


body 
  margin: 0;
  background: #3D3D4A;
  color: white;
  font-family: sans-serif;


.info 
  position: absolute;
  top: 0;
  left: 0;
  padding: 10px;
  opacity: 0.5;


.container 
  position: relative;
  display: inline-block;
  padding-top: 40px;


.range-slider 
  display: inline-block;
  width: 40px;
  position: relative;
  text-align: center;
  max-height: 100%;


.range-slider:before 
  position: absolute;
  top: -2em;
  left: 0.5em;
  content: attr(data-slider-value) '%';
  color: white;
  font-size: 90%;


.range-slider__thumb 
  position: absolute;
  left: 5px;
  width: 30px;
  height: 30px;
  line-height: 30px;
  background: white;
  color: #777;
  font-size: 50%;
  box-shadow: 0 0 0 4px #3D3D4A;
  border-radius: 50%;
  pointer-events: none;


.range-slider__bar 
  left: 16px;
  bottom: 0;
  position: absolute;
  background: linear-gradient(dodgerblue, blue);
  pointer-events: none;
  width: 8px;
  border-radius: 10px;


.range-slider input[type=range][orient=vertical] 
  position: relative;
  margin: 0;
  height: calc(100vh - 50px);
  width: 100%;
  display: inline-block;
  position: relative;
  writing-mode: bt-lr;
  -webkit-appearance: slider-vertical;


.range-slider input[type=range][orient=vertical]::-webkit-slider-runnable-track,
.range-slider input[type=range][orient=vertical]::-webkit-slider-thumb 
  -webkit-appearance: none;


.range-slider input[type=range][orient=vertical]::-webkit-slider-runnable-track 
  border: none;
  background: #343440;
  width: 8px;
  border-color: #343440;
  border-radius: 10px;
  box-shadow: 0 0 0 2px #3D3D4A;


.range-slider input[type=range][orient=vertical]::-moz-range-track 
  border: none;
  background: #343440;
  width: 8px;
  border-color: #343440;
  border-radius: 10px;
  box-shadow: 0 0 0 2px #3D3D4A;


.range-slider input[type=range][orient=vertical]::-ms-track 
  border: none;
  background: #343440;
  width: 8px;
  border-color: #343440;
  border-radius: 10px;
  box-shadow: 0 0 0 2px #3D3D4A;
  color: transparent;
  height: 100%;


.range-slider input[type=range][orient=vertical]::-ms-fill-lower,
.range-slider input[type=range][orient=vertical]::-ms-fill-upper,
.range-slider input[type=range][orient=vertical]::-ms-tooltip 
  display: none;


.range-slider input[type=range][orient=vertical]::-webkit-slider-thumb 
  width: 30px;
  height: 30px;
  opacity: 0;


.range-slider input[type=range][orient=vertical]::-moz-range-thumb 
  width: 30px;
  height: 30px;
  opacity: 0;


.range-slider input[type=range][orient=vertical]::-ms-thumb 
  width: 30px;
  height: 30px;
  opacity: 0;
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div class="container">

  <div class="range-slider">
    <input type="range" orient="vertical" min="0" max="100" />
    <div class="range-slider__bar"></div>
    <div class="range-slider__thumb"></div>
  </div>

</div>

【讨论】:

@RokoC.Buljan 这不是复制粘贴检查垂直滑块,它基于屏幕分辨率。根据请求,它的代码笔之一的增强版本。 所以你增强了别人的代码。增强了什么?介意解释一下增强功能吗?有哪些变化?现在有什么好?该代码与 OP 的代码有何关系? PS:根据要求?通过谁?密码笔?什么? @RokoC.Buljan 与高度相关的增强 == height: calc(100vh - 50px); === 根据屏幕分辨率,它会更好地调整高度。并且作为请求“青少年吸血鬼”而无需滚动页面,您将能够看到整个范围滑块。 我认为我们可以在不添加该库的情况下解决此问题。!请检查我的答案。

以上是关于如何制作移动响应式垂直范围滑块的主要内容,如果未能解决你的问题,请参考以下文章

如何垂直居中响应式剪切图像?

隐藏溢出的响应式垂直中心

如何使用 vuetify 制作移动响应式导航栏

垂直对齐内容与浮动元素 + 响应式布局

如何设置包装 div 的高度以防止响应式滑块/自动收录器后内容跳转?

powerbi切片器细分变大