Changer la couleur de l'image PNG via CSS?

465

Étant donné un PNG transparent affichant une forme simple en blanc, est-il possible de changer la couleur de celui-ci via CSS? Une sorte de superposition ou non?

Wesley
la source
4
Vous pouvez définir la background-colorpropriété CSS. Vous pouvez créer une partie non transparente qui sera fixe et une partie transparente de l'image qui sera remplie par n'importe quelle couleur que vous souhaitez via CSS. Est-ce ce que vous souhaitez réaliser?
jakub.g
2
@qbk, cela vaut une réponse, pas seulement un commentaire. Et tu m'as battu d'une seconde, techniquement.
Kirill G
2
Vous pouvez utiliser des éléments pseudo avec un mode de fusion pour recolorer n'importe quelle icône qui est 100% noire ou 100% blanche (l'arrière-plan reste transparent). Voir ma réponse ici: stackoverflow.com/a/39796437/1472114
chrscblls

Réponses:

570

Vous pouvez utiliser des filtres avec -webkit-filteret filter: Les filtres sont relativement nouveaux pour les navigateurs mais pris en charge dans plus de 90% des navigateurs selon le tableau CanIUse suivant: https://caniuse.com/#feat=css-filters

Vous pouvez changer une image en niveaux de gris, sépia et bien plus encore (regardez l'exemple).

Vous pouvez donc maintenant changer la couleur d'un fichier PNG avec des filtres.

body {
    background-color:#03030a;
    min-width: 800px;
    min-height: 400px
}
img {
    width:20%;
    float:left; 
     margin:0;
}
/*Filter styles*/
.saturate { filter: saturate(3); }
.grayscale { filter: grayscale(100%); }
.contrast { filter: contrast(160%); }
.brightness { filter: brightness(0.25); }
.blur { filter: blur(3px); }
.invert { filter: invert(100%); }
.sepia { filter: sepia(100%); }
.huerotate { filter: hue-rotate(180deg); }
.rss.opacity { filter: opacity(50%); }
<!--- img src http://upload.wikimedia.org/wikipedia/commons/thumb/e/ec/Mona_Lisa%2C_by_Leonardo_da_Vinci%2C_from_C2RMF_retouched.jpg/500px-Mona_Lisa%2C_by_Leonardo_da_Vinci%2C_from_C2RMF_retouched.jpg -->
<img alt="Mona Lisa" src="https://www.pexels.com/photo/photo-of-a-green-leaf-2563743/?auto=compress&cs=tinysrgb&dpr=3&h=750&w=1260" title="original">
<img alt="Mona Lisa" src="https://images.pexels.com/photos/40997/mona-lisa-leonardo-da-vinci-la-gioconda-oil-painting-40997.jpeg?auto=compress&cs=tinysrgb&dpr=3&h=750&w=1260" title="saturate" class="saturate">
<img alt="Mona Lisa" src="https://images.pexels.com/photos/40997/mona-lisa-leonardo-da-vinci-la-gioconda-oil-painting-40997.jpeg?auto=compress&cs=tinysrgb&dpr=3&h=750&w=1260" title="grayscale" class="grayscale">
<img alt="Mona Lisa" src="https://images.pexels.com/photos/40997/mona-lisa-leonardo-da-vinci-la-gioconda-oil-painting-40997.jpeg?auto=compress&cs=tinysrgb&dpr=3&h=750&w=1260" title="contrast" class="contrast">
<img alt="Mona Lisa" src="https://images.pexels.com/photos/40997/mona-lisa-leonardo-da-vinci-la-gioconda-oil-painting-40997.jpeg?auto=compress&cs=tinysrgb&dpr=3&h=750&w=1260" title="brightness" class="brightness">
<img alt="Mona Lisa" src="https://images.pexels.com/photos/40997/mona-lisa-leonardo-da-vinci-la-gioconda-oil-painting-40997.jpeg?auto=compress&cs=tinysrgb&dpr=3&h=750&w=1260" title="blur" class="blur">
<img alt="Mona Lisa" src="https://images.pexels.com/photos/40997/mona-lisa-leonardo-da-vinci-la-gioconda-oil-painting-40997.jpeg?auto=compress&cs=tinysrgb&dpr=3&h=750&w=1260" title="invert" class="invert">
<img alt="Mona Lisa" src="https://images.pexels.com/photos/40997/mona-lisa-leonardo-da-vinci-la-gioconda-oil-painting-40997.jpeg?auto=compress&cs=tinysrgb&dpr=3&h=750&w=1260" title="sepia" class="sepia">
<img alt="Mona Lisa" src="https://images.pexels.com/photos/40997/mona-lisa-leonardo-da-vinci-la-gioconda-oil-painting-40997.jpeg?auto=compress&cs=tinysrgb&dpr=3&h=750&w=1260" title="huerotate" class="huerotate">
<img alt="Mona Lisa" src="https://images.pexels.com/photos/40997/mona-lisa-leonardo-da-vinci-la-gioconda-oil-painting-40997.jpeg?auto=compress&cs=tinysrgb&dpr=3&h=750&w=1260" title="opacity" class="rss opacity">

La source

РАВИ
la source
12
Donc, la réponse courte est qu'il n'y a pas de solution générale pour la majorité des navigateurs.
Trilarion
18
Mais l'huerotation ou la saturation feront-elles réellement quelque chose à une image blanche?
Keith
6
Mise à jour 2016: cela fonctionne maintenant dans presque tous les navigateurs sauf IE: caniuse.com/#feat=css-filters
Stan
4
@datatype_void Parfois, vous ne contrôlez pas vous-même l'image de départ. Donc, il semble que vous conveniez que mon argument est valable, vous ne pouvez pas accéder à n'importe quelle couleur à partir du noir ou du blanc. Oh, et j'ai joué plus de 5 minutes pour arriver à cette conclusion.
AsGoodAsItGets
5
spécifiez également que vous pouvez faire des choses comme ceci: ce .gifcorrect{ filter: invert(28%) sepia(100%) hue-rotate(-180deg) saturate(3); }qui signifie que vous pouvez passer du noir et transparent ou des niveaux de gris à la couleur et cela fonctionne même sur les gifs animés
tatsu
141

J'ai trouvé cet excellent exemple de codepen que vous insérez votre valeur de couleur hexadécimale et il retourne le filtre nécessaire pour appliquer cette couleur au png

Générateur de filtres CSS pour convertir du noir en couleur hexadécimale cible

par exemple, j'avais besoin que mon png ait la couleur suivante # 1a9790

alors vous devez appliquer le filtre suivant à votre png

filter: invert(48%) sepia(13%) saturate(3207%) hue-rotate(130deg) brightness(95%) contrast(80%);
Fadi Abo Msalam
la source
12
<3 <3 <3 <3 <3 <3
dwjohnston
2
J'ai changé la couleur du blanc du bleu en utilisant ce code:filter: invert(1%) sepia(1%) saturate(1%) hue-rotate(1deg) brightness(1000%) contrast(80%);
Anjan Biswas
C'est bien!!
Thiago Pires
2
L'auteur mérite une statue! (notez le: luminosité (0) saturé (100%)
pré-ajout
1
Si quelqu'un en a besoin, voici une conversion TS de ce code gist.github.com/dwjohnston/7e60bf5d4b6c071cd869f9f346241c08
dwjohnston
56

Vous voudrez peut-être jeter un œil aux polices Icon. http://css-tricks.com/examples/IconFont/

EDIT: J'utilise Font-Awesome sur mon dernier projet. Vous pouvez même l'amorcer. Mettez simplement ceci dans votre <head>:

<link href="//netdna.bootstrapcdn.com/font-awesome/3.2.1/css/font-awesome.min.css" rel="stylesheet">

<!-- And if you want to support IE7, add this aswell -->
<link href="//netdna.bootstrapcdn.com/font-awesome/3.2.1/css/font-awesome-ie7.min.css" rel="stylesheet">

Et puis allez-y et ajoutez des liens d'icônes comme celui-ci:

<a class="icon-thumbs-up"></a>

Voici la feuille de triche complète

--Éditer--

Font-Awesome utilise différents noms de classe dans la nouvelle version, probablement parce que cela rend les fichiers CSS considérablement plus petits et pour éviter les classes CSS ambiguës. Alors maintenant, vous devez utiliser:

<a class="fa fa-thumbs-up"></a>

EDIT 2:

Je viens de découvrir que github utilise également sa propre police d'icônes: Octicons. Il est gratuit à télécharger. Ils ont également quelques conseils sur la façon de créer vos propres polices d'icônes .

Jules Colle
la source
Font Awesome porte bien son nom.
HerrimanCoder
+1 pour une réflexion immédiate. Et de nos jours, il existe des applications en ligne faciles à utiliser pour vous aider à créer une police Web à partir d'une image (svg).
yvan vander sanden
Si <a class="icon-thumbs-up"> </a> est l'ancien nom de la classe et <a class="fa fa-thumbs-up"> </a> est le nouveau, je ne pense pas rend le CSS plus petit, je peux voir un espace supplémentaire entre fa et fa-thumbs-up, ajouter au moins 1 octet supplémentaire à ce fichier CSS si je ne me trompe pas?
Brandito
Font Awesome était génial en son temps, malheureusement son blocage de rendu, ce qui rend Google et ses utilisateurs mécontents. Nous avons d'abord résolu ce problème en supprimant les polices inutilisées des fichiers de police CSS et binaires, réduisant ainsi les données d'environ la moitié. Nous sommes maintenant en train de supprimer complètement et de remplacer par un simple sprite, qui ne rend pas le blocage (processus DOM et CSSOM plus rapides, ce qui accélère les éléments sur la page), et réduira les données de 75% supplémentaires, jusqu'à 6 Ko. FA est d'environ 100 Ko. Les masques CSS peuvent aider dans notre cas, mais probablement inutiles.
YK
25

J'ai pu le faire en utilisant un filtre SVG. Vous pouvez écrire un filtre qui multiplie la couleur de l'image source par la couleur que vous souhaitez modifier. Dans l'extrait de code ci-dessous, flood-color est la couleur dans laquelle nous voulons changer la couleur de l'image (qui est rouge dans ce cas). FeComposite indique au filtre comment nous traitons la couleur. La formule pour feComposite avec arithmétique est (k1 * i1 * i2 + k2 * i1 + k3 * i2 + k4) où i1 et i2 sont les couleurs d'entrée pour in / in2 en conséquence. Donc, en spécifiant uniquement k1 = 1, cela ne fera que i1 * i2, ce qui signifie multiplier les deux couleurs d'entrée ensemble.

Remarque: Cela ne fonctionne qu'avec HTML5 car il utilise le SVG en ligne. Mais je pense que vous pourriez faire fonctionner cela avec un navigateur plus ancien en plaçant SVG dans un fichier séparé. Je n'ai pas encore essayé cette approche.

Voici l'extrait:

<svg xmlns="http://www.w3.org/2000/svg" version="1.1" width="60" height="90" style="float:left">
  <defs>
    <filter id="colorMask1">
      <feFlood flood-color="#ff0000" result="flood" />
      <feComposite in="SourceGraphic" in2="flood" operator="arithmetic" k1="1" k2="0" k3="0" k4="0" />
    </filter>
  </defs>
  <image width="100%" height="100%" xlink:href="http://i.stack.imgur.com/OyP0g.jpg" filter="url(#colorMask1)" />
</svg>
<svg xmlns="http://www.w3.org/2000/svg" version="1.1" width="60" height="90" style="float:left">
  <defs>
    <filter id="colorMask2">
      <feFlood flood-color="#00ff00" result="flood" />
      <feComposite in="SourceGraphic" in2="flood" operator="arithmetic" k1="1" k2="0" k3="0" k4="0" />
    </filter>
  </defs>
  <image width="100%" height="100%" xlink:href="http://i.stack.imgur.com/OyP0g.jpg" filter="url(#colorMask2)" />
</svg>
<svg xmlns="http://www.w3.org/2000/svg" version="1.1" width="60" height="90" style="float:left">
  <defs>
    <filter id="colorMask3">
      <feFlood flood-color="#0000ff" result="flood" />
      <feComposite in="SourceGraphic" in2="flood" operator="arithmetic" k1="1" k2="0" k3="0" k4="0" />
    </filter>
  </defs>
  <image width="100%" height="100%" xlink:href="http://i.stack.imgur.com/OyP0g.jpg" filter="url(#colorMask3)" />
</svg>

Vasan Jiaramaneetwesin
la source
4
Mec tu te fais voler sur cette réponse. Quiconque cherche à coloriser des images au-delà de ce filtre: la rotation de la teinte peut le faire - c'est la façon de le faire.
MaxPRafferty
23

La balise img a une propriété d'arrière-plan comme les autres. Si vous avez un PNG blanc avec une forme transparente, comme un pochoir, vous pouvez le faire:

<img src= 'stencil.png' style= 'background-color: red'>
Kirill G
la source
147
Je veux que la partie blanche soit colorée différemment, pas la partie transparente.
Wesley
2
meilleure solution que j'ai trouvée jusqu'à présent. Dommage que cela ne fonctionne que si vous utilisez une couleur d'arrière-plan unie sur vos sites Web
Jules Colle
8
@Wesley, vous devez ensuite inverser l'image (pour que le bit blanc devienne transparent et le reste blanc), ce que vous pouvez faire en utilisant votre éditeur d'image et vos masques préférés.
Charles Goodwin
5
@CharlesGoodwin Cela ne fonctionne que si l'image est placée sur un fond blanc.
Alex
21

Oui :)

