<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);
});

External CSS

This Pen doesn't use any external CSS resources.

External JavaScript

This Pen doesn't use any external JavaScript resources.