<div class="hsl-picker">
<form>
<label for="h">
Hue:
<input type="range" value="180" min="0" max="360" step="0.1" name="h" id="h">
</label>
<label for="s">
Saturation:
<input type="range" value="50" min="0" max="100" step="0.1" name="s" id="s">
</label>
<label for="l">
Lightness:
<input type="range" value="50" min="0" max="100" step="0.1" name="l" id="l">
</label>
<label for="a">
Alpha:
<input type="range" value="100" min="0" max="100" step="0.1" name="a" id="a">
</label>
</form>
<div class="output">
<code class="output-text">
hsla(180, 50%, 50%, 100%)
</code>
</div>
</div>
.hsl-picker {
--h: 180;
--s: 50%;
--l: 50%;
--a: 100%;
--border-color: hsl(var(--h), 100%, 35%);
}
html, body {
margin: 0;
}
body {
font-family: -apple-system, BlinkMacSystemFont, avenir next, avenir, helvetica neue, helvetica, Ubuntu, roboto, noto, segoe ui, arial, sans-serif;
background: #eee;
}
* {
font-family: inherit;
}
.hsl-picker {
display: flex;
padding: 1em;
gap: 1em;
}
form {
flex-grow: 1;
padding: 1em;
}
.output {
flex-basis: min(20em, 40%);
display: flex;
align-items: flex-end;
position: relative;
background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='8' height='8' viewBox='0 0 8 8'%3E%3Cg fill='%23000000' fill-opacity='0.4'%3E%3Cpath fill-rule='evenodd' d='M0 0h4v4H0V0zm4 4h4v4H4V4z'/%3E%3C/g%3E%3C/svg%3E");
background-size: 20px 20px;
background-position: 0 0, 0 10px, 10px -10px, -10px 0px;
}
.output::before {
content: '';
top: 0;
position: absolute;
bottom: 0;
left: 0;
right: 0;
background-color: hsla(var(--h), var(--s), var(--l), var(--a));
}
.output-text {
font-family: monospace;
margin: 0.5em;
padding: 0.5em;
background: hsla(0, 0%, 95%, 95%);
position: relative;
flex-grow: 1;
text-align: center;
}
label {
display: flex;
flex-direction: column;
width: 100%;
}
label + label {
margin-top: 1em;
}
input[type="range"] {
margin-top: 1em;
width: 100%;
-webkit-appearance: none;
height: 1em;
box-shadow: 0 0 0 0.12em #fff;
border-radius: 1em;
}
input[type="range"]:focus {
outline: none;
box-shadow:
0 0 0 0.2em #fff,
0 0 0 0.4em hsl(var(--h), 50%, 50%);
}
#h {
--s: 100%;
--l: 50%;
/* credit to Jamie Kudla: https://codepen.io/JKudla/pen/GpYXxZ */
background: linear-gradient(
to right,
hsl(0, 100%, 50%) 0%,
hsl(30, 100%, 50%) 8.3%,
hsl(60, 100%, 50%) 16.6%,
hsl(90, 100%, 50%) 25%,
hsl(120, 100%, 50%) 33.3%,
hsl(150, 100%, 50%) 41.6%,
hsl(180, 100%, 50%) 50%,
hsl(210, 100%, 50%) 58.3%,
hsl(240, 100%, 50%) 66.6%,
hsl(270, 100%, 50%) 75%,
hsl(300, 100%, 50%) 83.3%,
hsl(330, 100%, 50%) 91.6%,
hsl(360, 100%, 50%) 100%
);
}
#s {
background: linear-gradient(
to right,
hsl(var(--h), 0%, var(--l)) 0%,
hsl(var(--h), 100%, var(--l)) 100%
);
}
#l {
background: linear-gradient(
to right,
hsl(var(--h), var(--s), 0%) 0%,
hsl(var(--h), var(--s), 50%) 50%,
hsl(var(--h), var(--s), 100%) 100%
);
}
#a {
background: linear-gradient(to right, hsla(var(--h), var(--s), var(--l), 0%) 00%, hsla(var(--h), var(--s), var(--l), 100%) 100%);
}
[type="range"]::-moz-range-thumb {
background-color: hsl(var(--h), var(--s), var(--l));
border: 0.1em solid hsl(var(--h), 100%, 35%);
box-shadow:
0 0 0 0.2em #fff,
0 0 0 0.4em hsl(var(--h), 100%, 35%);
border-radius: 50%;
height: 1.5em;
width: 1.5em;
}
[type="range"]::-webkit-slider-thumb {
-webkit-appearance: none;
background-color: hsl(var(--h), var(--s), var(--l));
box-shadow: 0 0 0 0.25em hsl(var(--h), 100%, 35%);
border: 0.25em solid #fff;
border-radius: 50%;
height: 1.5em;
width: 1.5em;
}
[type="range"]::-ms-thumb {
background-color: hsl(var(--h), var(--s), var(--l));
box-shadow: 0 0 0 0.25em hsl(var(--h), 100%, 35%);
border: 0.25em solid #fff;
border-radius: 50%;
height: 1.5em;
width: 1.5em;
}
initPicker(document.querySelector('.hsl-picker'));
function initPicker(picker) {
const outputText = picker.querySelector('.output-text');
picker.querySelectorAll('[type="range"]').forEach(input => {
input.addEventListener('input', ({target}) => {
let {name, value} = target;
if(target.name !== 'h') {
value = `${value}%`;
}
picker.style.setProperty(`--${name}`, value);
const styles = window.getComputedStyle(picker);
outputText.innerText = `
hsla(${
styles.getPropertyValue('--h')
}, ${
styles.getPropertyValue('--s')
}, ${
styles.getPropertyValue('--l')
}, ${
styles.getPropertyValue('--a')
})
`.trim();
});
});
}
This Pen doesn't use any external CSS resources.
This Pen doesn't use any external JavaScript resources.