Skip to content

Instantly share code, notes, and snippets.

@webdesignberlin
Forked from adarshpastakia/theme-builder.html
Created June 25, 2024 20:06
Show Gist options
  • Save webdesignberlin/9e2468aebaf55d682ea037a200a40a5c to your computer and use it in GitHub Desktop.
Save webdesignberlin/9e2468aebaf55d682ea037a200a40a5c to your computer and use it in GitHub Desktop.
CSS Theming using `color-mix`
<html data-gray-scheme="gray" data-primary="blue" data-accent="pink">
<head>
<style type="text/css">
:root {
--black: #12181c;
--white: #ffffff;
--info: #06b6d4;
--danger: #ef4444;
--success: #27ae60;
--warning: #f39c12;
--blue: #28a7ff;
--green: #2aa285;
--red: #eb474a;
--orange: #fe4f11;
--purple: #706fd3;
--pink: #FC427B;
--brown: #b4883e;
--gray: #879797;
--grayblue: #89a7be;
--graygreen: #89a8a9;
--graybrown: #88857c;
--radius: 4px;
}
[data-gray-scheme="gray"] {
--grayscale: var(--gray);
}
[data-gray-scheme="grayblue"] {
--grayscale: var(--grayblue);
}
[data-gray-scheme="graygreen"] {
--grayscale: var(--graygreen);
}
[data-gray-scheme="graybrown"] {
--grayscale: var(--graybrown);
}
[data-primary="blue"] {
--primary: var(--blue);
}
[data-accent="pink"] {
--accent: var(--pink);
}
[data-scheme="light"] {
--bg-color: var(--white);
--fg-color: var(--black);
}
[data-scheme="dark"] {
--bg-color: var(--black);
--fg-color: var(--white);
}
[data-radius="more"] {
--radius: 8px;
}
[data-radius="round"] {
--radius: 999px;
}
[data-scheme] {
--bg-viewport: color-mix(in srgb, var(--grayscale) 24%, var(--bg-color));
--bg-base: color-mix(in srgb, var(--grayscale) 12%, var(--bg-color));
--bg-component: color-mix(in srgb, var(--grayscale) 5%, var(--bg-color));
--bg-input: var(--bg-color);
--placeholder: color-mix(in srgb, var(--grayscale) 65%, var(--bg-color));
--border: color-mix(in srgb, var(--grayscale) 35%, var(--bg-color));
--text-color: var(--fg-color);
--text-dimmed: color-mix(in srgb, var(--fg-color) 70%, var(--bg-color));
--text-muted: color-mix(in srgb, var(--fg-color) 50%, var(--bg-color));
--bg-primary: color-mix(in srgb, var(--primary) 60%, var(--bg-color));
--text-primary: color-mix(in srgb, var(--primary) 70%, var(--text-color));
--bg-accent: color-mix(in srgb, var(--accent) 60%, var(--bg-color));
--text-accent: color-mix(in srgb, var(--accent) 70%, var(--text-color));
--bg-info: color-mix(in srgb, var(--info) 70%, var(--bg-color));
--text-info: color-mix(in srgb, var(--info) 90%, var(--text-color));
--bg-danger: color-mix(in srgb, var(--danger) 70%, var(--bg-color));
--text-danger: color-mix(in srgb, var(--danger) 90%, var(--text-color));
--bg-success: color-mix(in srgb, var(--success) 70%, var(--bg-color));
--text-success: color-mix(in srgb, var(--success) 90%, var(--text-color));
--bg-warning: color-mix(in srgb, var(--warning) 70%, var(--bg-color));
--text-warning: color-mix(in srgb, var(--warning) 90%, var(--text-color));
--bg-blue: color-mix(in srgb, var(--blue) 60%, var(--bg-color));
--text-blue: color-mix(in srgb, var(--blue) 70%, var(--text-color));
--bg-green: color-mix(in srgb, var(--green) 60%, var(--bg-color));
--text-green: color-mix(in srgb, var(--green) 70%, var(--text-color));
--bg-red: color-mix(in srgb, var(--red) 60%, var(--bg-color));
--text-red: color-mix(in srgb, var(--red) 70%, var(--text-color));
--bg-orange: color-mix(in srgb, var(--orange) 60%, var(--bg-color));
--text-orange: color-mix(in srgb, var(--orange) 70%, var(--text-color));
--bg-purple: color-mix(in srgb, var(--purple) 60%, var(--bg-color));
--text-purple: color-mix(in srgb, var(--purple) 70%, var(--text-color));
--bg-pink: color-mix(in srgb, var(--pink) 60%, var(--bg-color));
--text-pink: color-mix(in srgb, var(--pink) 70%, var(--text-color));
--bg-brown: color-mix(in srgb, var(--brown) 60%, var(--bg-color));
--text-brown: color-mix(in srgb, var(--brown) 70%, var(--text-color));
background-color: var(--bg-color);
color: var(--fg-color);
}
</style>
<style type="text/css">
html,body{
margin:0;
min-height: 100vh;
width: 100vw;
font-family: "Avenir Next", "Avenir", Segoe UI, Roboto, Helvetica Neue,
Arial, Noto Sans, system-ui, -apple-system, BlinkMacSystemFont, sans-serif,
Apple Color Emoji, Segoe UI Emoji, Segoe UI Symbol, Noto Color Emoji;
}
.controls {
position: sticky;
top: 0;
padding: 0.5rem;
background-color: var(--bg-viewport);
}
.holder {
display: inline-block;
width: calc(50vw - 2px);
box-sizing: border-box;
margin-top: 4rem;
}
.viewport {
padding: 1rem;
color: var(--fg-color);
background-color: var(--bg-viewport);
}
.page {
padding: 1rem;
background-color: var(--bg-base);
border: 1px solid var(--border);
}
.component {
padding: 1rem;
background-color: var(--bg-component);
border: 1px solid var(--border);
}
.muted {
color: var(--text-muted);
}
.dimmed {
color: var(--text-dimmed);
}
.bg-primary {
background-color: var(--bg-primary);
}
.text-primary {
color: var(--text-primary);
}
.bg-accent {
background-color: var(--bg-accent);
}
.text-accent {
color: var(--text-accent);
}
.bg-info {
background-color: var(--bg-info);
}
.text-info {
color: var(--text-info);
}
.bg-danger {
background-color: var(--bg-danger);
}
.text-danger {
color: var(--text-danger);
}
.bg-success {
background-color: var(--bg-success);
}
.text-success {
color: var(--text-success);
}
.bg-warning {
background-color: var(--bg-warning);
}
.text-warning {
color: var(--text-warning);
}
.bg-blue {
background-color: var(--bg-blue);
}
.text-blue {
color: var(--text-blue);
}
.bg-green {
background-color: var(--bg-green);
}
.text-green {
color: var(--text-green);
}
.bg-red {
background-color: var(--bg-red);
}
.text-red {
color: var(--text-red);
}
.bg-orange {
background-color: var(--bg-orange);
}
.text-orange {
color: var(--text-orange);
}
.bg-purple {
background-color: var(--bg-purple);
}
.text-purple {
color: var(--text-purple);
}
.bg-pink {
background-color: var(--bg-pink);
}
.text-pink {
color: var(--text-pink);
}
.bg-brown {
background-color: var(--bg-brown);
}
.text-brown {
color: var(--text-brown);
}
input {
appearance: none;
outline: none;
border-radius: var(--radius);
border: 1px solid var(--border);
color: var(--text-color);
background-color: var(--bg-input);
padding: 4px 8px;
}
input::placeholder {
color: var(--placeholder);
}
input:focus-within {
box-shadow: 0 -2px 0 0 var(--primary) inset;
}
input[data-invalid="true"]:focus-within {
box-shadow: 0 -2px 0 0 var(--danger) inset;
}
button {
padding: 4px 8px;
border-radius: var(--radius);
color: var(--text-color);
background-color: color-mix(in srgb, var(--grayscale) 10%, var(--bg-color));
border: 1px solid color-mix(in srgb, var(--primary) 90%, var(--black));
}
button[type="submit"] {
background-color: color-mix(in srgb, var(--primary) 80%, var(--bg-color));
}
button:hover {
background-color: color-mix(in srgb, var(--primary) 70%, var(--white));
}
button:active {
background-color: color-mix(in srgb, var(--primary) 70%, var(--black));
}
label {
display: inline-block;
margin: 4px;
padding: 4px 8px;
min-width: 32px;
}
button[data-gray] {
box-shadow: 0 0 2px 1px var(--gray);
border-radius: 99px;
border:0;
width: 2rem;
height:2rem;
}
button[data-gray="gray"] {
background-color: var(--gray);
}
button[data-gray="grayblue"] {
background-color: var(--grayblue);
}
button[data-gray="graygreen"] {
background-color: var(--graygreen);
}
button[data-gray="graybrown"] {
background-color: var(--graybrown);
}
</style>
</head>
<body>
<div class="controls">
<label>Grayscale</label>
<button data-gray="gray" onclick="document.documentElement.dataset.grayScheme='gray'"></button>
<button data-gray="grayblue" onclick="document.documentElement.dataset.grayScheme='grayblue'"></button>
<button data-gray="graygreen" onclick="document.documentElement.dataset.grayScheme='graygreen'"></button>
<button data-gray="graybrown" onclick="document.documentElement.dataset.grayScheme='graybrown'"></button>
<label>Rounding</label>
<button data-gray style="background: none; border-radius: 4px; border:2px solid var(--border)" onclick="document.documentElement.dataset.radius='none'"></button>
<button data-gray style="background: none; border-radius: 8px; border:2px solid var(--border)" onclick="document.documentElement.dataset.radius='more'"></button>
<button data-gray style="background: none; border-radius: 999px; border:2px solid var(--border)" onclick="document.documentElement.dataset.radius='round'"></button>
</div>
<template id="template">
<div class="viewport">
<h2>Viewport</h2>
<div class="page">
<h3>Page</h3>
<div class="component">
<h4>Component</h4>
<h5 class="dimmed">Dimmed text</h5><h5 class="muted">Muted text</h5>
<input size="30" value="Input text"/>
<input size="30" data-invalid="true" placeholder="Input placeholder" />
<button>Simple button</button>
<button type="submit">Submit button</button>
<br/><br/>
<label class="bg-info">info</label><label class="text-info">info</label>
<label class="bg-danger">danger</label><label class="text-danger">danger</label>
<label class="bg-success">success</label><label class="text-success">success</label>
<label class="bg-warning">warning</label><label class="text-warning">warning</label>
<br/><br/>
<label class="bg-blue">blue</label><label class="text-blue">blue</label>
<label class="bg-red">red</label><label class="text-red">red</label>
<label class="bg-green">green</label><label class="text-green">green</label>
<label class="bg-orange">orange</label><label class="text-orange">orange</label>
<label class="bg-purple">purple</label><label class="text-purple">purple</label>
<label class="bg-pink">pink</label><label class="text-pink">pink</label>
<label class="bg-brown">brown</label><label class="text-brown">brown</label>
</div>
</div>
</div>
</template>
<div data-scheme="light" class="holder"></div>
<div data-scheme="dark" class="holder"></div>
<script>
const template = document.getElementById("template");
document.querySelector('[data-scheme="light"]').appendChild(template.content.cloneNode(true));
document.querySelector('[data-scheme="dark"]').appendChild(template.content.cloneNode(true));
</script>
</body>
</html>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment