Resizeable using input sliders

Range inputs are ideal for creating inputs that allow the user to set the width or height of elements on the screen. They can be very intuitive to use, but not quite so easy to program!

The following example illustrates a vertical slider as well as a horizontal slider.

Dragging the slider calls a Javascript function that updates the width or height of the div elements that it controls.

This Javascript also stores the selected value in localStorage. Next time the user visits this site the values in localStorage are retrieved and used to set the initial values used for these element widths.

Working demonstration using Range Inputs:

Drag the buttons on the green slider and release to observer the change is size of the div that it controls.

resizeable-slider.html

 

The HTML code:

The html code sets up three divs on the page, as in the previous example. The CSS controls the initial positions of these divs, but this is immediately changed by the onload call to the Javascript setcolumnwidth().

The significant aspects of this HTML code are highlighted in yellow in the code example below.

Code can be copied and pasted from this screen.

<!doctype html>
<html lang="en">
<head>
    <meta charset="utf-8">
    <meta name="viewport" content="width=device-width, initial-scale=1">
    <title>CSS Resizable Slider</title>
    <link rel="stylesheet" href="resizeable-slider.css">
</head>
<body onload="setcolumnwidth()">
    <div id="parent">
        <div id="topmenu">
            <h1>CSS Resizeable Slider</h1>
            <p>This has been tested in Firefox and Chromium. The vertical slider may not work in other browsers</p>
            <p>This is the top menu</p>
            <p>This is the top menu</p>
        </div>
        <div id="div1">
            <div class="content">
                <p>This is text in the left hand pane. Drag the right hand border of this pane.</p>
                <p>This is text in the left hand pane</p>
                <p>This is text in the left hand pane</p>
            </div>
        </div>
        <div id="div2">
            <div class="content">
                <p>This is text in the right hand pane</p>
                <p>This is text in the right hand pane</p>
                <p>This is text in the right hand pane</p>
                <p>This is text in the right hand pane</p>
                <p>This is text in the right hand pane</p>
                <p>This is text in the right hand pane</p>
            </div>
        </div>
    </div>
    <div class="scale" ><input type="range" min="0" max="100" step="1" value="60" id="slider2" onchange = "updatecolumnwidth(this.value)" ></div>
    <div class="vscale" ><input type="range" min="0" max="100" step="1" value="60" id="slider3" onchange = "updatetopmenuheight(this.value)" ></div>
    <script src="resizeable-slider.js" ></script>
</body>
</html>

The Javascript code:

onload starts by calling setcolumnwidth(). This checks localStorage to see if values have been stored for framewidth and topheight . If these are available these will be used, but if these are null, alternative values will be used: 40 and 30.

If a slider is moved then the onchange event is called. The horizontal slider, slider2 calls updatecolumnwidth(this.value)  , passing the value of the slider to that function. The function recieves this value as val  and first stores this in localStorage, line 2, , and then applies this to div1 ,line 3. The corresponding value needed to be applied to div2  is then calculated and applied on line 4. 

function updatecolumnwidth(val) {
    localStorage.setItem("framewidth", val);
    document.getElementById("div1").style.width = val + "%";
    document.getElementById("div2").style.width = 100 - val + "%";
}
 
function setcolumnwidth() {
    var val = localStorage.getItem("framewidth") || "40";
    var valtop = localStorage.getItem("topheight") || "30";
    document.getElementById("div1").style.width = val + "%";
    document.getElementById("div2").style.width = 100 - val + "%";
    document.getElementById("topmenu").style.height = valtop + "%";
}
 
function updatetopmenuheight(val) {
    localStorage.setItem("topheight", val);
    document.getElementById("topmenu").style.height = val + "%";
}

The CSS:

The range slider can be quite difficult to style with so many non-standard options. An online code generator can be very useful here. The vertical scale uses a range input inside the class vscale. This is rotated 90 degrees. As its height is the full height of the browser window, rotating it in place would place this in the middle of the screen. A margin of -50% of the screen moves this to the edge of the screen.

The CSS values for just input[type=range]: are applied to both the vertical and horizontal range inputs.

.scale { and .scale input[type=range] { apply only to the horizontal range input in this example.

.vscale { and .vscale input[type=range] { apply only to the vertical range input in this example.

#parent {
    position: absolute;
    height: 100vh;
    margin: 0;
    padding: 0;
    width: 98%;
}
 
#div1 {
    position: relative;
    display: block;
    float: left;
    width: 50%;
    background-color: #A2A;
    overflow: auto;
    
}
 
#div2 {
    display: block;
    background-color: #BBB;
    overflow: auto;
}
 
#topmenu {
    position: relative;
    width: 100%;
    height: calc(98vh /8);
    overflow: auto;
    
}
 
