Search code examples
csssvelte

Programmatically add (scoped) class name in Svelte


Code snippet:

<script>
  let coloredText = "This is colored text"
    let templateString = `This text is programmatically inserted`;
  let templateHtml = `<span class="colored">I want this text to be red</span></h1>`
  
</script>

<style>
  .colored {
    color: red;
  }

  main {
    font-family: sans-serif;
    text-align: center;
  }
</style>

<main>
    <h1>This is normal text</h1>
  <h1><span class="colored">{coloredText}</span></h1>
    <h1>{templateString}</h1>
  <h1>{@html templateHtml}</h1>
    
</main>

Output:

enter image description here

Codesandbox

When you add a css class to an element, Svelte seems to add an additional svelte-xxxx class to the (correctly styled) resulting markup. It does not add the same class to literal HTML rendered with an @html tag, and the resulting markup is not styled, even though the CSS selector should match the resulting element.

What is the canonical way to add a class name to programmatically generated HTML in Svelte? I am aware of :global but I would like to keep the result scoped to the component.


Solution

  • Using the :global(...) modifier in combination with a wrapping element inside the component will keep the styles scoped

     h1 :global(.colored) {
        color: red;
      }
    

    ->

    h1.svelte-nd95r3 .colored {
        color: red;
    }