web-dev-qa-db-fra.com

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

Je conçois une application en format électronique, donc j'ai accès aux variables CSS. J'ai défini une variable de couleur dans vars.css:

:root {
  --color: #f0f0f0;
}

Je veux utiliser cette couleur dans main.css, mais avec une certaine opacité appliquée:

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

Comment pourrais-je m'y prendre? Je n'utilise aucun préprocesseur, seulement CSS. Je préférerais une réponse entièrement en CSS, mais j'accepterai JavaScript/jQuery.

Je ne peux pas utiliser opacity parce que j'utilise une image d'arrière-plan qui ne doit pas être transparente.

83
JoshyRobot

Vous ne pouvez pas prendre une valeur de couleur existante et lui appliquer un canal alpha. En d'autres termes, vous ne pouvez pas prendre une valeur hexadécimale existante telle que #f0f0f0, lui attribuer une composante alpha et utiliser la valeur résultante avec une autre propriété.

Cependant, les propriétés personnalisées vous permettent de convertir votre valeur hexadécimale en un triplet RVB à utiliser avec rgba(), de stocker cette valeur dans la propriété personnalisée (y compris les virgules!), De remplacer cette valeur par var() par un rgba() fonctionne avec la valeur alpha souhaitée, et il ne vous reste plus qu'à fonctionner:

: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 ça marche?

La magie réside dans le fait que les valeurs des propriétés personnalisées sont substituées telles quelles lors du remplacement de var() références dans une valeur de propriété, avant la valeur de cette propriété est calculée. Cela signifie qu'en ce qui concerne les propriétés personnalisées, la valeur de --color dans votre exemple n'est pas une valeur de couleur jusqu'à ce que a var(--color) expression apparaît quelque part qui attend une valeur de couleur (et uniquement dans ce contexte). De section 2.1 de la spécification css-variables:

La syntaxe autorisée pour les propriétés personnalisées est extrêmement permissive. La production <declaration-value> correspond à toute séquence d'un ou de plusieurs jetons, tant qu'elle ne contient pas <bad-string-token>, <bad-url-token>, <) - token>, <] - jeton>, ou <} - jeton>, ou jetons <point-virgule>> ou <delim-jeton> de niveau supérieur avec une valeur "!".

Par exemple, voici une propriété personnalisée valide:

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

Bien que cette valeur soit évidemment inutile en tant que variable, comme elle serait invalide dans toute propriété normale, elle pourrait être lue et exploitée par JavaScript.

Et section :

Si une propriété contient une ou plusieurs fonctions var () et que ces fonctions sont valides du point de vue de la syntaxe, la grammaire de la propriété entière doit être considérée comme valide au moment de l’analyse. Ce n'est que la syntaxe vérifiée au moment de la valeur calculée, après le remplacement des fonctions var ().

Cela signifie que la valeur 240, 240, 240 que vous voyez ci-dessus est directement substituée à la fonction rgba() avant la déclaration est calculée. Donc ça:

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

qui ne semble pas être une CSS valide au début parce que rgba() ne s'attend pas à moins de quatre valeurs numériques séparées par des virgules, devient ceci:

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

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

Pour aller plus loin, vous pouvez stocker le composant alpha dans sa propre propriété personnalisée:

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

et le substituer, 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 permuter à la volée.


1Eh bien, si vous exécutez le fragment de code dans un navigateur qui ne prend pas en charge les propriétés personnalisées.

134
BoltClock

Je sais que le PO n'utilise pas de préprocesseur, mais on m'aurait aidé si les informations suivantes faisaient partie de la réponse ici (je ne peux pas commenter, sinon j'aurais commenté la réponse de @BoltClock.

Si vous utilisez, par exemple scss, la réponse ci-dessus va échouer, car scss tente de compiler les styles avec une fonction spécifique à scss, rgba ()/hsla (), qui nécessite 4 paramètres. Cependant, rgba ()/hsla () sont également des fonctions css natives. Vous pouvez donc utiliser une interpolation de chaîne pour contourner la fonction scss.

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 l’interpolation de chaîne ne fonctionnera pas pour les fonctions scss non-CSS, telles que lighten(), car le code résultant ne serait pas un CSS fonctionnel. Cela resterait cependant valide, donc vous ne recevrez aucune erreur lors de la compilation.

10
SimplyPhy
: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

1
Pizza lord

Ceci est en effet possible avec CSS. C'est juste un peu sale, et vous devrez utiliser des dégradés. Par exemple, j'ai codé un petit extrait. Notez que pour les fonds sombres, vous devez utiliser l'opacité noire, comme pour les fonds clairs: les blancs:

: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>
1
Roberrrt

Je me trouvais dans une situation similaire, mais malheureusement les solutions proposées ne fonctionnaient pas pour moi, car les variables pouvaient être quelque chose de rgb à hsl à hex ou même à des noms de couleurs.
J'ai résolu ce problème maintenant, en appliquant le background-color et le opacity à un pseudo :after élément:

.container {
    position: relative;
}

.container:after {
    content: "";
    width: 100%;
    height: 100%;
    position: absolute;
    left: 0;
    background-color: var(--color);
    opacity: 0.3;
}

Les styles devront peut-être être légèrement modifiés, en fonction de l'élément auquel l'arrière-plan devra être appliqué.
En outre, cela pourrait ne pas fonctionner dans toutes les situations, mais nous espérons que cela aidera dans certains cas, lorsque les autres solutions ne peuvent pas être utilisées.

0
Springrbua

En CSS, vous devriez pouvoir utiliser les valeurs de rgba:

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

ou simplement définir l'opacité:

#element {
  background: #f0f0f0;
  opacity: 0.5;    
}
0
Patrick H.

Vous pouvez définir une variable/valeur spécifique pour chaque couleur - l’original et 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 utiliser ceci et que vous êtes d'accord avec la solution javascript, vous pouvez utiliser celle-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>
0
Dekel

Pour utiliser rgba () avec une variable css générale, essayez ceci:

  1. Déclarez votre couleur à l'intérieur: racine, mais n'utilisez pas rgb () comme le font les autres réponses. Écrivez simplement la valeur
:root{
  --color : 255,0,0;
  }
  1. tilisez la variable --color en utilisant var () comme autre réponse
#some-element {
  color : rgba(var(--color),0.5);
}
0
Dani Fadli