Zmienić kolor obrazu PNG za pomocą CSS?

464

Biorąc pod uwagę przezroczysty PNG o prostym kształcie w kolorze białym, czy można w jakiś sposób zmienić jego kolor za pomocą CSS? Jakaś nakładka czy co nie?

Wesley
źródło
4
Możesz ustawić background-colorwłaściwość CSS. Możesz stworzyć nieprzezroczystą część, która zostanie naprawiona, i przezroczystą część obrazu, która będzie wypełniona dowolnym kolorem, który ci się podoba za pomocą CSS. Czy to właśnie chcesz osiągnąć?
jakub.g
2
@qbk, to jest warte odpowiedzi, a nie tylko komentarza. I technicznie pokonałeś mnie o 1 sekundę.
Kirill G
2
Możesz użyć elementów psuedo z trybem mieszania, aby ponownie pokolorować dowolną ikonę, która jest w 100% czarna lub w 100% biała (tło pozostaje przezroczyste). Zobacz moją odpowiedź tutaj: stackoverflow.com/a/39796437/1472114
chrscblls

Odpowiedzi:

569

Możesz używać filtrów z -webkit-filteri filter: Filtry są stosunkowo nowe w przeglądarkach, ale obsługiwane w ponad 90% przeglądarek, zgodnie z poniższą tabelą CanIUse: https://caniuse.com/#feat=css-filters

Możesz zmienić obraz na skalę szarości, sepię i wiele więcej (patrz przykład).

Możesz teraz zmienić kolor pliku PNG za pomocą filtrów.

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">

Źródło

РАВИ
źródło
12
Tak krótka odpowiedź jest taka, że ​​nie ma żadnego ogólnego rozwiązania dla większości przeglądarek.
Trilarion
18
Ale czy huerotate lub nasycenie faktycznie zrobią coś z białym obrazem?
Keith
6
Aktualizacja 2016: działa teraz prawie we wszystkich przeglądarkach oprócz IE: caniuse.com/#feat=css-filters
Stan
4
@datatype_ unikać Czasami sam nie kontrolujesz obrazu początkowego. Wygląda więc na to, że zgadzasz się z moim twierdzeniem, że nie możesz uzyskać żadnego koloru, zaczynając od czerni lub bieli. Och, i grałem przez ponad 5 minut, aby dojść do tego wniosku.
AsGoodAsItGets
5
określ także, że możesz robić takie rzeczy: .gifcorrect{ filter: invert(28%) sepia(100%) hue-rotate(-180deg) saturate(3); }co oznacza, że ​​MOŻESZ przejść od czerni i przezroczystości lub skali szarości do koloru i działa nawet na animowanych
gifach
140

Znalazłem ten wspaniały przykład codepen, w którym wstawiasz wartość koloru heksadecymalnego i zwraca on wymagany filtr, aby zastosować ten kolor do png

Generator filtrów CSS do konwersji z czarnego na docelowy kolor heksadecymalny

na przykład potrzebowałem mojego png, aby mieć następujący kolor # 1a9790

następnie musisz zastosować następujący filtr do siebie png

filter: invert(48%) sepia(13%) saturate(3207%) hue-rotate(130deg) brightness(95%) contrast(80%);
Fadi Abo Msalam
źródło
12
<3 <3 <3 <3 <3 <3
dwjohnston
2
Zmieniłem kolor na biały z niebieskiego za pomocą tego kodu:filter: invert(1%) sepia(1%) saturate(1%) hue-rotate(1deg) brightness(1000%) contrast(80%);
Anjan Biswas
To jest świetne!!
Thiago Pires,
2
Autor zasługuje na posąg! (zwróć uwagę na: nasycenie jasności (0) (100%) opcjonalne, które zabija wszelkie wątpliwości)
Jackie Degl'Innocenti
1
Jeśli ktoś tego potrzebuje, oto konwersja TS tego kodu gist.github.com/dwjohnston/7e60bf5d4b6c071cd869f9f346241c08
dwjohnston
56

Możesz rzucić okiem na czcionki Icon. http://css-tricks.com/examples/IconFont/

EDYCJA: Używam Font-Awesome w moim najnowszym projekcie. Możesz go nawet uruchomić. Po prostu umieść to w <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">

