How to Style Slot Elements in Vue 3 Using Slotted Selectors

Robin
Updated on March 7, 2024

You can add styles to any upcoming HTML elements in the <slot> using Vue 3 slotted selectors. In this way, we can write CSS styles in one place and reuse them throughout our application.

Vue 3 provides the :slotted() pseudo-class to target any HTML tags, id, or class that the slot will receive from another component and add styles to those elements. Whenever it receives those elements, it will apply the styles automatically.

You can also apply the global CSS style in Vue 3 if you prefer. But if you want to write scoped CSS for the slot elements, you have to use this pseudo-class.

What are Slotted Selectors in Vue 3?

Slotted selectors are a type of CSS selector that allows you to target elements that are passed to a slot and add CSS styles in Vue 3 SFC components. You can target any HTML element, id, or class selector using the :slotted() pseudo-class.

To understand how this pseudo-class works, let's see an example:

          <style scoped>
.container :slotted(h2) {
    font-size: 35px;
    color: #054ba0;
}
</style>
        

Suppose you will pass a <h2> element to a <slot> and you want to add a default style to it. If you select that heading tag directly and add style in the scoped <style> section, it will not have any effect.

Vue considers the elements that you pass to the slot are owned by that component. This component has no control over them. That's why we need to use the :slotted() pseudo-class in order to select any upcoming elements.

Here I am targeting any <h2> tag that is present inside the .container class and adding CSS properties. Now, whenever you pass <h2> elements, these styles will work on them. You don't have to write styles for it in any other components.

Also Read: How to Pass Data From Child to Parent in Vue 3 (Composition API)


Add CSS Styles to Slot Elements

You have to add the CSS styles in the component where you use the <slot> element. So, create a Vue 3 component in your project with it.

I have a BaseLayout.vue component, where I will receive content from other components using <slot> and render them on the screen. Here I want to target the title class.

          <template>
    <section>
        <header>Header Section</header>

        <main class="container">
            <slot></slot>
        </main>

        <footer>Footer Section</footer>
    </section>
</template>

<style scoped>
.container :slotted(.title) {
    font-size: 35px;
    color: #054ba0;
}
</style>
        

In this example, I am using the <slot> element in this component where I can pass and render any content from another component.

Here I expect an element with a class title and add some style to it. As you know, we can't directly select that element here. Because it is coming from another component.

The BaseLayout.vue component doesn't have control over that element. Therefore, you need to use the :slotted() inside <style scoped> section to select that class.

That's why I am targeting .title that is present inside the container class and adding some CSS properties to it. Now whenever you will pass an element with this title class, these styles will be applied to it automatically.

          <template>
    <div>
        <base-layout>
            <div>
                <h2 class="title">Page title</h2>
            </div>
        </base-layout>
    </div>
</template>

<script setup>
import BaseLayout from './components/BaseLayout.vue'
</script>
        

Here I am using the BaseLayout component and passing a <h2> tag with the title class. It will have those styles applied even if there is no style for it in this component.

It is very useful when you want to add a unique look to an element without writing CSS properties again and again. You can select that element and add the styles to make your CSS code reusable.

Related Posts