<!doctype html>
<style>
.reference { width: 50px; height: 50px; position: relative; display: inline-block; }
.reference > div {
position: absolute;
width: 100%;
height: 100%;
}
</style>
<body>
<script>
function createReference(colors) {
const div = document.createElement("div");
div.className = "reference";
const layers = colors.map(color => {
const layer = document.createElement("div");
layer.style.backgroundColor = color;
return layer;
}).toReversed();
div.append(...layers);
return div;
}
const opaqueColors = [
"red",
"blue",
"green",
"purple",
"orange",
"color(display-p3 1 0.5 0)",
"currentcolor",
"canvas",
"color-mix(in lab, red, blue)",
];
const semiTransparentColors = [
"rgb(from yellow r g b / 0.5)",
"rgba(0, 255, 128, 0.6)",
"color-mix(in lab, purple, rgba(0,0,0,0.5))",
"hsla(0, 100%, 20%, 0.4)",
];
// Test layering with opaque colors on top (top color wins)
for (const opaqueColor of opaqueColors) {
document.body.append(createReference([opaqueColor, ...semiTransparentColors]));
}
// Test layering multiple semi-transparent colors
for (let i = 0; i < semiTransparentColors.length; i++) {
let sliceUntilEndMinusI = semiTransparentColors.slice(0, semiTransparentColors.length - i);
let sliceUntilI = semiTransparentColors.slice(0, i);
let sliceFromIPlusOne = semiTransparentColors.slice(i + 1, semiTransparentColors.length);
document.body.append(createReference(sliceUntilEndMinusI));
// Interleave one opaque color.
for (const opaqueColor of opaqueColors) {
document.body.append(createReference([...sliceUntilEndMinusI, opaqueColor]));
if (sliceFromIPlusOne.length)
document.body.append(createReference([...sliceUntilI, opaqueColor, ...sliceFromIPlusOne]));
}
if (sliceFromIPlusOne.length)
document.body.append(createReference([...sliceUntilI, ...sliceFromIPlusOne]));
}
</script>
</body>