A następnie dodaj kilka ikon-linków:

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

Oto pełna ściągawka

--edytować--

Font-Awesome używa różnych nazw klas w nowej wersji, prawdopodobnie dlatego, że powoduje to drastycznie mniejsze pliki CSS i pozwala uniknąć niejednoznacznych klas css. Więc teraz powinieneś użyć:

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

EDYCJA 2:

Właśnie się dowiedziałem, że github używa również własnej czcionki ikony: Octicons Można go bezpłatnie pobrać. Mają także kilka wskazówek na temat tworzenia własnych czcionek ikon .

Jules Colle
źródło
Font Awesome zasługuje na swoją nazwę.
HerrimanCoder
+1 za nieszablonowe myślenie. Obecnie dostępne są łatwe w użyciu aplikacje online, które pomagają w tworzeniu stron WWW z obrazu (svg).
yvan vander sanden
Jeśli <a class="icon-thumbs-up"> </a> to stara nazwa klasy, a <a class="fa fa-thumbs-up"> </a> to nowa, nie sądzę zmniejsza CSS, widzę dodatkową spację między fa i fa-thumbs-up, dodaj co najmniej 1 dodatkowy bajt do tego pliku CSS, jeśli się nie mylę?
Brandito
Czcionka Awesome była świetna w ciągu dnia, niestety jej blokowanie renderowania sprawia, że ​​Google i jej użytkownicy są niezadowoleni. Po raz pierwszy rozwiązaliśmy ten problem, usuwając nieużywane czcionki zarówno z CSS, jak i plików czcionek binarnych, zmniejszając dane o około połowę. Jesteśmy teraz w trakcie usuwania całkowicie i zastępowania prostym ikoną, która nie renderuje blokowania (DOM i CSSOM przetwarzają szybciej, dzięki czemu elementy na stronie pojawiają się szybciej) i zmniejszy dane o kolejne 75%, do 6 KB. FA ma około 100 KB. Maski CSS mogą w naszym przypadku pomóc, ale prawdopodobnie niepotrzebne.
YK
25

Udało mi się to zrobić za pomocą filtra SVG. Możesz napisać filtr, który zwielokrotnia kolor obrazu źródłowego przez kolor, który chcesz zmienić. W poniższym fragmencie kodu kolor-powodzi to kolor, który chcemy zmienić na kolor obrazu (w tym przypadku na Czerwony). FeComposite informuje filtr, w jaki sposób przetwarzamy kolor. Wzór na feComposite z arytmetyką jest (k1 * i1 * i2 + k2 * i1 + k3 * i2 + k4), gdzie i1 i i2 są odpowiednio kolorami wejściowymi dla in / in2. Podanie tylko k1 = 1 oznacza, że ​​zrobi to tylko i1 * i2, co oznacza pomnożenie razem obu kolorów wejściowych.

Uwaga: Działa to tylko z HTML5, ponieważ używa wbudowanego SVG. Ale myślę, że możesz sprawić, by działało to ze starszą przeglądarką, umieszczając SVG w osobnym pliku. Nie próbowałem jeszcze takiego podejścia.

Oto fragment:

<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
źródło
4
Człowieku, który cię okrada z tej odpowiedzi. Każdy, kto chce pokolorować obrazy poza tym, co filtr: hue-rotate może zrobić - tak to zrobić.
MaxPRafferty
23

Tag img ma właściwość tła, jak każda inna. Jeśli masz biały plik PNG o przezroczystym kształcie, takim jak szablon, możesz to zrobić:

<img src= 'stencil.png' style= 'background-color: red'>
Kirill G.
źródło
147
Chcę, aby biała część była inaczej zabarwiona, a nie przezroczysta.
Wesley
2
najlepsze rozwiązanie, jakie do tej pory znalazłem. Szkoda, że ​​zadziała tylko wtedy, gdy użyjesz jednolitego koloru tła na swoich stronach internetowych
Jules Colle,
8
@Wesley musisz wtedy odwrócić obraz (aby biały bit stał się przezroczysty, a reszta biała), co możesz zrobić za pomocą swojego ulubionego edytora obrazów i masek.
Charles Goodwin,
5
@CharlesGoodwin To działa tylko wtedy obraz jest umieszczony na białym tle.
Alex
21

