389 votes

Comment appliquer l'opacité à une variable de couleur CSS?

Je suis en train de concevoir une application dans l'électronique, j'ai donc accès à la CSS de variables. J'ai défini une couleur variable en vars.css:

:root {
  --color: #f0f0f0;
}

Je veux utiliser cette couleur en main.css, mais avec un peu d'opacité appliquée:

#element {
  background: (somehow use var(--color) at some opacity);
}

Comment pourrais-je aller sur le faire? Je ne suis pas à l'aide de tout preprocesser, uniquement en CSS. Je préfère un CSS réponse, mais je vais accepter le JavaScript/jQuery.

Je ne peux pas utiliser opacity parce que je suis en utilisant une image de fond qui ne devrait pas être transparent.

594voto

BoltClock Points 249668

Vous ne pouvez pas prendre une couleur existante de valeur et appliquer une couche alpha. À savoir, vous ne pouvez pas prendre un hex de valeur tels que l' #f0f0f0, donner un composant alpha et l'utilisation de la valeur de la propriété.

Cependant, les propriétés personnalisées vous permettent de convertir votre valeur hexadécimale en RVB, triplet pour une utilisation avec des rgba(), stocker cette valeur dans la propriété personnalisée (y compris les virgules!), substituer cette valeur à l'aide d' var() en rgba() de la fonction désirée de la valeur alpha, et il va tout simplement de travail:

:root {
  /* #f0f0f0 in decimal RGB */
  --color: 240, 240, 240;
}

body {
  color: #000;
  background-color: #000;
}

#element {
  background-color: rgba(var(--color), 0.5);
}
<p id="element">If you can see this, your browser supports custom properties.</p>

Cela semble presque trop beau pour être vrai.1 Comment cela fonctionne?

La magie réside dans le fait que les valeurs de propriétés personnalisées sont substitués comme lors du remplacement d' var() des références en la valeur d'une propriété, avant que la valeur de la propriété est calculée. Cela signifie que dans la mesure où les propriétés personnalisées sont concernés, la valeur de --color dans votre exemple n'est pas une couleur de la valeur à tous jusqu'à ce qu' un var(--color) expression apparaît quelque part qui attend une valeur de couleur (et seulement dans ce contexte). De l'article 2.1 de la css-variables spec:

Le permis de syntaxe pour les propriétés personnalisées est très permissive. L' <déclaration de valeur> production correspond à toute séquence de un ou plusieurs jetons, tant que la séquence ne contient pas de <mauvais-chaîne-token>, <mauvais-url-token>, une <)-token>, <]-token>, ou <}>, ou de niveau supérieur <point-virgule-token> jetons ou <delim-token> jetons avec une valeur de "!".

Pour exemple, le code suivant est valide propriété personnalisée:

--foo: if(x > 5) this.width = 10;

Alors que cette valeur est évidemment inutile comme une variable, comme il serait invalide dans une propriété, il peut être lu et traité par JavaScript.

Et l'article 3:

Si une propriété contient un ou plusieurs (var) de fonctions, et ces fonctions sont syntaxiquement valide, l'ensemble de la propriété de la grammaire doit être supposé pour être valide au moment de l'analyse. C'est seulement la syntaxe vérifié au calculée valeur de temps après (var) fonctions ont été substituées.

Cela signifie que l' 240, 240, 240 de la valeur que vous voyez ci-dessus se substituer directement dans l' rgba() fonction avant la déclaration est calculée. Donc ceci:

#element {
  background-color: rgba(var(--color), 0.5);
}

ce qui ne semble pas être valide CSS au premier abord car rgba() attend pas moins de quatre séparée par des virgules des valeurs numériques, devient:

#element {
  background-color: rgba(240, 240, 240, 0.5);
}

ce qui, bien sûr, est parfaitement valide CSS.

En prenant une étape supplémentaire, vous pouvez stocker la composante alpha dans sa propre propriété personnalisée:

:root {
  --color: 240, 240, 240;
  --alpha: 0.5;
}

et de le remplacer, avec le même résultat:

#element {
  background-color: rgba(var(--color), var(--alpha));
}

Cela vous permet d'avoir différentes valeurs alpha que vous pouvez échanger à la volée.


1eh Bien, c'est, si vous êtes en cours d'exécution du fragment de code dans un navigateur qui ne prend pas en charge les propriétés personnalisées.

42voto

