color-elements
Version:
A set of web components for working with color. A Color.js project.
174 lines (151 loc) • 5.33 kB
CSS
:host {
display: flex;
position: relative;
}
.color-slider,
.slider-tooltip {
--transparency-cell-size: 1.5em;
--_transparency-cell-size: var(--transparency-cell-size, .5em);
--_transparency-background: var(--transparency-background, transparent);
--_transparency-darkness: var(--transparency-darkness, 5%);
--_transparency-grid: var(--transparency-grid,
repeating-conic-gradient(transparent 0 25%, rgb(0 0 0 / var(--_transparency-darkness)) 0 50%)
0 0 / calc(2 * var(--_transparency-cell-size)) calc(2 * var(--_transparency-cell-size))
content-box border-box var(--_transparency-background)
);
--_slider-color-stops: var(--slider-color-stops, transparent 0% 100%);
--_slider-gradient: var(--slider-gradient, linear-gradient(to right var(--in-space, ), var(--_slider-color-stops)));
--_slider-height: var(--slider-height, 2.2em);
--_slider-thumb-width: var(--slider-thumb-width, 1em);
--_slider-thumb-height-offset: var(--slider-thumb-height-offset, 2px);
--_slider-thumb-height: var(--slider-thumb-height, calc(var(--_slider-height) + var(--_slider-thumb-height-offset)));
--_slider-thumb-radius: var(--slider-thumb-radius, .16em);
--_slider-thumb-background: var(--slider-thumb-background, var(--color, transparent));
--_slider-thumb-border: var(--slider-thumb-border, 1px solid oklab(.2 0 0));
--_slider-thumb-border-active: var(--slider-thumb-border-active, 2px solid oklab(.4 0 0));
--_slider-thumb-scale-active: var(--slider-thumb-scale-active, 1.1);
--_tooltip-background: var(--tooltip-background, hsl(0 0 0 / 80%));
--_tooltip-border-radius: var(--tooltip-border-radius, .3em);
--_tooltip-pointer-height: var(--tooltip-pointer-height, .3em);
--_tooltip-pointer-angle: var(--tooltip-pointer-angle, 90deg);
}
.color-slider {
@supports (background: linear-gradient(in oklab, red, tan)) {
--in-space: in var(--color-space, oklab) var(--hue-interpolation, );
}
display: block;
margin: 0;
width: 100%;
-moz-appearance: none;
-webkit-appearance: none;
background: var(--_slider-gradient), var(--_transparency-grid);
background-origin: border-box;
background-clip: border-box;
height: var(--_slider-height);
border-radius: .3em;
border: 1px solid rgb(0 0 0 / 8%);
&::-webkit-slider-thumb {
-webkit-appearance: none;
box-sizing: content-box;
width: var(--_slider-thumb-width);
height: var(--_slider-thumb-height);
border-radius: var(--_slider-thumb-radius);
border: var(--_slider-thumb-border);
box-shadow: 0 0 0 1px white;
background: var(--color, transparent);
transition: 200ms, 0s background;
}
&::-moz-range-thumb {
box-sizing: content-box;
width: var(--_slider-thumb-width);
height: var(--_slider-thumb-height);
border-radius: var(--_slider-thumb-radius);
border: var(--_slider-thumb-border);
box-shadow: 0 0 0 1px white;
background: var(--color, transparent);
transition: 200ms, 0s background;
}
&::-moz-range-thumb:active {
border: var(--_slider-thumb-border-active);
scale: var(--_slider-thumb-scale-active);
}
&::-moz-range-track {
background: none;
}
}
/* For some reason, the &::-webkit-slider-thumb:active rule (previously used inside the above rule) doesn't work 🤷♂️ */
/* DO NOT MOVE IT BACK! :) */
.color-slider::-webkit-slider-thumb:active {
border: var(--_slider-thumb-border-active);
scale: var(--_slider-thumb-scale-active);
}
.slider-tooltip {
position: absolute;
left: clamp(-20%,
100% * var(--progress)
- (var(--progress) - 0.5) * var(--_slider-thumb-width) / 2 /* center on slider thumb */
, 100%);
bottom: calc(100% + 3px);
translate: -50%;
transform-origin: bottom;
display: flex;
padding-block: .3em;
padding-inline: .4em;
border: var(--_tooltip-pointer-height) solid transparent;
border-radius: calc(var(--_tooltip-border-radius) + var(--_tooltip-pointer-height));
text-align: center;
color: white;
background:
conic-gradient(from calc(-1 * var(--_tooltip-pointer-angle) / 2) at bottom, var(--_tooltip-background) var(--_tooltip-pointer-angle), transparent 0) border-box bottom / 100% var(--_tooltip-pointer-height) no-repeat,
var(--_tooltip-background) padding-box;
color-scheme: dark;
transition:
visibility 0s 200ms,
opacity 200ms,
scale 200ms,
width 100ms,
left 200ms cubic-bezier(.17,.67,.49,1.48);
&::after {
content: var(--tooltip-suffix);
}
input {
all: unset;
&:where([type=number]) {
--content-width: calc(var(--value-length) * 1ch);
width: calc(var(--content-width, 2ch) + 1.2em);
min-width: calc(2ch + 1.2em);
box-sizing: content-box;
&::-webkit-textfield-decoration-container {
gap: .2em;
}
@container style(--tooltip-suffix) {
&::-webkit-textfield-decoration-container {
flex-flow: row-reverse;
}
}
/* Don’t auto hide the spin buttons */
&::-webkit-inner-spin-button {
opacity: 1;
}
}
@supports (field-sizing: content) {
field-sizing: content;
width: auto;
}
/* Prevent input from moving all over the place as we type */
&:focus {
transition-delay: .5s;
}
}
&:not(:is(:focus-within, :hover) > *, .color-slider:is(:focus, :hover) + *, :focus, :hover) {
visibility: hidden;
opacity: 0;
scale: .5;
}
}
:host(:not([tooltip])) .slider-tooltip {
display: none;
}
:host([tooltip="progress"]) .slider-tooltip {
--tooltip-suffix: "%";
}