Sass: ¿manipular la propiedad heredada?

Resuelto Design by Adrian asked hace 11 años • 4 respuestas

¿Es posible, en Sass, manipular un valor que un elemento determinado ya hereda?

Mi objetivo es algo como esto:

body
  color: blue
  .warning
    color: red

strong
  color: darken(inherit,20)
Design by Adrian avatar Feb 17 '13 18:02 Design by Adrian
Aceptado

Herencia

No. Sass no "sabe" de qué selector heredar el color. Debería saber que stronges descendiente de body. Esa parece una suposición bastante razonable para usted y para mí, ya que strongno está permitido fuera del cuerpo, pero ese tipo de suposición no se puede hacer con la mayoría de los selectores. Sass también tendría que saber que no se producen cascadas de otros elementos ancestrales.

ul {
    color: red;
}

ol {
    color: blue;
}

li {
    // which color do I inherit from ????
}

Bueno, ¿puedo especificar desde qué selector quiero copiar?

Sass tampoco otorga acceso a los valores de ninguna variable previamente declarada de ninguna manera. No hay forma de especificar "ser más oscuro que el color del cuerpo". Las reglas CSS no son objetos ni asignaciones y no son accesibles de ninguna manera. Su caso puede ser simple, pero considere un caso más complejo como este:

.foo {
    background: mix(white, blue); // fallback for non-rgba browsers
    background: rgba(blue, .5);

    .baz & {
        background: yellow;
    }

    @media (min-width 30em) {
        background: orange;
    }

    @supports (flex-wrap: wrap) {
        background: red;
    }
}

.bar {
    // access which background color from .foo ????
}

Bueno, ¿qué puedo hacer?

Necesitará usar variables o tendrá que ser una característica de CSS básico para hacer lo que quiera.

CSS anticuado

Algunas propiedades pueden dar la ilusión de ser generadas/heredadas dinámicamente utilizando elementos que han sido compatibles con los navegadores durante años :

ul.one {
  background: white;
}

ul.two {
  background: yellow;
}

ul {
  background: rgba(0, 120, 255, .2);
  padding: 1em;
}
<ul class="one">
  <li><ul>
    <li><ul>
      <li>Foo</li>
    </ul></li>
  </ul></li>
</ul>

<ul class="two">
  <li><ul>
    <li><ul>
      <li>Foo</li>
    </ul></li>
  </ul></li>
</ul>
Expandir fragmento

Variables CSS

Generar variables CSS es lo más parecido a poder manipular una propiedad heredada. La compatibilidad con el navegador aún no está disponible (consulte caniuse ), pero así es como se vería:

Hablar con descaro a:

ul {
  --list-color: orange;
  --darker-color: darken(orange, 15%);
  color: var(--list-color);
}

ol {
  --list-color: green;
  --darker-color: darken(green, 10%);
  color: var(--list-color);
}

li {
  background: var(--darker-color);
}

Producción:

ul {
  --list-color: orange;
  --darker-color: #b37400;
  color: var(--list-color);
}

ol {
  --list-color: green;
  --darker-color: #004d00;
  color: var(--list-color);
}

li {
  background: var(--darker-color);
}
<ul>
  <li>Foo</li>
</ul>

<ol>
  <li>Bar</li>
</ol>
Expandir fragmento

Si está utilizando un navegador que admite variables CSS, el resultado debería verse así:

ingrese la descripción de la imagen aquí

cimmanon avatar Feb 17 '2013 12:02 cimmanon

Estaba buscando lo mismo y encontré esto. Su pregunta fue respondida, pero no resolvió el problema.

Aquí está la solución: http://codepen.io/monsto/pen/tiokl

Si tu HTML fuera este:

    <div class="main">
      <header class="header">
        <div class="warning">
          <p><strong>Danger,</strong> Will Robinson!</p>
        </div>
      </header>
    </div>

Luego, usando SASS podrías hacer esto:

$bg: #f88;

@mixin colorize {
  $bg: darken($bg,15%) !global; // !global flag required for 3.4 or later, remove if using 3.3 or older
  background: $bg;
}

.warning {
  background: $bg;
  p {
    @include colorize;
    strong {
      @include colorize;
    }
  }
}

SASS parece no tener idea de los resultados de su producción. Por lo tanto, inheritno significa nada para ello. Básicamente, le estás pidiendo que sepa cuál es el resultado antes de emitirlo.

Sin embargo, sí conoce sus variables ya que, de forma predeterminada, tienen un alcance estricto. De los documentos:

Las variables solo están disponibles dentro del nivel de selectores anidados donde están definidas. Si se definen fuera de cualquier selector anidado, estarán disponibles en todas partes.

Y LUEGO variables en mixins:

El bloque de contenido pasado a un mixin se evalúa en el ámbito donde se define el bloque, no en el ámbito del mixin.

Esto permite que el mixin anterior tome una variable conocida, definida en el nivel principal, y la redefina para el nivel actual y esté disponible para sus hijos. Es como hacerlo $x = $x + 1dentro de un bucle multianidado.

TBPH, esto cambia bastante mi forma de pensar sobre SASS. Es claramente mucho más programático de lo que pensaba.

monsto avatar Sep 12 '2013 19:09 monsto