Skip to content

CSS ::slotted not working with Svelte based custom elements #10093

Open
@GELight

Description

@GELight

Describe the bug

It is not possible to use CSS ::slotted to set CSS styles on slotted elements inside a Svelte-based custom element / web component in Svelte 4.x.

Note: With Svelte 3.x this CSS was working inside a custom element.

What I try do do:
I working on a UI lib based on custom elements. In this bug / case I try to implement 2 simple custom elements for a "list" and a "list-item". All list-item's should be placed in the slot of the list.
Per CSS ::slotted() I need to set a simiple CSS style for all list-items so that each "list-item + list-item" get a border-top for a visual separator only between the list-item's.

Reproduction

List Component 1:

<svelte:options customElement="cds-list" />

<div class="cds-list">
    <slot />
</div>

<style lang="scss">
  .cds-list {
    box-sizing: border-box;
    position: relative;
    display: flex;
    flex-direction: column;
    padding: var(--cds-spacing-2);
    border: 1px solid #666;
  }

  ::slotted(cds-list-item:not(:first-child)) {
    border-top: 1px solid red;
  }
</style>

List-Item Component 2:

<svelte:options customElement="cds-list-item" />

<div class="cds-list-item">
    <slot />
</div>

<style lang="scss">
  :host {
    box-sizing: border-box;
    position: relative;
    display: flex;
    flex-direction: column;
    justify-content: center;
    padding: 10px;
  }
</style>

Using in HTML/Template:

<cds-list>
    <cds-list-item>List Item Text 1</cds-list-item>
    <cds-list-item>List Item Text 2</cds-list-item>
    <cds-list-item>List Item Text 3</cds-list-item>
</cds-list>

Example of rendered style results inside the list component shadow-dom style

The styles below are the rendered result of my current production test:

.cds-list.svelte-ucfdua{box-sizing:border-box;position:relative;display:flex;flex-direction:column;padding:var(--cds-spacing-2);border:var(--cds-border-width-default) var(--cds-border-style-default) var(--cds-color-accent-border-neutral);border-radius:var(--cds-radius-2)}.svelte-ucfdua::slotted(cds-list-item:not(:first-child)){border-top:1px solid red}:host([flush]) .cds-list.svelte-ucfdua{border:0;padding-left:0;padding-right:0}

_Specific view on the generated CSS code of the slotted CSS:

.svelte-ucfdua::slotted(cds-list-item:not(:first-child)){border-top:1px solid red}

Here you can see that the Svelte-Bundler will set a sciping css class before my ::sotted CSS.
(NOT EXPECTED)

After I edit the generated style CSS inside the shadow dom with the developer tools and remove the ".svelte-ucfdua" string, the CSS works fine. I think this is a bug ..... right?
When not ... its possible to configure vite so that no scoping prefix will set for ::slotted and :global?

Note: :global do not working also after manual editing about the developer tools
Note: If I test this example from MDN https://developer.mozilla.org/en-US/docs/Web/CSS/::slotted#highlighting_slotted_elements all works fine.

Logs

No response

System Info

System: Linux Mint 19
Browser: Chrome

Vite Config:


import { svelte } from "@sveltejs/vite-plugin-svelte";
import sveltePreprocess from "svelte-preprocess";
import { resolve, join } from "path";

if (process.env.APP_ENV === "dev") {
}

// https://vitejs.dev/config/

export default {
    root: resolve(__dirname),
    // base: '/lib/',
    build: {
        outDir: "dist",
        emptyOutDir: true,
        minify: true,
        sourcemap: false,
        lib: {
            entry: "src/main.ts",
            formats: ["es"],
            name: "CowDesignSystem",
            fileName: "cow-design-system",
        },
        rollupOptions: {
            output: {
                assetFileNames: "cow-design-system.css",
            },
        },
    },
    plugins: [
        svelte({
            emitCss: true,
            preprocess: [sveltePreprocess(
                {
                    typescript: true,
                },
            )],
            compilerOptions: {
                customElement: true,
            },
        }),
    ],
    resolve: {
        alias: {
            "~@fontsource": join(__dirname, "../node_modules/@fontsource"),
        },
    },
};

Severity

annoyance

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions