<main v-scope>
<h1>Color Palette Builder</h1>
<ul class="colors">
<li v-if="colors.length === 0" style="grid-column:1/-1;">Add a color to get started</li>
<li v-for="color,i in colors">
<article class="color" :style="{'--color':color}" :class="{dark:isDark(color)}">
<p>{{color}}</p>
<button class="remove-color-btn" :class="{dark:isDark(color)}" @click="removeColor(i)">x</button>
<button class="copy-color-btn" :class="{dark:isDark(color)}" @click="copyString(color)">copy</button>
</article>
</li>
<li class="color-add">
<button @click="addColor">Add Color</button>
</li>
</ul>
<pre>{{cssString()}}</pre>
<button @click="copyString(cssString())">Copy CSS</button>
</main>
* {
box-sizing:border-box;
}
:root {
--bg-color:#fff;
}
body {
background-color:var(--bg-color);
margin:0;
display:grid;
place-items:center;
min-height:100vh;
font-family:sans-serif;
}
ul {
list-style:none;
padding:0;
width:100%;
}
main {
width:100%;
padding:20px;
display:grid;
place-items:center;
}
.colors {
background-color:#dfdfdf;
display:grid;
gap:1rem;
grid-template-columns: repeat( auto-fill, minmax(120px, 1fr) );
place-items:center;
padding:2rem;
.color-add {
grid-column: 1 / -1;
}
}
.color {
--color:#fff;
border:2px solid #222;
background-color:var(--color);
width:120px;
height:120px;
padding:10px;
border-radius:10px;
display:grid;
grid-template-columns:1fr 1fr;
gap: .5rem;
p {
grid-column: 1 / -1;
text-align:center;
font-weight:bold;
}
&.dark {
p {
color:White;
}
}
}
button {
border:none;
padding:4px 10px;
color:#fff;
background-color:#222;
border-radius:4px;
cursor:pointer;
&.dark {
background-color:#dfdfdf;
color:#222;
}
}
View Compiled
if(!window.EyeDropper) {
document.querySelector('main').innerHTML = "Oops, not supported, try Chrome Canary (95)";
}
import { createApp } from 'https://unpkg.com/petite-vue?module';
createApp({
colors:[],
async addColor() {
let eyeDropper = new EyeDropper();
const {sRGBHex} = await eyeDropper.open();
this.colors.push( sRGBHex );
},
isDark( color ) {
const c = color.substring(1);
const rgb = parseInt(c, 16);
const [r,g,b] = [(rgb >> 16) & 0xff, (rgb >> 8) & 0xff, (rgb >> 0) & 0xff];
const luma = 0.2126 * r + 0.7152 * g + 0.0722 * b;
if (luma < 50) {
return true;
}
return false;
},
copyString(str) {
const el = document.createElement('textarea');
el.value = str;
document.body.appendChild(el);
el.select();
document.execCommand('copy');
document.body.removeChild(el);
},
removeColor(i) {
this.colors.splice(i, 1);
},
cssString() {
return ":root {\n" + this.colors.map( (c,i) => {
return ` --c-color${i+1}: ${c};`
}).join('\n') + "\n}";
}
}).mount();
This Pen doesn't use any external CSS resources.
This Pen doesn't use any external JavaScript resources.