@scope

<< @layer @property >>

La rule @scope es una regla de CSS que te permite aislar estilos de manera nativa para que solo afecten a una parte específica del documento (el DOM). Básicamente, crea un "micro-entorno" donde tus selectores funcionan de forma independiente sin riesgo de sobreescribir el diseño del resto de la página.

Tened en cuenta que siempre debemos mirar la compatibilidad con el navegador desde mdn y caniuse

Imagina que tenemos una tarjeta (.card) que tiene un título (.title). Pero dentro de esa tarjeta, podemos tener otro componente (como un .badge o una .media-object) que también tiene su propio .title.

El Problema: Normalmente, si escribes .card .title { color: blue; }, ambos títulos se volverán azules.

La Solución con @scope: Usamos @scope para decirle al CSS de la tarjeta que no debe aplicarse a los elementos que están dentro del .badge.

En el siguiente ejemplo, dentro de un bloque @scope, la pseudo-clase :scope se refiere al propio elemento raíz que define ese ámbito (scope), es decir, .badge.

<!DOCTYPE html>
<html lang="es">
<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>Ejemplo de @scope</title>
  <link rel="stylesheet" href="1.scope.css">
</head>
<body>

  <h1>Ejemplo de <code>@scope</code></h1>

  <article class="card">
    <h2 class="title">Este es el Título de la Tarjeta</h2>
    <p>Este párrafo debe heredar los estilos de la tarjeta.</p>
  </article>

  <article class="card">
    <h2 class="title">Este es el Título de la Tarjeta</h2>
    <p>Este párrafo también.</p>

    <div class="badge">
      <h3 class="title">Título de la Insignia</h3>
      <p>Este bloque es un componente separado y no debe ser afectado por los estilos de .card .</p>
    </div>
  </article>

</body>
</html>

En la Tarjeta 1: El .title ("Este es el Título de la Tarjeta") será grande (1.75rem) y de color oscuro (#333), tal como lo define el ámbito de .card.

En el caso de no poner un límite al scope, como en el caso de @scope (.badge), sería equivalente a simplemente usar nesting.

En la Tarjeta 2:

  • El primer .title (el de la tarjeta) será grande y oscuro.
  • El segundo .title ("Título de la Insignia") no se verá afectado por los estilos de .card. En su lugar, usará los estilos de su propio ámbito (.badge), siendo pequeño (1rem) y de color azul (#007c91).

¿Cuándo usar nesting y cuándo @scope?

  • Usa Nesting para organizar los estilos internos de un componente que no contiene otros componentes complejos.
  • Usa @scope cuando estés diseñando un componente "contenedor" (como .card, article, sidebar) y quieras asegurarte de que sus estilos no interfieran con los componentes que pueda tener dentro (como .badge, .avatar, .mi-boton).
<!DOCTYPE html>
<html lang="en">

<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
    <link rel="stylesheet" href="2.scopevsnesting.css">
</head>

<body>
    <main>
        <article>Lorem ipsum dolor sit amet consectetur adipisicing elit. Nobis praesentium tenetur, incidunt voluptatem
            exercitationem fugit modi minus unde dolorum autem quis ea recusandae suscipit vitae illo ratione maxime
            mollitia quaerat.</article>
        <aside class="sidebar">
            <h3>Menú</h3>
            <p>Contenido de la barra lateral...</p>

            <button>Botón Genérico</button>

            <hr>

            <button class="mi-boton">
                Botón Verde (¡Debería ser verde!)
            </button>
        </aside>
    </main>

</body>

</html>

Con nesting, .mi-boton pierde sus estilos. Se vuelve transparente y con texto blanco normal, porque los estilos de .sidebar button son más específicos (o simplemente se aplican después) y anulan los estilos base de .mi-boton.

En cambio con scope, odemos aplicar estilos al .sidebar y sus botones genéricos, pero creando un límite para que no afecten a nuestro componente .mi-boton.

  • El .sidebar tiene su fondo oscuro y padding.
  • El genérico se vuelve transparente con borde blanco (como queríamos).
  • El mantiene sus estilos originales (fondo verde, texto blanco, negrita) porque el @scope impidió que los estilos del contenedor le afectaran.

Límite inferior to

La palabra clave to crea una frontera estricta donde el alcance de los estilos se detiene por completo.

Lo que hace to (.badge) es decirle al navegador: "Aplica estos estilos a todo lo que esté dentro de la tarjeta, pero en el momento en que te choques con un elemento .badge, detente". Automáticamente excluye a ese elemento y a todos los elementos descendientes que vivan dentro de él.

Se podría ver de manera análoga a un paraguas, es decir, el @scope (.card) lanza una cascada de estilos desde arriba. Sin embargo, el to (.badge) abre un paraguas exactamente en ese contenedor. Todo lo que esté debajo de ese paraguas (el propio .badge y su contenido interno) queda protegido y no se "moja" con los estilos de la tarjeta.

<< @layer @property >>