sveltesveltekit

Preventing Persistent CSS Styles Across Pages in SvelteKit


I'm using SvelteKit and have encountered an issue where CSS styles persist across page changes. I'm importing a CSS file in a Svelte component like this:

<script>
    import "$lib/styles/sample.css";
</script>

The problem occurs when navigating between pages: the styles from sample.css remain applied even after moving to a page where sample.css is not imported. However, if I reload a page where sample.css was not imported, the styles from sample.css disappear, as expected.

This behavior suggests that once a CSS file is loaded, its styles persist across page changes within the SvelteKit app, affecting pages that haven't explicitly imported the CSS file.

I'm looking for a solution to either:

Automatically remove the CSS styles applied from sample.css when navigating away from a page that imported it. Ensure that the CSS styles from sample.css do not affect pages that have not imported it. Any advice or solutions to prevent CSS styles from persisting across pages in a SvelteKit application would be greatly appreciated.


Solution

  • According to the comment that Rich Harris left on this issue, the problem is caused by how .css imports work and there’s no solution for it. But here are two different things I’ve done as workarounds:

    First approach: data-sveltekit-reload

    I’m not really happy with this one, but it is something that could work fine depending on your particular case.

    You can add data-sveltekit-reload to the link of the page which you need the styles to be cleared out, like this:

    <a href="/path-to-page" data-sveltekit-reload>
       Link text
    </a>
    

    Keep in mind that this will allow the browser to handle the link, causing a full-page navigation after it is clicked.

    Official docs: https://svelte.dev/docs/kit/link-options#data-sveltekit-reload

    Second approach: scoped styles

    Include this in the main element of your layout:

    <div data-page-pathname={$page.url.pathname.replace('/', '')}>
        ...
    </div>
    

    Now you can target the elements inside of each individual page with CSS without impacting the others:

    [data-page-pathname="path-to-page"] .element {
        ...
    }
    

    To make it easier, you could add a class instead of a data attribute, but the one in the example is the approach I prefer ;)