Surfin 'Safari - Blog Archive »Masques CSS

WebKit prend désormais en charge les masques alpha en CSS. Les masques vous permettent de superposer le contenu d'une boîte avec un motif qui peut être utilisé pour masquer des parties de cette boîte dans l'affichage final. En d'autres termes, vous pouvez découper des formes complexes en fonction de l'alpha d'une image.
[...]
Nous avons introduit de nouvelles propriétés pour fournir aux concepteurs Web un grand contrôle sur ces masques et sur la façon dont ils sont appliqués. Les nouvelles propriétés sont analogues aux propriétés d'arrière-plan et d'image de bordure qui existent déjà.

-webkit-mask (background)
-webkit-mask-attachment (background-attachment)
-webkit-mask-clip (background-clip)
-webkit-mask-origin (background-origin)
-webkit-mask-image (background-image)
-webkit-mask-repeat (background-repeat)
-webkit-mask-composite (background-composite)
-webkit-mask-box-image (border-image)
benhowdle89
la source
1
Cela fait-il partie d'une norme (à venir), car je n'ai trouvé aucune information sans rapport avec Webkit, ou s'agit-il uniquement d'une saveur Apple? Il semble que le W3 propose SVG pour de telles utilisations: w3.org/TR/SVG/masking.html
feeela
3
Malheureusement, cela ne semble être que du webkit et le blog triche en utilisant des images composites plutôt que des exemples réels. Cette réponse est un peu de hareng rouge.
Charles Goodwin
17

