vuejs-scoped-styles

Qué son y cómo usar estilos scoped en Vue.js

  • 2 min

Los scoped styles son una forma de encapsular estilos CSS dentro de un componente específico.

A medida que las aplicaciones crecen, los estilos globales pueden volverse difíciles de mantener y pueden generar conflictos entre componentes.

Aquí es donde entran en juego los scoped styles una característica de Vue.js que permite encapsular estilos dentro de un componente.

Los scoped styles son estilos que se aplican únicamente al componente en el que se definen, evitando conflictos con otros componentes.

Cómo usar Scoped Styles en Vue.js

Para usar scoped styles en Vue.js, simplemente agrega el atributo scoped a la etiqueta <style> en tu componente.

<template>
  <div class="container">
    <p class="text">Este es un texto estilizado.</p>
  </div>
</template>

<style scoped>
.container {
  padding: 20px;
  border: 1px solid #ccc;
}

.text {
  color: blue;
  font-size: 18px;
}
</style>

En este ejemplo,

  • Los estilos definidos en <style scoped> solo se aplican a los elementos dentro del componente.

Cómo funcionan los Scoped Styles internamente

Cuando definmos estilos con el atributo scoped en un componente, Vue.js automáticamente realiza una serie de modificaciones en los elementos a la hora de renderizarlo.

  1. Agrega un atributo único: A cada elemento del componente se le asigna un atributo único, como data-v-123456.
  2. Modifica los selectores CSS: Vue.js modifica los selectores CSS para que incluyan el atributo único.

Por ejemplo, el siguiente CSS:

.container {
  padding: 20px;
}

Se convertirá en:

.container[data-v-123456] {
  padding: 20px;
}

Esto garantiza que los estilos solo se apliquen a los elementos del componente actual.

Esto ocurre de forma transparente para nosotros, sin que tengamos que preocuparnos por (casi) nada

Propagar estilos a componentes hijos con Deep

Por defecto los estilos con scoped no se aplican a los componentes hijos. Pero, en algunos casos, es posible que queramos que sí se propagen.

Para esto, Vue.js proporciona el deep selector (:deep()).

<template>
  <div class="parent">
    <ChildComponent />
  </div>
</template>

<script setup>
import ChildComponent from './ChildComponent.vue';
</script>

<style scoped>
.parent :deep(.child-class) {
  color: red;
}
</style>

En este ejemplo, el estilo se aplica a elementos con la clase child-class dentro del componente ChildComponent, a pesar de que los estilos están definidos con scoped.

Aplicar estilos a elementos de slot con :slotted

De forma similar, cuando trabajamos con slots Vue.js tampoco propaga por defecto los estilos scoped a los slots. Para ello, proporciona el selector :slotted().

<template>
  <div class="wrapper">
    <slot></slot>
  </div>
</template>

<style scoped>
:slotted(p) {
  font-weight: bold;
  color: green;
}

/* También puedes usar clases o combinaciones más complejas */
:slotted(.special) {
  background-color: #eee;
}
</style>

En este ejemplo:

  • El selector :slotted(p) se aplicará a todos los elementos <p> que sean insertados en el slot del componente.
  • El selector :slotted(.special) se aplicará a cualquier elemento con la clase special que sea insertado en el slot.