.content {
    margin: 10px;
    height: 100%;
    width: 100%;
    
}
 
body {
    overflow: hidden;
}
 
html {
    overflow: hidden;
}
 
.scale {
    position:absolute;
    height:30px;
    margin:0;
    padding:0;
    width:100%;
    left: 0;
    bottom: 0;
    z-index: 1000;
}
.vscale {
    position:absolute;
    height:100%;
    margin:0;
    padding:0;
    width:30px;
    left: 0;
    top: 0;
    z-index: 1000;
 
}
 
 
.scale input[type=range] {
  -webkit-appearance: none;
  width: 100%;
  margin: 8.9px 0;
}
.scale input[type=range]:focus {
  outline: none;
}
.scale input[type=range]::-webkit-slider-runnable-track {
  width: 100%;
  height: 4.2px;
  cursor: pointer;
  box-shadow: 1px 1px 1px #000000, 0px 0px 1px #0d0d0d;
  background: #4dcc72;
  border-radius: 0px;
  border: 0.8px solid #0d2025;
}
.scale input[type=range]::-webkit-slider-thumb {
  box-shadow: 2.2px 2.2px 6.7px #080000, 0px 0px 2.2px #220000;
  border: 2.3px solid #885d00;
  height: 22px;
  width: 19px;
  border-radius: 4px;
  background: #b1d245;
  cursor: pointer;
  -webkit-appearance: none;
  margin-top: -9.7px;
}
.scale input[type=range]:focus::-webkit-slider-runnable-track {
  background: #61d282;
}
.scale input[type=range]::-moz-range-track {
  width: 100%;
  height: 4.2px;
  cursor: pointer;
  box-shadow: 1px 1px 1px #000000, 0px 0px 1px #0d0d0d;
  background: #4dcc72;
  border-radius: 0px;
  border: 0.8px solid #0d2025;
}
.scale input[type=range]::-moz-range-thumb {
  box-shadow: 2.2px 2.2px 6.7px #080000, 0px 0px 2.2px #220000;
  border: 2.3px solid #885d00;
  height: 22px;
  width: 19px;
  border-radius: 4px;
  background: #b1d245;
  cursor: pointer;
}
.scale input[type=range]::-ms-track {
  width: 100%;
  height: 4.2px;
  cursor: pointer;
  background: transparent;
  border-color: transparent;
  color: transparent;
}
input[type=range]::-ms-fill-lower {
  background: #39c662;
  border: 0.8px solid #0d2025;
  border-radius: 0px;
  box-shadow: 1px 1px 1px #000000, 0px 0px 1px #0d0d0d;
}
input[type=range]::-ms-fill-upper {
  background: #4dcc72;
  border: 0.8px solid #0d2025;
  border-radius: 0px;
  box-shadow: 1px 1px 1px #000000, 0px 0px 1px #0d0d0d;
}
input[type=range]::-ms-thumb {
  box-shadow: 2.2px 2.2px 6.7px #080000, 0px 0px 2.2px #220000;
  border: 2.3px solid #885d00;
  height: 22px;
  width: 19px;
  border-radius: 4px;
  background: #b1d245;
  cursor: pointer;
  height: 4.2px;
}
input[type=range]:focus::-ms-fill-lower {
  background: #4dcc72;
}
input[type=range]:focus::-ms-fill-upper {
  background: #61d282;
}
 
.vscale input[type=range] {
transform: rotateZ(90deg);
  margin-top: 50vh;
  width: 100vh;
margin-left:-50vh;
    -webkit-transform: rotate(90deg);
 
 
 
}
.vscale input[type=range]::-moz-range-track {
  height: 10px;
  width: 100vh;
  cursor: pointer;
  box-shadow: 1px 1px 1px #000000, 0px 0px 1px #0d0d0d;
  background: #4dcc72;
  border-radius: 0px;
  border: 0.8px solid #0d2025;
}
.vscale input[type=range]::-moz-range-thumb {
  box-shadow: 2.2px 2.2px 6.7px #080000, 0px 0px 2.2px #220000;
  border: 2.3px solid #885d00;
  height: 22px;
  width: 19px;
  border-radius: 4px;
  background: #b1d245;
  cursor: pointer;
}
.vscale input[type=range]::-webkit-slider-runnable-track {
  width: 800px;
  height: 10px;
  cursor: pointer;
  box-shadow: 1px 1px 1px #000000, 0px 0px 1px #0d0d0d;
  background: #4dcc72;
  border-radius: 0px;
  border: 0.8px solid #0d2025;