Dans la plupart des navigateurs , vous pouvez utiliser des filtres:

  • sur les <img>éléments et les images d'arrière-plan d'autres éléments

  • et définissez-les soit statiquement dans votre CSS, soit dynamiquement en utilisant JavaScript

Voir les démos ci-dessous.


<img> éléments

Vous pouvez appliquer cette technique à un <img>élément:

#original, #changed {
    width: 45%;
    padding: 2.5%;
    float: left;
}

#changed {
    -webkit-filter : hue-rotate(180deg);
    filter : hue-rotate(180deg);
}
<img id="original" src="http://i.stack.imgur.com/rfar2.jpg" />

<img id="changed" src="http://i.stack.imgur.com/rfar2.jpg" />

Images de fond

Vous pouvez appliquer cette technique à une image d'arrière-plan:

#original, #changed {
    background: url('http://i.stack.imgur.com/kaKzj.jpg');
    background-size: cover;
    width: 30%;
    margin: 0 10% 0 10%;
    padding-bottom: 28%;
    float: left;
}

#changed {
    -webkit-filter : hue-rotate(180deg);
    filter : hue-rotate(180deg);
}
<div id="original"></div>

<div id="changed"></div>

Javascript

Vous pouvez utiliser JavaScript pour définir un filtre lors de l'exécution:

