简体   繁体   中英

How to make the "slider thumb" on a range slider go outside of the track

I have a vertical range slider and I want the "thumb" (the thing you move on the slider) to be wider than the track itself (very similar to how the android sliders look).

I've tried a lot of stuff and this is the closest I managed to be

This is my code so far:

HTML

<div class="sliderContainer">
   <input type="range">
</div>

JS

$(window).on("load resize", function () {
   var sliderWidth = $('[type=range]').width();

   $('.custom-style-element-related-to-range').remove();

   $('<style class="custom-style-element-related-to-range">input[type="range"]::-webkit-slider-thumb { box-shadow: -' + sliderWidth + 'px 0 0 ' + sliderWidth + 'px;}<style/>').appendTo('head');
});

CSS

.sliderContainer {
    position: absolute;
    margin: 0 auto;
    left: -27px;
    top: 127px;
    width: 0px;
    height: 135px;
}

input[type='range'] {
    width: 120px;
}

@media screen and (-webkit-min-device-pixel-ratio:0) {
    input[type='range'] {
        overflow: hidden;
        -webkit-appearance: none;
        background-color: #D2CECC;
        transform: rotate(270deg);
    }
    input[type='range']::-webkit-slider-runnable-track {
        height: 3px;
        -webkit-appearance: none;
        color: #0098A6;
    }
    input[type='range']::-webkit-slider-thumb {
        width: 10px;
        -webkit-appearance: none;
        height: 10px;
        cursor: pointer;
        background: #434343;
        color: #0098A6;
        border: 10px #0098A6;
        border-radius: 50%;
        margin-top: -3px;
    }
}

input[type="range"]::-moz-range-progress {
    background-color: #0098A6;
}

input[type="range"]::-moz-range-track {
    background-color: #D2CECC;
}

input[type="range"]::-ms-fill-lower {
    background-color: #0098A6;
}

input[type="range"]::-ms-fill-upper {
    background-color: #D2CECC;
}

Any idea on how to progress would be great

EDIT:

This is what I'm trying to achieve:

客观的

I've tried some more stuff and managed to make it so the thumb is "outside" but now the track doesnt change color.

CSS

@media screen and (-webkit-min-device-pixel-ratio:0) {
    input[type='range'] {
        -webkit-appearance: none;
        background-color: #D2CECC;
        transform: rotate(270deg);
    }
    input[type='range']::-webkit-slider-runnable-track {
        height: 3px;
        -webkit-appearance: none;
        color: #0098A6;
    }
    input[type='range']::-webkit-slider-thumb {
        width: 10px;
        -webkit-appearance: none;
        height: 10px;
        cursor: pointer;
        background: #0098A6;
        color: transparent;
        border: 10px #0098A6;
        border-radius: 50%;
        margin-top: -3px;
    }
}

I have spent some time to solve this since it is tricky to find the best solution.

The overflow: hidden on input[type='range'] prevents that your range thumb is "outside" of the range slider.

You could use box-shadow: -80px 0 0 80px #0098A6; on input[type='range']::-webkit-slider-thumb to have a css tricky way to show the range background color, but this also again requires overflow: hidden on the range track and would again prevent showing your range thumb outside (I have commented this part out in my solution).

So I managed to solve this with a JS/JQuery solution. You would also need to specify min and max attributes on the HTML part in order to let JS read those values when dragging the range slider.

You can just watch the CodePen that I have created for this issue and copy the parts to your needs. It also demonstrates that it works:

https://codepen.io/alexiovay/pen/VwYMZpg

I sticked to your desired design outcome as much as I could.

We all know and love CSS only solutions. However, sometimes it just isn't the best solution! It is often less readable, includes a lot of workarounds and is limited to the boundaries of CSS.

I really like @AlexioVay 's approach and solution, but it has an issue where the colored part only updates, if you let go of the handle, due to CSS limitations, ( Edit: fixed now) and you will probably have a bad time customizing it to the deepest of your needs. Since you are using jQuery already, why not just use the jQuery UI?

I think this solution is much, much more readable and practical.

 $(function() { $("#slider").slider({ orientation: "vertical", range: "min", value: 35, min: 0, max: 100 }); });
 #slider { background: #e6e6e6; border: 0; width: 3px; } #slider * { outline: none; } #slider .ui-slider-range, #slider .ui-slider-handle { background: #0098A6; border: 0; } #slider .ui-slider-handle { border-radius: 100%; width: 11px; height: 11px; margin-left: 1px; }
 <script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script> <script type="text/javascript" src="//cdnjs.cloudflare.com/ajax/libs/jqueryui/1.11.4/jquery-ui.min.js"></script> <script type="text/javascript" src="//cdnjs.cloudflare.com/ajax/libs/jqueryui-touch-punch/0.2.3/jquery.ui.touch-punch.min.js"></script> <link href="https://code.jquery.com/ui/1.12.1/themes/base/jquery-ui.min.css" rel="stylesheet"/> <div id="slider"></div>

Easy to read documentation and easy to customize. Since it isn't just a default HTML slider, you can target each item individually for future event-listeners or custom CSS. This way it is not limited to the CSS limits.

So, yes, my solution isn't CSS, but in my opinion the better one and much more practical.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM