How to Pass Styles to Child Component and Use It as Scoped Style in Vue

How to pass styles to child component and use it as scoped style in Vue?

If you want to target the child elements with scoped styling you have to use the deep selector.

Which can be done with

a >>> b { color : red; }
/deep/ a b { color : red; }
a::v-deep b { color : red; }

Here is the full explanation: https://vue-loader.vuejs.org/guide/scoped-css.html#child-component-root-elements

Vue js - making a style to be inherited by children components

I think the only way to make a style intended for child components only, while not defining a selector for the parent, is simply to define this style in the child component.

Cordially!

Vue 3 slot styles from child component

Use the new :slotted selector in Vue 3:

Child.vue

<template>
<slot></slot>
</template>

<script>
export default {
name: "Child",
};
</script>

<style scoped>
:slotted(h1) {
color: red !important;
}
</style>

In Vue 3, child scoped styles don't affect slotted content by default.

In your particular example, the !important modifier is also necessary because the parent also defined an h1 style which would take precedence otherwise

Child component with muti-root nodes cannot be styled from parent scoped style

If the HelloWorld.vue component has a single root element like:

<template>
<div class="hello-world">
/* ... */
</div>
</template>

your code should work without changing anything because the class hello will be added to hello-world. Read in the docs -> Fallthrough Attributes

If the HelloWorld.vue component has multiple root nodes like:

<header>...</header>
<main>...</main>
<footer>...</footer>

then no "automatic attribute fallthrough behavior" will happen and you will have to manually bound the $attrs because otherwise you will get a warning:

<header>...</header>
<main v-bind="$attrs">...</main>
<footer>...</footer>

Read in the docs -> Attribute Inheritance on Multiple Root Nodes

What is the problem with mutli-root components?

Once you add many root nodes to a component, then suddenly the parent cannot change the child element styling in style scoped. /p>

See it live

I don't know if this is the intended behavior or it's a bug, but if you want an update on this, see this issue

Is there a way to style elements of a child mutli-root-nodes component?

One way is to use non-scoped style:

<style>
.hello {...}
</style>

Another way is to use style module:

<template>
<HelloWorld :class="$style.hello" />
</template>

<style module>
.hello {
background: blue;
color: white;
}
</style>

See live example

Vue.js: use CSS class for child element

Scoped Styles

  • Using scoped styles (in both parent and child) is a good idea and will make this solution easier.

  • Instead of creating a new custom-popup class, use a deep selector in the parent. This allows the parent to define extra styles for child components that use the same selector.

  • The deep selector looks like this: >>> unless you're using a SCSS/SASS pre-processor. Then you use ::v-deep instead.

<template>
<v-popup>
Popup content
</v-popup>
</template>

<style scoped>
>>> .popup {
padding: 20px;
}

/* If using SCSS/SASS, do this instead */
/*
::v-deep .popup {
padding: 20px;
}
*/
</style>

The child will use both its own .popup class and the one from the parent.

If you didn't use scoped styles, it would quickly become a problem if you wanted to import the child in multiple parents and use different styles each time.

How to use vue js scoped style

The scoped keyword means that this the changes to the style will apply only to the elements in the current scope. Meaning all custom made elements in the page. If you want to access elements "created" somewhere else you will have to skip the scoped keyword. The code that is in the scoped tag will apply only for the current page/view else it will apply for all pages/views.

All not scoped elements usually are style in the App.vue file. If you want to apply style of element that is not scoped just wrap it in a div add the class to it and style it in the scoped tag:

<style scoped>
.my-custom-div{
.el-icon-close:before{
content: "Back" !important;
}
}
</style>

Atleast that is working with me.



Related Topics



Leave a reply



Submit