var element = document.getElementById("changed");
var filter = 'hue-rotate(120deg) saturate(2.4)';
element.style['-webkit-filter'] = filter;
element.style['filter'] = filter;
#original, #changed {
    margin: 0 10%;
    width: 30%;
    float: left;
    background: url('http://i.stack.imgur.com/856IQ.png');
    background-size: cover;
    padding-bottom: 25%;
}
<div id="original"></div>

<div id="changed"></div>

John Slegers
la source
6
La question portait sur la colorisation d'une image blanche avec un fond transparent. hue-rotatene fonctionne pas sur le blanc.
Synetech
17

Je pense avoir une solution pour cela qui est a) exactement ce que vous cherchiez il y a 5 ans, et b) est un peu plus simple que les autres options de code ici.

Avec n'importe quel png blanc (par exemple, icône blanche sur fond transparent), vous pouvez ajouter un sélecteur :: after pour recolorer.

.icon {
    background: url(img/icon.png); /* Your icon */
    position: relative; /* Allows an absolute positioned psuedo element */
}

.icon::after{
    position: absolute; /* Positions psuedo element relative to .icon */
    width: 100%; /* Same dimensions as .icon */
    height: 100%;
    content: ""; /* Allows psuedo element to show */
    background: #EC008C; /* The color you want the icon to change to */
    mix-blend-mode: multiply; /* Only apply color on top of white, use screen if icon is black */
}