Tak :)

Surfin 'Safari - Archiwum blogów »Maski CSS

WebKit obsługuje teraz maski alfa w CSS. Maski pozwalają na nałożenie zawartości pola wzorem, którego można użyć do wybicia części tego pola na ostatecznym ekranie. Innymi słowy, możesz przycinać złożone kształty oparte na alfa obrazu.
[...]
Wprowadziliśmy nowe właściwości, aby zapewnić projektantom stron internetowych dużą kontrolę nad tymi maskami i sposobem ich stosowania. Nowe właściwości są analogiczne do właściwości tła i obramowania obrazu, które już istnieją.

-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
źródło
1
Czy to część jakiegokolwiek (jeszcze) standardu, ponieważ nie znalazłem żadnych informacji niezwiązanych z Webkitem, czy może to tylko smak Apple? Wygląda na to, że W3 sugeruje SVG dla takich przypadków użycia: w3.org/TR/SVG/masking.html
opłata
3
Niestety wydaje się, że jest to tylko webkit, a blog oszukuje, używając skomponowanych obrazów, a nie rzeczywistych przykładów. Ta odpowiedź to trochę czerwony śledź.
Charles Goodwin,
17

W większości przeglądarek możesz użyć filtrów:

  • na <img>elementach i obrazach tła innych elementów

  • i ustaw je albo statycznie w CSS, albo dynamicznie przy użyciu JavaScript

Zobacz dema poniżej.


<img> elementy

Możesz zastosować tę technikę do <img>elementu:

#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" />

Obrazy tła

Możesz zastosować tę technikę do obrazu tła:

#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

Możesz użyć JavaScript, aby ustawić filtr w czasie wykonywania:

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
źródło
6
Pytanie dotyczyło pokolorowania białego obrazu przezroczystym tłem. hue-rotatenie działa na białym.
Synetech
17

Pomyśl, że mam na to rozwiązanie, a) dokładnie to, czego szukałeś 5 lat temu, i b) jest nieco prostsze niż inne opcje kodu tutaj.

Z dowolnym białym png (np. Białą ikoną na przezroczystym tle), możesz dodać selektor :: po, aby go ponownie pokolorować.

.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 */
}

Zobacz ten codepen (zastosowanie zamiany kolorów po najechaniu kursorem): http://codepen.io/chrscblls/pen/bwAXZO

chrscblls
źródło
Ponownie przestawiłem obraz z imgur, miałem problemy z ładowaniem go.
chrscblls,
W najnowszej wersji Chrome wygląda na to, że (przezroczyste) tło również ustawia kolor. W połączonym przykładzie po najechaniu kursorem widzę nieprzezroczysty różowy kwadrat ... Działa dobrze w przeglądarce Firefox.
logiczny
1
@chrscblls Link nie działa.
Steven Lu
15

Najprostsza jedna linia, która zadziałała dla mnie:

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

Możesz ustawić krycie od 0 do 1, aby rozjaśnić lub przyciemnić kolor.

Rehmat
źródło
Miły. Pozwala to uniknąć wszystkich ograniczeń innych rozwiązań tutaj.
cdonner,
3
Powtórz cień 2-3 razy, aby wzmocnić
djdance
1
GENIUS SOLUTION, wygląda trochę niechlujnie w CSS, ale z komentarzem, jest całkowicie zrozumiały. Dzięki!
Richard KeMiKaL GeNeRaL Denton
nie zadziała, aby uzyskać dokładny kolor, zawsze jest to jakaś mieszanka między kolorem oryginalnym a nowym.
swisswiss
takie podejście nieznacznie zniekształca obraz i pogarsza się po każdym zastosowaniu cienia. Podobnie jak w przypadku kopiowania, wyniki różnią się od oryginału.
SMAG
8

Znalazłem to podczas korzystania z Google'a, najlepiej dla mnie działało ...

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
źródło
To działa, głosowałem w górę. Ale tylko dla nagrania ma pewne problemy, takie jak nie można ustawić rozmiaru obrazu tła, nie można ustawić obrazu i się powtarza.
Daniel,
Ohh, naprawdę nie próbowałem tych ... spróbuj poniżej linku. developer.mozilla.org/en-US/docs/Web/CSS/-webkit-mask-box-image podziękowania, Daniel
Muthukumar Anbalagan
7

