DEV Community

Cover image for ๐Ÿš€ Svelte Quick Tip: Styling slot content with :global
Dana Woodman
Dana Woodman

Posted on • Updated on

๐Ÿš€ Svelte Quick Tip: Styling slot content with :global

๐Ÿ‘‹ Hello, World!

Here's a spicy ๐ŸŒถ Svelte quick tip for ya, hope you enjoy ๐Ÿคฉ

Ever sat around scratching your head asking "how on earth do I get rid of this damn margin on my <slot> content?" or some other slot styling quandary?

Well, I know I have, so maybe you have too? ๐Ÿง


The problem

Let's say you have a <Box> component that you pass content into and sometimes that content has margins on it that you really just don't want. You'd prefer if your box component would remove the margins of the content that is passed into it, no matter what that content may be.

Well, since Svelte scopes styles to a component by default, it's not as simple as you may initially think.


The component

So, let's say your pretty little <Box> component looks about like this:

<!-- Box.svelte -->

<section>
  <slot></slot>
</section>

<style>
  section {
    background: PaleTurquoise;
    padding: 1rem;
  }
</style>
Enter fullscreen mode Exit fullscreen mode

Now let's say you use it a bit like so:

<!-- App.svelte -->

<script>
  import Box from "./Box.svelte"
</script>

<Box>
  <p>This paragraph should not have a top margin!</p>
  <p>This is a paragraph with top and bottom margins</p>
  <p>This paragraph should not have a bottom margin!</p>
</Box>

<style>
  p {
    margin: 2rem 0;
  }
</style>
Enter fullscreen mode Exit fullscreen mode

Now when you render this, you see something like this which isn't really what you wanted:

box with margins

You look at this monstrosity and scream out some expletives ๐Ÿคฌ and wonder how the hell you're going to do to remedy this situation.

Well, fear not dear reader, for you have stumbled upon the solution to your existential pain and suffering!


The solution

The solution is simple and elegant; we will use the :global modifier in our <Box> CSS to remove top/bottom margins.

Here's how we're going to do it, just add these two rules to your CSS for Box.svelte like so:

section :global(> :first-child) {
  margin-top: 0;
}
section :global(> :last-child) {
  margin-bottom: 0;
}
Enter fullscreen mode Exit fullscreen mode

Now you should see your <Box> component in all its margin-less glory!

box without margins

๐ŸŽ‰ Huzzah!! We did it! A real game-changer, I know!

This will generate some styles that are still scoped to the component:

rendered CSS

You'll see that the paragraph styling is overridden by the :first-child style because it is more "specific", thus allowing you to have styles applied to the slot's content as well as overriding any styles you need in the parent component.

Cool right!? ๐Ÿค“


The final component

Here is our component in its full glory:

<section>
  <slot></slot>
</section>

<style>
  section {
    background: PaleTurquoise;
    padding: 1rem;
  }
  section :global(> :first-child) {
    margin-top: 0;
  }
  section :global(> :last-child) {
    margin-bottom: 0;
  }
</style>
Enter fullscreen mode Exit fullscreen mode

Checkout the Svelte REPL here to play around with this.


๐ŸŽฌ Fin

You can leverage the :global modifier to do a lot of other cool stuff as well, this is just one specific example to get your mind active ๐Ÿง 

Thanks for reading thus far ๐Ÿ™, hope you enjoyed!

Have other tips, ideas, feedback or corrections? Let me know in the comments! ๐Ÿ™‹โ€โ™‚๏ธ

You can find me on Twitter (@danawoodman) or Github (danawoodman)

Photo by Joshua Aragon on Unsplash

Top comments (0)