Voir ce codepen (application de l'échange de couleurs au survol): http://codepen.io/chrscblls/pen/bwAXZO

chrscblls
la source
J'ai réhébergé l'image hors d'imgur, j'ai eu quelques problèmes pour la charger.
chrscblls
Dans la dernière version de Chrome, il semble que l'arrière-plan (transparent) soit également défini sur la couleur. Dans l'exemple lié, lorsque je survole, je vois juste un carré rose opaque ... Fonctionne bien dans Firefox.
logidelic
1
@chrscblls Le lien est mort.
Steven Lu
15

La ligne la plus simple qui a fonctionné pour moi:

filter: opacity(0.5) drop-shadow(0 0 0 blue);

Vous pouvez régler l'opacité de 0 à 1 pour éclaircir ou assombrir la couleur.

Rehmat
la source
Agréable. Cela évite toutes les limitations des autres solutions ici.
cdonner le
3
répéter l'ombre portée 2-3 fois pour le rendre plus fort
djdance
1
GENIUS SOLUTION, semble un peu désordonné dans le CSS, mais avec un commentaire, c'est parfaitement compréhensible. Merci!
Richard KeMiKaL GeNeRaL Denton
ne fonctionnera pas pour obtenir la couleur exacte, c'est toujours une sorte de mélange entre la couleur d'origine et la nouvelle.
swisswiss
cette approche déforme légèrement l'image et elle empire chaque fois que l'ombre portée est appliquée. Comme pour faire une copie d'une copie, les résultats sont différents de l'original.
SMAG
8

J'ai trouvé ça en cherchant sur Google, j'ai trouvé qu'il valait mieux travailler pour moi ...

HTML

<div class="img"></div>

CSS

.img {
  background-color: red;
  width: 60px;
  height: 60px;
   -webkit-mask-image: url('http://i.stack.imgur.com/gZvK4.png');
}

http://jsfiddle.net/a63b0exm/

Muthukumar Anbalagan
la source
Cela fonctionne, j'ai voté. Mais pour mémoire, il a des problèmes comme la taille de l'image d'arrière-plan, la position de l'image et la répétition.
Daniel
Ohh, je n'ai vraiment pas essayé ceux-ci ... essayez le lien ci-dessous. developer.mozilla.org/en-US/docs/Web/CSS/-webkit-mask-box-image merci, Daniel
Muthukumar Anbalagan
7

J'avais besoin d'une couleur spécifique, donc le filtre ne fonctionnait pas pour moi.

Au lieu de cela, j'ai créé un div, en exploitant plusieurs images d'arrière-plan CSS et la fonction de gradient linéaire (qui crée une image elle-même). Si vous utilisez le mode de fusion de superposition, votre image réelle sera mélangée avec l'image "dégradée" générée contenant la couleur souhaitée (ici, # BADA55)

.colored-image {
        background-image: linear-gradient(to right, #BADA55, #BADA55), url("https://i.imgur.com/lYXT8R6.png");
        background-blend-mode: overlay;
        background-size: contain;
        width: 200px;
        height: 200px;        
    }
<div class="colored-image"></div>

rolznz
la source
Ça n'a pas marché pour moi. Je ne peux pas dire pourquoi, j'ai copié collé exactement
Vic Seedoubleyew
@VicSeedoubleyew l'extrait fonctionne correctement. Inspectez votre div à l'aide des outils de développement pour vous assurer que votre CSS est réellement appliqué. Assurez-vous également que l'URL de votre image est valide si vous n'utilisez pas celle que j'ai fournie. EDIT: si l'extrait ne fonctionne pas pour vous, vous utilisez peut-être un navigateur obsolète ou ne prenant pas en charge la fonction de gradient linéaire.
rolznz
5

Répondre parce que je cherchais une solution pour cela.

le stylo dans la réponse @chrscblls fonctionne bien si vous avez un fond blanc ou noir, mais pas le mien. De plus, les images ont été générées avec ng-repeat, donc je ne pouvais pas avoir leur URL dans mon css ET vous ne pouvez pas utiliser :: after sur les balises img.

J'ai donc pensé à contourner le problème et j'ai pensé que cela pourrait aider les gens s'ils trébuchent trop ici.

Donc ce que j'ai fait est à peu près la même chose avec trois différences principales:

  • l'url étant dans ma balise img, je l'ai mise (et une étiquette) dans une autre div sur laquelle :: after fonctionnera.
  • le «mode mix-blend» est réglé sur «différence» au lieu de «multiplier» ou «écran».
  • J'ai ajouté un :: before avec exactement la même valeur pour que le :: after fasse la 'différence' de la 'différence' faite par le :: before et l'annule lui-même.

Pour le faire passer du noir au blanc ou du blanc au noir, la couleur d'arrière-plan doit être blanche. Du noir aux couleurs, vous pouvez choisir n'importe quelle couleur. Du blanc aux couleurs, vous devrez choisir la couleur opposée à celle que vous souhaitez.

.divClass{
   position: relative;
   width: 100%;
   height: 100%;
   text-align: left;
}
.divClass:hover::after, .divClass:hover::before{
   position: absolute;
   width: 100%;
   height: 100%;
   background: #FFF;
   mix-blend-mode: difference;
   content: "";
}

https://codepen.io/spaceplant/pen/oZyMYG

Salix
la source
3

Il n'y a pas besoin d'un jeu de polices complet si vous n'avez besoin que d'une seule icône, et je pense qu'il est plus "propre" en tant qu'élément individuel. Donc, à cette fin, en HTML5, vous pouvez placer un SVG directement dans le flux de documents. Ensuite, vous pouvez définir une classe dans votre feuille de style .CSS et accéder à sa couleur d'arrière-plan avec la fillpropriété:

Violon de travail: http://jsfiddle.net/qmsj0ez1/

Notez que, dans l'exemple, j'ai utilisé :hoverpour illustrer le comportement; si vous voulez juste changer la couleur pour l'état "normal", vous devez supprimer la pseudoclasse.

Pere
la source
1

Pour changer littéralement la couleur, vous pouvez incorporer une transition CSS avec un filtre -webkit où, lorsque quelque chose se produit, vous invoquerez le filtre -webkit de votre choix. Par exemple:

img {
    -webkit-filter:grayscale(0%);
    transition: -webkit-filter .3s linear;
    }
img:hover 
    {
    -webkit-filter:grayscale(75%);
    }
beta208
la source
1

Lorsque vous changez une image du noir au blanc ou du blanc au noir, le filtre de rotation de teinte ne fonctionne pas, car le noir et le blanc ne sont pas techniquement des couleurs. Au lieu de cela, les changements de couleur noir et blanc (du noir au blanc ou vice-versa) doivent être effectués avec la propriété de filtre inversé.

.img1 { filter: invert(100%); }

Samuel stankiewicz
la source
0

body{
  background: #333 url(/images/classy_fabric.png);
  width: 430px;
  margin: 0 auto;
  padding: 30px;
}
.preview{
  background: #ccc;
  width: 415px;
  height: 430px;
  border: solid 10px #fff;
}

input[type='radio'] {
  -webkit-appearance: none;
  -moz-appearance: none;
  width: 25px;
  height: 25px;
  margin: 5px 0 5px 5px;
  background-size: 225px 70px;
  position: relative;
  float: left;
  display: inline;
  top: 0;
  border-radius: 3px;
  z-index: 99999;
  cursor: pointer;
  box-shadow: 1px 1px 1px #000;
}

input[type='radio']:hover{
  -webkit-filter: opacity(.4);
  filter: opacity(.4);    
}

.red{
  background: red;
}

.red:checked{
  background: linear-gradient(brown, red)
}

.green{
  background: green;
}

.green:checked{
  background: linear-gradient(green, lime);
}

.yellow{
  background: yellow;
}

.yellow:checked{
  background: linear-gradient(orange, yellow);
}

.purple{
  background: purple;
}

.pink{
  background: pink;
}

.purple:checked{
  background: linear-gradient(purple, violet);
}

.red:checked ~ img{
  -webkit-filter: opacity(.5) drop-shadow(0 0 0 red);
  filter: opacity(.5) drop-shadow(0 0 0 red);
}

.green:checked ~ img{
  -webkit-filter: opacity(.5) drop-shadow(0 0 0 green);
  filter: opacity(.5) drop-shadow(0 0 0 green);
}

.yellow:checked ~ img{
  -webkit-filter: opacity(.5) drop-shadow(0 0 0 yellow);
  filter: opacity(.5) drop-shadow(0 0 0 yellow);
}

.purple:checked ~ img{
  -webkit-filter: opacity(.5) drop-shadow(0 0 0 purple);
  filter: opacity(.5) drop-shadow(0 0 0 purple);
}

.pink:checked ~ img{
  -webkit-filter: opacity(.5) drop-shadow(0 0 0 pink);
  filter: opacity(.5) drop-shadow(0 0 0 pink);
}


img{
  width: 394px;
  height: 375px;
  position: relative;
}

.label{
  width: 150px;
  height: 75px;
  position: absolute;
  top: 170px;
  margin-left: 130px;
}

::selection{
  background: #000;
}
<div class="preview">
  <input class='red' name='color' type='radio' />
  <input class='green' name='color' type='radio' />
    <input class='pink' name='color' type='radio' />
  <input checked class='yellow' name='color' type='radio' />
  <input class='purple' name='color' type='radio' />  
  <img src="https://i.stack.imgur.com/bd7VJ.png"/>
</div>

Source: https://codepen.io/taryaoui/pen/EKkcu

Bashirpour
la source