Wymagałem określonego koloru, więc filtr nie działał dla mnie.

Zamiast tego stworzyłem div, wykorzystując wiele obrazów tła CSS i funkcję gradientu liniowego (która tworzy sam obraz). Jeśli użyjesz trybu mieszania nakładki, rzeczywisty obraz zostanie zmieszany z wygenerowanym obrazem „gradientowym” zawierającym pożądany kolor (tutaj # 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
źródło
Nie działało dla mnie. Nie umiem powiedzieć, dlaczego dokładnie
wkleiłem
@VicSeedoubleyew snippet działa dobrze. Sprawdź swoją div za pomocą narzędzi programistycznych, aby upewnić się, że CSS jest rzeczywiście stosowany. Upewnij się również, że adres URL Twojego obrazu jest prawidłowy, jeśli nie używasz tego, który podałem. EDYCJA: Jeśli fragment kodu nie działa, być może używasz przeglądarki, która jest nieaktualna lub nie obsługuje funkcji gradientu liniowego.
rolznz
5

Odpowiadając, ponieważ szukałem rozwiązania tego problemu.

pióro w odpowiedzi @chrscblls działa dobrze, jeśli masz białe lub czarne tło, ale moje nie. Również obrazy zostały wygenerowane za pomocą ng-repeat, więc nie mogłem mieć ich adresu URL w moim css ORAZ nie możesz używać :: after na tagach img.

Tak więc wymyśliłem coś dookoła i pomyślałem, że może to pomóc ludziom, jeśli oni też się tutaj potkną.

Więc to, co zrobiłem, jest prawie takie samo z trzema głównymi różnicami:

  • URL jest w moim tagu img, umieszczam go (i etykietę) w innym div, na którym będzie działać :: after.
  • „tryb mieszania-mieszania” jest ustawiony na „różnicę” zamiast na „mnożenie” lub „ekran”.
  • Dodałem :: before z dokładnie taką samą wartością, więc :: after zrobiłoby „różnicę” z „różnicy” dokonanej przez :: before i sam się anulowałem.

Aby zmienić kolor z czarnego na biały lub z białego na czarny, kolor tła musi być biały. Od czerni po kolory, możesz wybrać dowolny kolor. Od bieli do kolorów, musisz wybrać kolor przeciwny do tego, który chcesz.

.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
źródło
3

Nie potrzebujesz całego zestawu czcionek, jeśli potrzebujesz tylko jednej ikony, a ponadto uważam, że jest bardziej „czysty” jako pojedynczy element. W tym celu w HTML5 można umieścić plik SVG bezpośrednio w obiegu dokumentów. Następnie możesz zdefiniować klasę w arkuszu stylów .CSS i uzyskać dostęp do jej koloru tła za pomocą fillwłaściwości:

Działające skrzypce: http://jsfiddle.net/qmsj0ez1/

Zauważ, że w tym przykładzie :hoverzilustrowałem zachowanie; jeśli chcesz tylko zmienić kolor dla stanu „normalnego”, powinieneś usunąć pseudoklasę.

Pere
źródło
1

Aby dosłownie zmienić kolor, możesz dołączyć przejście CSS z filtrem -webkit, w którym gdy coś się dzieje, wywołujesz wybrany filtr -webkit. Na przykład:

img {
    -webkit-filter:grayscale(0%);
    transition: -webkit-filter .3s linear;
    }
img:hover 
    {
    -webkit-filter:grayscale(75%);
    }
beta208
źródło
1

Podczas zmiany obrazu z czarnego na biały lub z białego na czarny filtr obracania odcienia nie działa, ponieważ czarno-biały nie jest technicznie kolorami. Zamiast tego należy zmienić kolor czarno-biały (z czarnego na biały lub odwrotnie) za pomocą właściwości filtru odwracającego.

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

Samuel Stankiewicz
źródło
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>

Źródło: https://codepen.io/taryaoui/pen/EKkcu

Bashirpour
źródło