web-dev-qa-db-fra.com

Sass - Manipuler une propriété héritée?

Est-il possible, dans Sass, de manipuler une valeur qu'un élément donné hérite déjà?

Je vise quelque chose comme ça:

body
  color: blue
  .warning
    color: red

strong
  color: darken(inherit,20)
33
Design by Adrian

Héritage

Non. Sass ne "sait" pas de quel sélecteur hériter la couleur. Il faudrait savoir que strong est un descendant de body. Cela semble être une hypothèse assez raisonnable pour vous et moi puisque strong n’est pas autorisé en dehors du corps, mais ce genre d’hypothèse ne peut pas être faite pour la plupart des sélecteurs. Sass devrait également savoir qu'il n'y a pas de cascades d'autres éléments ancêtres.

ul {
    color: red;
}

ol {
    color: blue;
}

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

Puis-je spécifier le sélecteur lequel que je veux copier?

Sass n'autorise pas non plus l'accès aux valeurs des variables précédemment déclarées. Il n'y a aucun moyen de spécifier "être plus sombre que la couleur du corps". Les règles CSS ne sont ni des objets ni des mappages et ne sont en aucun cas accessibles. Votre cas peut être simple, mais considérons un cas plus complexe comme celui-ci:

.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 ????
}

Eh bien qu'est-ce que je fais {peut}?

Vous devrez soit utiliser des variables, soit utiliser une fonctionnalité de Vanilla CSS pour faire ce que vous voulez.

CSS à l'ancienne

Certaines propriétés peuvent donner l’illusion d’être générées/héritées dynamiquement en utilisant des éléments pris en charge par les navigateurs depuis années:

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>

Variables CSS

La génération de variables CSS est à peu près aussi proche que possible de la possibilité de manipuler une propriété héritée. Le support du navigateur n’est pas encore tout à fait là (vérifiez caniuse ), mais voici à quoi cela ressemblerait:

Toupet:

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);
}

Sortie:

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>

Si vous utilisez un navigateur qui prend en charge les variables CSS, le résultat devrait ressembler à ceci:

 enter image description here

21
cimmanon

Je cherchais la même chose et je suis tombé sur ça. On a répondu à votre question, mais cela n'a pas résolu le problème.

Voici la solution: http://codepen.io/monsto/pen/tiokl

Si votre code HTML était ceci:

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

Ensuite, en utilisant SASS, vous pouvez faire ceci:

$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 semble n'avoir aucune idée des résultats de sa sortie. Par conséquent, inherit ne signifie rien pour elle. Vous lui demandez essentiellement de savoir quelle est la sortie avant de la produire.

Il sait cependant que ce sont des variables car, par défaut, elles sont étroitement délimitées. À partir de la documentation:

Les variables ne sont disponibles qu'au niveau des sélecteurs imbriqués où elles sont définies. S'ils sont définis en dehors de tout sélecteur imbriqué, ils sont disponibles partout.

ET ALORS variables dans mixins:

Le bloc de contenu transmis à un mixin est évalué dans la portée où le bloc est défini, pas dans la portée du mixin.

Cela permet au mélange ci-dessus de prendre une variable connue, définie dans le niveau parent, et de la redéfinir pour le niveau actuel et disponible pour ses enfants. C'est comme faire $x = $x + 1 dans une boucle multi-imbriquée

TBPH, cela change plutôt ma façon de penser du SASS. C'est clairement beaucoup plus programmatique que je ne le pensais.

9
monsto

Étant donné qu’un élément ne peut pas avoir plusieurs propriétés qui se combinent et que inherit ne peut pas connaître l’état actuel du rendu, vos options sont les suivantes:

1) Garder une trace du passé se transforme en utilisant les variables SASS: Demo

.parent {
  $firstTrans: translateX(50%);
  transform: $firstTrans;

  .child {
    /* Old followed by new */
    transform: $firstTrans rotate(10deg);
  }
}

2) Appliquez la transformation à un parent (peut-être en ajoutant un autre conteneur si nécessaire): Démo

3) Utilisez Javascript pour associer la transformation actuelle à celle que vous souhaitez ajouter (c’est le seul moyen de supprimer les transformations appliquées au parent si vous le souhaitez): Démo

Note: Cette réponse provient d'un article fusionné en raison de ce méta message .

9
Zach Saucier

Cela répond spécifiquement à la fonction darken: Une alternative possible consiste à utiliser le filtre CSS brightness() au lieu de la fonction SASS (ou LESS) darken(). Vous devrez en principe insérer la couleur dans une balise span pour que le filtre n’affecte pas les autres éléments.

Démo simple:

.red {color: red}
.blue {color: blue}
.green {color: green}

span {
  display: inline-block;
  padding: 1em;
}

.darken span {
  -webkit-filter: brightness(0.4);
  filter: brightness(0.4);
}
<span class="red">Red</span>
<span class="blue">Blue</span>
<span class="green">Green</span>

<div class="darken">
  <span class="red">Red</span>
  <span class="blue">Blue</span>
  <span class="green">Green</span>
</div>

jsFiddle: https://jsfiddle.net/azizn/hhorhz9s/

Vous devez garder à l'esprit la compatibilité du navigateur, cela devrait fonctionner pour IE Edge, les derniers Firefox et Chrome. Voir caniuse ou MDN pour plus d’informations.

En cas d’obscurcissement de l’arrière-plan, vous pouvez utiliser un pseudo-sélecteur avec opacité ou ajouter une image de fond PNG noire semi-transparente.

0
Aziz