1

I am using the Oruga and Storybook libraries to make components in Vue 3.

The Vue file code is written as:

<template>
  <o-radio v-bind="$props" v-model="model">
    <slot />
  </o-radio>
</template>

<script lang="ts">
import { defineComponent } from "@vue/runtime-core";
import Radio from '../mixins/radio-mixins';

export default defineComponent({
  name: "BaseRadio",
  computed: {
    model: {
      get() {
        return this.$props.nativeValue;
      },
      set(value: any) {
        this.$emit("input", value);
      },
    },
  },
  emits: ["input"],
  props: {
    ...Radio.props,
  },
});
</script>

<style scoped>
  .b-radio.radio.is-primary .check:checked {
    border-color: var(--color-blue);
  }
  .b-radio.radio.is-primary .check:checked:focus {
    box-shadow: 0 0 3px 3px var(--color-light-blue);
  }
  .b-radio.radio.is-primary .check:before {
    background: var(--color-blue);
  }
</style>

Here in the <style> tag I am modifying the element classes provided by the Oruga library to achieve the desired styling.

The main problem is that when I use scoped on the <style> tag, none of my styles get applied to the rendered view. Omitting scoped makes it work again.

How can I fix this? I need to apply these styles while also using the scoped tag in <style>.

zcoop98
  • 2,590
  • 1
  • 18
  • 31

2 Answers2

0

Maybe it's because you are trying to change classes that only exist in the DOM itself because the Oruga thing that you are using, so when you omit the "scoped" property, you are able to manipulate oruga classes globally. These oruga classes doesn't exist in your component itself when you're working with the component

  • Do you know how can I fix that ?. – Nishkarsh Kumar Apr 08 '22 at 05:02
  • Your answer could be improved with additional supporting information. Please [edit] to add further details, such as citations or documentation, so that others can confirm that your answer is correct. You can find more information on how to write good answers [in the help center](/help/how-to-answer). – Community Apr 08 '22 at 05:34
  • use your style with the scoped – BugInTheConsole Dec 02 '22 at 16:31
0

By default, slotted content (elements rendered via the <slot> tag) isn't affected by the scoped styles of the component hosting that <slot>. Instead, that content is considered "owned by" its parent, which is the component actually being rendered into the <slot>.

This leaves you with 3 options:

Put the styles in the slotted component directly

If you put the styles in the component getting rendered into the slot, then they will apply to that component regardless of where it's rendered.

Given, this isn't always desired or even possible, however, if you e.g. don't control the slotted-in component.

Use the :slotted() Attribute

The ::slotted() pseudo-attribute is designed specifically to refer to elements rendered within a <slot> tag. Vue 3 has its own version of this written as :slotted() (note the single colon : instead of two ::).

<style scoped>
  :slotted(.b-radio.radio.is-primary .check:checked) {
    border-color: var(--color-blue);
  }
  :slotted(.b-radio.radio.is-primary .check:checked:focus) {
    box-shadow: 0 0 3px 3px var(--color-light-blue);
  }
  :slotted(.b-radio.radio.is-primary .check:before) {
    background: var(--color-blue);
  }
</style>

Use the :deep() Attribute

The scoped attribute specifically limits styles to the component their declared on, but the :deep() selector lets components apply styles to their children, which includes slotted components, since they're rendered as child nodes in the DOM.

<style scoped>
  :deep(.b-radio.radio.is-primary .check:checked) {
    border-color: var(--color-blue);
  }
  :deep(.b-radio.radio.is-primary .check:checked:focus) {
    box-shadow: 0 0 3px 3px var(--color-light-blue);
  }
  :deep(.b-radio.radio.is-primary .check:before) {
    background: var(--color-blue);
  }
</style>

Note, however, that doing this will pollute the styles scope further down the chain; grandchildren nodes and further will still be affected by these styles. This can potentially cause problems if you aren't careful with your class names and selector choices.

zcoop98
  • 2,590
  • 1
  • 18
  • 31