Skip to content

Svelte does not handle external CSS imports correctly when compiling components as custom elements (Web Components) #16130

@GCastilho

Description

@GCastilho

Describe the bug

If a component is exported as a custom element using

<svelte:options customElement="some-component" />

any foreign CSS imports that works in normal Svelte componentes don't work on the custom element:

  • Using

    import './custom.css';

    works as expected in regular Svelte components, but when used in a custom element, the styles are not properly scoped or injected into the shadow root.

  • Adding a stylesheet with

    <svelte:head>
      <link rel="stylesheet" href="/custom.css" />
    </svelte:head>

    causes Svelte to insert the <link> into the document's <head>, not into the custom element's shadow root. This means the styles are global and not encapsulated within the custom element, which causes them to not affect it at all (see AquaCounter for a manual workaround).

  • Importing CSS via a <style> tag:

    <style>
      @import "./custom.css";
    </style>

    partially works, but if the imported CSS contains selectors not used in the component's markup, Svelte emits a 'css-unused-selector' warning. Additionally, the imported CSS is scoped only to the current component and is not available to child components, so it cannot act as a "global" style for the custom element.

Reproduction

I've created a repository to demonstrate the bug and some workarounds one can use to import foreign CSSs

https://github.com/GCastilho/svelte-css-imports-custom-elements-bug-demo

Instructions and details are on README

Logs

N/A

System Info

System:
    OS: Windows 11 10.0.26100
    CPU: (14) x64 Intel(R) Core(TM) Ultra 5 135U
    Memory: 3.91 GB / 15.52 GB
  Binaries:
    Node: 22.16.0 - C:\Program Files\nodejs\node.EXE
    pnpm: 10.11.1 - C:\Program Files\nodejs\pnpm.CMD
  Browsers:
    Edge: Chromium (134.0.3124.85)
  npmPackages:
    svelte: ^5.28.1 => 5.33.14

Severity

blocking all usage of svelte

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions