Im having a lot of problems triying to style a child from parent in vue3.
In this case, i create a generic button with some css properties, and i try to customize this button from other component
Parent
<template>
<OwnButton
@ownButtonClicked="emit('accept')"
>
<slot>
ACCEPT
</slot>
</OwnButton>
</template>
<script setup>
import OwnButton from 'path/to/own-button.vue';
const emit = defineEmits(['accept']);
</script>
<style scoped>
.accept-button :deep(.own-button)
{
background-color : #4CAF50 !important;
outline-color : green !important;
}
.accept-button :deep(.own-button:hover)
{
background-color: green !important;
}
</style>
Child
<template>
<button
type="button"
@click="emit('ownButtonClicked')"
v-on:keyup.enter="emit('ownButtonClicked')"
>
<slot>
</slot>
</button>
</template>
<script setup>
const emit = defineEmits
([
'ownButtonClicked'
]);
</script>
<style scoped>
.own-button
{
background-color : azure;
outline-color : lightblue;
color : black;
margin : 2px;
padding : 5px;
border-radius : 15px;
border : 0;
box-shadow : 0 4px 8px 0 rgba(0, 0, 0, 0.2), 0 6px 20px 0 rgba(0, 0, 0, 0.19);
outline-style : solid;
min-width : 100px;
max-width : 150px;
}
.own-button:hover
{
cursor: pointer;
}
</style>
I tried everything I could think of, including using :deep(button) in parent
CodePudding user response:
I think it is related to where you apply the main class.
Try to put a wrapper around like that:
<template>
<div >
<OwnButton
@ownButtonClicked="emit('accept')"
>
<slot>
ACCEPT
</slot>
</OwnButton>
</div>
</template>
<script setup>
import OwnButton from './Comp.vue';
const emit = defineEmits(['accept']);
</script>
<style scoped>
.accept-button :deep(.own-button)
{
background-color : yellow !important;
outline-color : green !important;
}
.accept-button :deep(.own-button:hover)
{
background-color: green !important;
}
</style>
Here is the example above.
CodePudding user response:
This is a design limitation of Vue 3 when dealing with multi-root nodes
I wrote about this in my article Scoped styles and multi-root nodes don't work well together.
Understanding the issue
In Vue 3 we can finally have more than "one root node" components. That is great, but there is a design limitation when doing that. Imagine we have a child component:
<template>
<p >First p</p>
<p >Second p</p>
</template>
And a parent component:
<template>
<h1>My awesome component</h1>
<MyChildComponent />
</template>
<style scoped>
// There is no way to style the p tags of MyChildComponent
.my-p { color: red; }
:deep(.my-p) { color: red; }
</style>
There is no way from the scoped styling of the multi-root parent component to style the child component's p tags.
So in short, a multi-root component, can't target multi-root child component's styles with scoped styles.
Solutions