<p class="browser-alert">
This page works best in browsers that support CSS Variables.
<a href="https://caniuse.com/#search=css%20variables">More info</a>
</p>
<div class="wrapper">
<div class="theme-editor-container">
<h1>Theme Editor</h1>
<section class="theme-editor">
<section class="predefined-themes">
<h2>Predefined Themes</h2>
<button data-theme="green" style="background-color: #2eec96">
green
</button>
<button data-theme="blue" style="background-color: #3f51b5">
blue
</button>
<button data-theme="yellow" style="background-color: #ffeb3b">
yellow
</button>
<button data-theme="black" style="background-color: #222">
black
</button>
<button data-theme="white" style="background-color: white">
white
</button>
</section>
<section class="colors">
<h2>Colors</h2>
<form>
<p class="color-picker">
<label for="background-color">Background Color</label>
<input type="color"
id="background-color"
value="#2eec96">
</p>
<p class="color-picker">
<label for="text-color">Text Color</label>
<input type="color" id="text-color" value="#000000">
</p>
<p class="color-picker">
<label for="label-color">Label Color</label>
<input type="color" id="label-color" value="#1a905d">
</p>
</form>
</section>
<section class="typography">
<h2>Typography</h2>
<form>
<p>
<label for="base-font-size">Base Font Size</label>
<input type="range"
id="base-font-size"
min="12"
max="16"
step="1"
value="14">
</p>
<p>
<label for="base-line-height">Base Line Height</label>
<input type="range"
id="base-line-height"
min="1.2"
max="2.0"
step="0.1"
value="1.6">
</p>
</form>
</section>
</section>
<section class="theme-preview">
<h1>A live theme editor with slick new CSS variables.</h1>
<h2>Lorem ipsum dolor sit amet, consectetur adipisicing elit. Ab
aliquam eos quas. Ab amet dicta earum enim, esse
excepturi.</h2>
<p>Lorem ipsum dolor sit amet, consectetur adipisicing elit. A
blanditiis commodi consequuntur delectus doloremque error esse
mollitia nemo neque nesciunt nihil odit, perferendis
praesentium, suscipit velit veniam voluptate. Autem, soluta!</p>
<p>Et odit, totam! Accusantium deserunt earum laudantium molestiae
praesentium quam reiciendis ut? Beatae harum numquam quisquam
quod recusandae rem soluta sunt veniam. Animi doloremque
exercitationem magnam recusandae repellendus similique,
voluptas!</p>
</section>
</div>
</div>
:root {
--background-color: #2eec96;
--text-color: #222;
--label-color: #1a905d;
--border-color: rgba(250, 250, 250, 0.5);
--base-font-size: 14px;
--base-line-height: 1.6;
}
.browser-alert {
margin: 0;
padding: 1rem;
background-color: white;
color: black;
}
.browser-alert a {
color: inherit;
}
@supports (--css: variables) {
.browser-alert {
display: none;
}
}
html,
body {
min-height: 100%;
}
body {
margin: 0;
padding: 0;
font-family: 'Roboto', sans-serif;
font-size: var(--base-font-size);
line-height: var(--base-line-height);
font-weight: 300;
color: var(--text-color);
background-color: var(--background-color);
transition: font-size 0.2s ease-in-out, line-height 0.2s ease-in-out, color 0.2s ease-in-out, background-color 0.2s ease-in-out;
}
h1,
h2,
h3,
h4,
h5,
h6 {
font-weight: inherit;
line-height: calc(var(--base-line-height) * 0.85);
transition: line-height 0.2s ease-in-out;
}
label {
font-size: 0.85rem;
font-weight: 500;
letter-spacing: 0.05em;
text-transform: uppercase;
color: var(--label-color);
}
.wrapper {
max-width: 60rem;
min-height: calc(100vh - 56px - 3rem);
margin: 0 auto;
padding: 1.5rem;
}
.theme-editor-container {
width: 100%;
}
.theme-editor-container > h1 {
margin-bottom: 2rem;
}
.theme-editor,
.theme-preview {
padding: 1rem 0;
border-top: 1px solid var(--border-color);
}
.theme-editor > section {
margin-bottom: 2.5rem;
}
button[data-theme] {
display: inline-block;
width: 2rem;
height: 2rem;
margin-right: 0.25rem;
border: 1px solid var(--text-color);
border-radius: 50%;
font-size: 0;
background: transparent;
outline: 0;
cursor: pointer;
}
.color-picker {
display: flex;
align-items: center;
}
.color-picker label {
margin-right: 0.5rem;
}
.typography label {
margin-right: 0.5rem;
}
input[type='color'] {
width: 2rem;
height: 2rem;
border: 0;
background: transparent;
outline: 0;
}
input[type=range] {
-webkit-appearance: none;
background: transparent;
outline: 0;
}
input[type=range]::-webkit-slider-thumb {
-webkit-appearance: none;
width: 18px;
height: 18px;
margin-top: -5px;
border-color: transparent;
border-radius: 50%;
background-color: var(--label-color);
cursor: pointer;
}
input[type=range]::-moz-range-thumb {
width: 18px;
height: 18px;
margin-top: -5px;
border-color: transparent;
border-radius: 50%;
background-color: var(--label-color);
cursor: pointer;
}
input[type=range]::-ms-thumb {
width: 18px;
height: 18px;
margin-top: -5px;
border-color: transparent;
border-radius: 50%;
background-color: var(--label-color);
cursor: pointer;
}
input[type=range]::-webkit-slider-runnable-track {
width: 100%;
height: 8px;
border-radius: 12px;
background-color: var(--border-color);
transition: background-color 0.1s ease-out;
cursor: pointer;
}
input[type=range]::-moz-range-track {
width: 100%;
height: 8px;
border-radius: 12px;
background-color: var(--border-color);
transition: background-color 0.1s ease-out;
cursor: pointer;
}
input[type=range]::-ms-track {
width: 100%;
border-width: 16px;
border-color: transparent;
border-radius: 12px;
color: transparent;
background-color: transparent;
transition: background-color 0.1s ease-out;
cursor: pointer;
}
input[type=range]::-ms-fill-lower {
background-color: var(--border-color);
}
input[type=range]::-ms-fill-upper {
background-color: var(--border-color);
}
.theme-preview > h1 {
font-size: 2em;
}
@media (min-width: 50rem) {
body {
display: flex;
flex-direction: column;
}
.wrapper {
display: flex;
flex: 1;
flex-direction: column;
align-items: center;
justify-content: center;
}
.theme-editor-container {
display: flex;
}
.theme-editor-container > * {
padding: 0 0.5rem;
}
.theme-editor-container > h1 {
flex: 1;
margin-top: 1rem;
}
.theme-editor,
.theme-preview {
padding: 0 2rem;
border: 0;
}
.theme-editor {
flex: 2;
}
.theme-preview {
flex: 3;
}
.color-picker,
.typography form p {
display: flex;
align-items: center;
justify-content: space-between;
}
}
const setValue = (property, value) => {
if (value) {
document.documentElement.style.setProperty(`--${property}`, value);
const input = document.querySelector(`#${property}`);
if (input) {
value = value.replace('px', '');
input.value = value;
}
}
};
const setValueFromLocalStorage = property => {
let value = localStorage.getItem(property);
setValue(property, value);
};
const setTheme = options => {
for (let option of Object.keys(options)) {
const property = option;
const value = options[option];
setValue(property, value);
localStorage.setItem(property, value);
}
}
document.addEventListener('DOMContentLoaded', () => {
setValueFromLocalStorage('background-color');
setValueFromLocalStorage('text-color');
setValueFromLocalStorage('label-color');
setValueFromLocalStorage('border-color');
setValueFromLocalStorage('base-font-size');
setValueFromLocalStorage('base-line-height');
});
const dataThemeButtons = document.querySelectorAll('[data-theme]');
for (let i = 0; i < dataThemeButtons.length; i++) {
dataThemeButtons[i].addEventListener('click', () => {
const theme = dataThemeButtons[i].dataset.theme;
switch (theme) {
case 'green':
setTheme({
'background-color': '#2eec96',
'text-color': '#222222',
'label-color': '#1a905d',
'border-color': 'rgba(250, 250, 250, 0.5)'
});
return;
case 'blue':
setTheme({
'background-color': '#3f51b5',
'text-color': '#ffffff',
'label-color': '#ff5252',
'border-color': 'rgba(250, 250, 250, 0.5)'
});
return;
case 'yellow':
setTheme({
'background-color': '#ffeb3b',
'text-color': '#222222',
'label-color': '#ff5252',
'border-color': 'rgba(250, 250, 250, 0.5)'
});
return;
case 'black':
setTheme({
'background-color': '#222222',
'text-color': '#ffffff',
'label-color': '#ff5252',
'border-color': 'rgba(250, 250, 250, 0.5)'
});
return;
case 'white':
setTheme({
'background-color': '#ffffff',
'text-color': '#222222',
'label-color': '#ff5252',
'border-color': '#dddddd'
});
return;
}
})
}
const handleInputChange = (property, pixels) => {
document.documentElement.style.setProperty(`--${property}`, `${event.target.value}${pixels ? 'px' : ''}`);
localStorage.setItem(property, `${event.target.value}${pixels ? 'px' : ''}`);
};
document.querySelector('#background-color').addEventListener('change', event => {
handleInputChange('background-color', false);
})
document.querySelector('#text-color').addEventListener('change', event => {
handleInputChange('text-color', false);
});
document.querySelector('#label-color').addEventListener('change', event => {
handleInputChange('label-color', false);
});
document.querySelector('#base-font-size').addEventListener('input', event => {
handleInputChange('base-font-size', true);
});
document.querySelector('#base-line-height').addEventListener('input', event => {
handleInputChange('base-line-height', false);
});
This Pen doesn't use any external CSS resources.
This Pen doesn't use any external JavaScript resources.