SimplyPhy Points 138

Je sais que l'OP n'est pas à l'aide d'un préprocesseur, mais j'aurais été aidé si l'information suivante a été une partie de la réponse ici (je ne peux rien dire encore, sinon j'aurais commenté @BoltClock réponse.

Si vous êtes en utilisant, par exemple, scss, la réponse ci-dessus sera un échec, car scss essaie de compiler les styles avec une scss spécifiques rgba()/hsla() de la fonction, qui nécessite 4 paramètres. Cependant, rgba()/hsla() sont également natif css fonctions, de sorte que vous pouvez utiliser de la chaîne d'interpolation pour contourner le scss fonction.

Exemple (valable dans sass 3.5.0+):

:root {
    --color_rgb: 250, 250, 250;
    --color_hsl: 250, 50%, 50%;
}

div {
    /* This is valid CSS, but will fail in a scss compilation */
    background-color: rgba(var(--color_rgb), 0.5);
    
    /* This is valid scss, and will generate the CSS above */
    background-color: #{'rgba(var(--color_rgb), 0.5)'};
}
<div></div>

Notez que la chaîne d'interpolation ne fonctionnera pas pour les non-CSS scss fonctions, telles que l' lighten(), parce que le code résultant ne serait pas fonctionnelle CSS. Il serait toujours valide scss si, donc, vous recevez aucun message d'erreur lors de la compilation.

5voto

Roberrrt Points 5527

C' est en effet possible avec CSS. C'est juste un peu sale, et vous aurez à utiliser des dégradés. J'ai codé un petit extrait à titre d'exemple, prenez note que pour les arrière-plans sombres, vous devez utiliser le noir opacité, comme pour la lumière, le blanc.:

:root {
  --red: rgba(255, 0, 0, 1);
  --white-low-opacity: rgba(255, 255, 255, .3);
  --white-high-opacity: rgba(255, 255, 255, .7);
  --black-low-opacity: rgba(0, 0, 0, .3);
  --black-high-opacity: rgba(0, 0, 0, .7);
}

div {
	width: 100px;
	height: 100px;
	margin: 10px;
}
    
    
.element1 {
	background: 
        linear-gradient(var(--white-low-opacity), var(--white-low-opacity)) no-repeat,
	linear-gradient(var(--red), var(--red)) no-repeat;
}

.element2 {
	background: 
        linear-gradient(var(--white-high-opacity), var(--white-high-opacity)) no-repeat,
	linear-gradient(var(--red), var(--red)) no-repeat;
}
    
.element3 {
	background: 
        linear-gradient(var(--black-low-opacity), var(--black-low-opacity)) no-repeat,
	linear-gradient(var(--red), var(--red)) no-repeat;
}

.element4 {
	background: 
        linear-gradient(var(--black-high-opacity), var(--black-high-opacity)) no-repeat,
	linear-gradient(var(--red), var(--red)) no-repeat;
}
<div class="element1">hello world</div>
<div class="element2">hello world</div>
<div class="element3">hello world</div>
<div class="element4">hello world</div>

0voto

Pizza lord Points 193
 :root{
--color: 255, 0, 0;
}

#element{
    background-color: rgba(var(--color), opacity);
}
 

où vous remplacez l'opacité par n'importe quoi entre 0 et 1

-1voto

Dekel Points 41575

Vous pouvez définir un ensemble de variable/valeur pour chaque couleur - l'original et l'un avec l'opacité:

:root {
  --color: #F00;
  --color-opacity: rgba(255, 0, 0, 0.5);
}
#a1 {
  background: var(--color);
} 
#a2 {
  background: var(--color-opacity);
}
<div id="a1">asdf</div>
<div id="a2">asdf</div>

Si vous ne pouvez pas l'utiliser et que vous êtes ok avec javascript solution, vous pouvez utiliser celui-ci:

$(function() {
  $('button').click(function() {
    bgcolor = $('#a2').css('backgroundColor');
    rgb_value = bgcolor.match(/\d+,\s?\d+,\s?\d+/)[0]
    $('#a2').css('backgroundColor', 'rgba(' + rgb_value + ', 0.5)');
  });
});
:root {
  --color: #F00;
}
#a1 {
  background: var(--color);
} 
#a2 {
  background: var(--color);
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div id="a1">asdf</div>
<div id="a2">asdf</div>
<button>Click to change opacity</button>

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X