DEV Community

Discussion on: Theming in Svelte with CSS Variables

Collapse
 
isnit0 profile image
Joe Reeve • Edited

For anyone that's super lazy and just wants to get CSS variables working quickly like me:

<script>
    export let themeSettings = {
        font: {
            family: 'Merriweather, serif'
        },
        main: {
            background: 'white'
        },
        colors: {
            primary: { background: '#1b4738', color: 'white' }
        }
    };

    function encodeB64(str){
        if(process.browser) { // For Sapper
            return btoa(str);
        } else {
            const buff = Buffer.from(str, 'utf-8');
            return buff.toString('base64');
        }
    }

    function makeCSSVars(settings, prefix = '-') {
        return Object.entries(settings)
            .flatMap(([key, value]) => {
                const path = prefix + '-' + key;
                if (typeof value === 'object') return makeCSSVars(value, path);
                else return `${path}:${value};`;
            })
            .join('\n');
    }

    $: themeCSS = `:root {${makeCSSVars(themeSettings)}}`;

</script>

<link rel="stylesheet" href="data:text/css;base64,{encodeB64(themeCSS)}" />

<style>
main {
  background: var(--colors-primary-background);
}
</style>
Enter fullscreen mode Exit fullscreen mode
Collapse
 
josef profile image
Josef Aidt

Hey I'm just seeing this! This looks like an excellent approach and I hadn't thought about base64 encoding! Would love to hear your thoughts over at svelte-themer 🙂

Collapse
 
ambrt profile image
Rik

Some time ago i was looking for a way to switch themes in SvelteKit and ended up in having separate CSS files in public dir and just linking them.
It sucked b/c it needed full webpage reload to get new css to be applied.

So this solution with base64'ing content might do that automatically.
(I think getting css file as text and sending whole text as base64 might work).