<h1 id="title">HSL PREVIEW</h1>
<div id="container">
<div class="range_slider">
<input id='range1' type="range" value="276" min="0" max="360" step="3">
<span id='val1' class="rval">276</span>
</div>
<div class="range_slider">
<input id='range2' type="range" value="100" min="0" max="100">
<span id='val2' class="rval">100</span>
</div>
<div class="range_slider">
<input id='range3' type="range" value="6" min="0" max="100">
<span id='val3' class="rval">6</span>
</div>
</div>
:root {
--title: hsla(210, 19%, 40%, 0.5);
--slider: hsl(210, 19%, 40%);
--track: hsl(241, 19%, 48%);
}
* {
text-align: center;
font-family: Arial;
box-sizing: border-box;
}
body {
margin: 50px calc(20% + 20px) 50px 20%;
}
#title {
font-size: 1.6rem;
margin: 80px 25px 20px 0;
color: var(--title);
filter:saturate(10);
}
.range_slider {
margin: 50px 0;
width: 100%;
}
input {
margin: 0;
height: 25px;
width: calc(100% - (100px));
background: transparent;
}
div .rval,
input,
input::range-track {
border-radius: 5px;
}
input::range-track {
background: var(--track);
border: solid 4px var(--track);
box-shadow: 2px 4px 8px 0 hsla(241, 19%, 32%, 0.6);
}
input::slider-thumb {
appearance: none;
appearance: none;
appearance: none;
}
input::range-thumb {
--size: 30px;
width: var(--size);
height: var(--size);
background: var(--slider);
border: 1px solid var(--slider);
cursor: pointer;
}
.rval {
width: 60px;
padding: 5px 10px;
margin: 20px 0 20px 20px;
position: relative;
display: inline-block;
color: white;
background: var(--slider);
box-shadow: 2px 4px 8px 0 hsla(241, 19%, 32%, 0.6);
}
.rval:after {
width: 0;
height: 0;
top: 8px;
left: -8px;
position: absolute;
border-top: 8px solid transparent;
border-right: 8px solid var(--slider);
border-bottom: 8px solid transparent;
content: '';
}
.pulse {
animation: pulse 200ms ease-in-out 2 alternate;
}
@keyframes pulse {
from {
transform: scale(1);
}
to {
transform: scale(1.2);
}
}
@media screen and (min-width: 800px) {
#title {
font-size: 2.3rem;
}
}
@media screen and (min-width: 950px) {
#title {
font-size: 2.75rem;
}
}
const body = document.body;
body.style.background = `hsl(276, 100%, 6%)`;
const getVals = () => ([range1, range2, range3]).map(item => item.value);
const updateValue = (values) => {
const [v1, v2, v3] = values;
return [val1.textContent, val2.textContent, val3.textContent] = [v1, v2, v3];
}
const updateColor = (values) => {
const [v1, v2, v3] = values;
const color = `hsl(${v1}, ${v2}%, ${v3}%)`;
return body.style.background = title.textContent = color;
}
const autoContrast = (value) => {
let [r, g, b] = value.match(/\d+/g);
[r, g, b] = [r * 0.2126, g * 0.7152, b * 0.0722];
title.style.color = (r + g + b) >= 128 ? "hsla(261,23%,38%,0.6)" : "hsla(225,100%,92%,0.6)";
}
container.addEventListener("input", (e) => {
if (e.target && e.target.nodeName == "INPUT") {
const values = getVals();
updateValue(values);
updateColor(values);
autoContrast(body.style.background);
}
});
const copyText = () => {
const el = document.createElement('textarea');
el.value = title.textContent;
el.setAttribute('readonly', "");
el.style.position = 'absolute';
el.style.left = '-9999px';
body.appendChild(el);
const selected = document.getSelection().rangeCount > 0 ? document.getSelection().getRangeAt(0) : false;
el.select();
document.execCommand('copy');
body.removeChild(el);
if (selected) {
document.getSelection().removeAllRanges();
document.getSelection().addRange(selected);
}
}
title.addEventListener("click", (e) => {
if (title.textContent !== "HSL PREVIEW") {
title.className = "pulse";
copyText();
title.addEventListener("animationend", (e) => {
title.className = "";
}, false);
}
}, false);
This Pen doesn't use any external CSS resources.