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)
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 ????
}
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 ????
}
Vous devrez soit utiliser des variables, soit utiliser une fonctionnalité de Vanilla CSS pour faire ce que vous voulez.
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>
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:
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.
É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 .
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.