CSS kolorno miksovanje - blend modovi

Efekat kolornog miksovanja, tj. CSS blending, služi da odredimo način na koji će se kreirati prikaz kada imamo jedan elemenat preko drugog. Ovo je prilično česta pojava, pošto praktično uvek imamo situaciju u kojoj se element nalazi unutar nekog drugog ("kontejnerskog") elementa ili se zahvaljujući pozicioniranju, preklapa sa drugim elementima.

Uobičajena situacija je da element ili makar njegov tekst "pokriva" ono što se nalazi ispod. Osnovni način na koji možemo videti neko mešanje boja elementa u prvom planu i elementa u pozadini je zadavanjem stepena providnosti, atributom opacity. Providnost se može zadati i unutar rgba() kolorne vrednosti, a takođe i PNG ili SVG slike mogu imati poluprovidne delove. U tom slučaju se rezultujući prikaz dobija prostim uprosečavanjem boja na tim polu-providnim mestima.

Međutim, ovo je samo vrh ledenog brega. CSS omogućava kolorno miksovanje koje je slično efektima za kombinovanje slojeva (layers) u programima za obradu grafike, poput Photoshopa. Ovo su tzv. blend-modovi, koji su nam dostupni:

normal bez primene ikakvog efekta - gornja boja prosto ide preko donje
multiply efekat preklapanja obojenih folija
screen efekat projektovanja više preklapajućih slika
overlay kombinacija multiply i screen zavisno od intenziteta donje boje
darken kombinacija tamnijih nijansi
lighten kombinacija svetlijih nijansi
color-dodge "agresivni" screen efekat
color-burn "agresivni" multiply efekat
hard-light snažno osvetljenje - overlay sa obrnutim bojama
soft-light slabije osvetljenje
difference boje se mešaju oduzimanjem
exclusion difference efekat sa slabijim kontrastom
hue preuzimanje nijanse
saturation preuzimanje zasićenosti
color kombinacija hue i saturation efekata
luminosity preuzimanje osvetljenosti

Svaki od ovih efekata predstavlja algoritam, odnosno matematičku operaciju koja se vrši nad bojama svakog piksela elementa za koji je zadat. U daljem tekstu ćemo elemenat koji "ide preko" nazivati "gornji" a elemenat koji se nalazi u pozadini i sa kojim se vrši mešanje boja ćemo nazivati "donji". Inače, blending mod se uvek zadaje gornjem elementu. Moguće su i kombinacije različitih blending modova kada imamo više preklapajućih elemenata.

Za razliku od CSS filter-funkcija, ovde ne možemo podesiti intenzitet "primene" efekta, kao što ni sama kolorna miksovanja ne mogu biti animirana. Međutim, ako se setimo da elementi mogu imati promenljiv opacity, dolazimo do "zaobilaznog" načina kako bismo zadali intenzitet efekta - koliko je elemenat vidljiv ili providan, definiše i koliko "snažno" će biti primenjen efekat. Uz to, opacity može biti animiran.

Blending modove možemo zadati pomoću dva atributa:

Atribut mix-blend-mode se zadaje elementu kako bi se definsalo kako će se preklapati boje tog elementa sa bilo čime što se nalazi u njegovoj pozadini. To može biti boja pozadine ili pozadinska slika kontejnerskog elementa, ali isto tako i neki sasvim drugi elementi, pošto je elemenat moguće pozicionirati npr. apsolutno ili fiksno.

mix-blend-mode: blend-mod

Drugi atribut - background-blend-mode se odnosi na međusobno miksovanje slika u pozadini, zadatih grupom background atributa. Ovom atributu je moguće zadati i čitavu listu blending modova, ako imamo više slika u pozadini. Ovo važi i za klasične unapred pripremljene slike, kao i za proceduralne gradiente.

background-blend-mode: blend-mod background-blend-mode: blend-mod, blend-mod, blend-mod, ...

Blend modovi ukratko

U ovom odeljku ćemo se pozabaviti matematičkim transformacijama koje stoje iza svakog blending moda.

normal
multiply
screen
overlay

Efekat multiply se dobija množenjem kolornih vrednosti donje i gornje boje. Šta to u stvari znači? Kao što znamo svaka boja se sastoji iz tri komponente - crvene, zelene i plave (RGB sistem boja). Kada se kombinuju dve boje, računar svaku od RGB komponenti (koje imaju vrednosti u rasponu od 0 do 255) preračuna u raspon od 0 do 1. Onda se sa tim vrednostima obavljaju matematičke operacije, zavisno od toga kakav efekat treba da se postigne.

Kao što smo rekli, kolorne komonente se kod multiply efekta, množe. Dakle, ako sa 0 obeležimo kolornu komponentu donje boje, a sa 1 kolornu komponentu gornje boje, onda se nova boja dobija međusobnim množenjem svake komponente:

R = r0 * r1 G = g0 * g1 B = b0 * b1

Pošto se svaka komponenta računa na potpuno isti način, ne moramo da pišemo sve tri formule, već samo jednu, koja važi za svaku komponentu:

multiply C = c0 * c1

Logično, pošto vrednost 0.0 (najtamnija) anulira bilo šta sa čime se pomnoži, a vrednost 1.0 (najsvetlija) ne utiče na bilo šta sa čime se pomnoži, dolazimo do rezultata multiply efekta - crna boja uvek zacrnjuje, bela nema efekat - kao kada preklapamo dve providne folije.

Da se vratimo sada korak unazad - kada ne zadamo nikakvo kolorno miksovanje, podrazumevana vrednost je normal. To znači da gornja boja potpno prekriva donju - nema mešanja, nema nikakve kombinacije ni matematike:

normal C = c1

Naravno, u slučaju da postoji zadata određena poluprovidnost preko atributa opacity, tada se gornja i donja boja uprosečavaju - zavisno od vrednosti:

normal C = (1-o1)*c0 + o1*c1

Na isti način, preko opacity vrednosti, možemo kontrolisati "intenzitet" multiply efekta. Formula bi glasila:

multiply C = (1-o1)*c0 + o1*c0*c1

Nije nam ideja da toliko detaljno ulazimo u matematiku - formule nam služe samo da ilustrujemo ideju koja stoji iza svakog kolornog miksovanja, pa ćemo ubuduće da zanemarimo opacity vrednost.

Efekat screen je zamišljen kao suprotnost multiply efektu. Originalna i nova boja se invertuju, zatim se množe i dobijena boja ponovo invertuje.

screen C = 1 - (1-c0) * (1-c1)

Crna boja nema efekat, a bela uvek "zabeljuje" - kao kada dve slike projektujemo jednu preko druge na belom platnu.

Konačno, efekat overlay predstavlja kombinaciju multiply i screen efekta. Ako je donja boja tamna, radi se multiply, a screen ako je svetla (gleda se da li je ispod ili iznad polovine mogućeg intenziteta).

overlay C = (c0 < 0.5) ? (c0 * c1) : (1 - (1-c0) * (1-c1))

darken
lighten

Vrednost darken suštinski kombinuje tamnije nijanse obe boje. Boja se dobija tako što se za svaku RGB kolornu komponentu gornje i donje boje, izabere manja (tamnija) vrednost.

darken C = (c0 < c1) ? c0 : c1

Logično, postojaće i suprotna blend vrednost - lighten kod koje se boja dobija tako što se pri upoređivanju donje i gornje boje, uvek bira veća (svetlija) vrednost.

ligten C = (c0 > c1) ? c0 : c1

color-dodge
color-burn

Ovi efekti spadaju među najupečatljivije. Efekat color-dodge je sličan screen vrednosti, samo što je ukupan efekat "agresivniji". Dobija se kada se vrednost donje boje podeli invertovanom vrednošću gornje boje.

color-dodge C = c0 / (1-c1), za c0 == 0, C = 0, za c1 == 1, C = 1

Slično tome, efekat color-burn podseća na multiply, samo još snažniji - sa jačim kontrastima i bojama. Donja boja se invertuje, zatim deli vrednošću gornje boje, pa se dobijena vrednost ponovo invertuje:

color-burn C = 1 - (1-c0) / c1, za c0 == 1, C = 1, za c1 == 0, C = 0

hard-light
soft-light

Efekat hard-light je matematički veoma sličan overlay efektu - praktično to overlay samo kada bismo obrnuli gornju i donju boju. Ako je gornja boja tamna, radi se multiply, a screen u suprotnom. Krajnji efekat je kao da smo usmerili snažno svetlo sa novom slikom ka originalnoj pozadini.

hard-light C = (c1 < 0.5) ? (c0 * c1) : (1 - (1-c0) * (1-c1))

Efekat soft-light (iako matematički dosta drugačiji) se po rezultatu može opisati kao hard-light slabijeg intenziteta. Formula je verovatno najkomplikovanija od svih...

soft-light C = (c1 <= 0.5) ? c0 - (1 - 2*c1) * c0 * (1-c0) : c0 + (2*c1 - 1) * (d0-c0) gde se d0 računa kao: d0 = (c0 <= 0.25) ? ((16 * c0 - 12) * c0 + 4) * c0 : sqrt(c0)

difference
exclusion

Kod efekta difference, tamnija boja se oduzima od svetlije. To znači da crna neće imati efekta, dok će bela invertovati drugu boju.

difference C = (c0 < c1) ? (c1 - c0) : (c0 - c1)

Efekat exclusion ima drugačiju formulu, ali rezultat izgleda kao difference sa umanjenim kontrastom.

exclusion C = c0 + c1 - 2*c0*c1

hue
saturation
color
luminosity

Ova četiri blend moda se računaju na potpuno drugačiji način od prethodnih. Pre svega, ne uzima se RGB kombinacija, već se posmatra HSL kolorni sistem. Takođe, ne radi se svaka komponenta na isti način, već se sada svaka komponenta računa drugačije. Kada se zada vrednost hue, koristi se nijansa (hue) gornje boje, a zasićenje i svetlina se uzimaju od donje boje:

hue H = h1 S = s0 L = l0

Slično tome, kod efekta saturation, koristi se zasićenje (saturation) gornje, a nijansa i svetlina donje boje:

saturation H = h0 S = s1 L = l0

Time efikasno možemo da podešavamo gde će boja biti intenzivnija (drečavija), a gde pastelnija (sivlja).

Blending mod color koristi zasićenje i nijansu gornje boje, a samo svetlinu donje, čime lako postižemo "monohromatski" efekat (slično kao propuštanje slike kroz jednobojni filter):

color H = h1 S = s1 L = l0

Najzad, efekat luminosity koristi svetlinu (luminosity) gornje, a nijansu i zasićenost donje boje:

luminosity H = h0 S = s0 L = l1

Ovim efektom možemo lako podesiti svetlije i tamnije delove slike.

Primeri kolornog miksovanja

Do sada smo se bavili teorijom, a sada ćemo videti kako blend-modovi funkcionišu u praksi.

Miksovanje pozadina - sivi gradijent

Najpre ćemo videti kako različite nijanse svtlo-tamno utiču na sliku u pozadini. Koristimo atribut background-blend-mode kako bismo kombinovali fotografiju u pozadini i sivi gradijent koji nanosimo iznad. Ovaj gradijent predstavlja prelaz od crne do bele boje, uz vidljivost 80%.


<style>
  .ef-multiply { background-blend-mode: multiply, normal; }
  .ef-screen { background-blend-mode: screen, normal; }
  .ef-overlay { background-blend-mode: overlay, normal; }
  .ef-darken { background-blend-mode: darken, normal; }
  .ef-lighten { background-blend-mode: lighten, normal; }
  .ef-color-dodge { background-blend-mode: color-dodge, normal; }
  .ef-color-burn { background-blend-mode: color-burn, normal; }
  .ef-hard-light { background-blend-mode: hard-light, normal; }
  .ef-soft-light { background-blend-mode: soft-light, normal; }
  .ef-difference { background-blend-mode: difference, normal; }
  .ef-exclusion { background-blend-mode: exclusion, normal; }
  .ef-hue { background-blend-mode: hue, normal; }
  .ef-saturation { background-blend-mode: saturation, normal; }
  .ef-color { background-blend-mode: color, normal; }
  .ef-luminosity { background-blend-mode: luminosity, normal; }

  .original {
    background-image: url("img/pic-angie.jpg");
/*    background-image: url("img/pic-girl-with-doll.jpg");  */
  }
  .primer-1 {
    background-image: 
      linear-gradient(90deg, rgba(0,0,0, 0.8), rgba(255,255,255, 0.8)),
      url("img/pic-angie.jpg");
  }
</style>
<div class="original"> Original </div> <div class="primer-1"> normal </div> <div class="primer-1 ef-multiply"> multiply </div> <div class="primer-1 ef-screen"> screen </div> <div class="primer-1 ef-overlay"> overlay </div> <div class="primer-1 ef-darken"> darken </div> <div class="primer-1 ef-lighten"> lighten </div> <div class="primer-1 ef-color-dodge"> color-dodge </div> <div class="primer-1 ef-color-burn"> color-burn </div> <div class="primer-1 ef-hard-light"> hard-light </div> <div class="primer-1 ef-soft-light"> soft-light </div> <div class="primer-1 ef-difference"> difference </div> <div class="primer-1 ef-exclusion"> exclusion </div> <div class="primer-1 ef-hue"> hue </div> <div class="primer-1 ef-saturation"> saturation </div> <div class="primer-1 ef-color"> color </div> <div class="primer-1 ef-luminosity"> luminosity </div>
pgrey

Izostavili smo CSS i HTML prikaz, da stranica ne bi bila preterano opterećena. Ako želite da vidite kako je sve ovo izvedeno, pogledajte primer.

css-blend-gray-sr

Miksovanje pozadina - kolorni gradijent

Ovde ćemo izvesti istu stvar, samo sa gradijentom u boji, da biste videli kako se različiti blending modovi ponašaju u tom slučaju.


<style>
  .ef-multiply { background-blend-mode: multiply, normal; }
  .ef-screen { background-blend-mode: screen, normal; }
  .ef-overlay { background-blend-mode: overlay, normal; }
  .ef-darken { background-blend-mode: darken, normal; }
  .ef-lighten { background-blend-mode: lighten, normal; }
  .ef-color-dodge { background-blend-mode: color-dodge, normal; }
  .ef-color-burn { background-blend-mode: color-burn, normal; }
  .ef-hard-light { background-blend-mode: hard-light, normal; }
  .ef-soft-light { background-blend-mode: soft-light, normal; }
  .ef-difference { background-blend-mode: difference, normal; }
  .ef-exclusion { background-blend-mode: exclusion, normal; }
  .ef-hue { background-blend-mode: hue, normal; }
  .ef-saturation { background-blend-mode: saturation, normal; }
  .ef-color { background-blend-mode: color, normal; }
  .ef-luminosity { background-blend-mode: luminosity, normal; }

  .original {
    background-image: url("img/pic-angie.jpg");
  }
  .primer-1 {
    background-image: 
      linear-gradient(90deg, rgba(255,128,0, 0.8), rgba(0,255,128, 0.8)),
      url("img/pic-angie.jpg");
  }
</style>
<div class="original"> Original </div> <div class="primer-1"> normal </div> <div class="primer-1 ef-multiply"> multiply </div> <div class="primer-1 ef-screen"> screen </div> <div class="primer-1 ef-overlay"> overlay </div> <div class="primer-1 ef-darken"> darken </div> <div class="primer-1 ef-lighten"> lighten </div> <div class="primer-1 ef-color-dodge"> color-dodge </div> <div class="primer-1 ef-color-burn"> color-burn </div> <div class="primer-1 ef-hard-light"> hard-light </div> <div class="primer-1 ef-soft-light"> soft-light </div> <div class="primer-1 ef-difference"> difference </div> <div class="primer-1 ef-exclusion"> exclusion </div> <div class="primer-1 ef-hue"> hue </div> <div class="primer-1 ef-saturation"> saturation </div> <div class="primer-1 ef-color"> color </div> <div class="primer-1 ef-luminosity"> luminosity </div>
pcolor

Tu je i urađen primer.

css-blend-color-sr

Miksovanje elemenata - tekst preko slike

Svrha ovog primera je da vidite kako se mogu miksovati boje elemenata koji se prikazuju jedni preko drugih. U tu svrhu koristimo atribut mix-blend-mode koji se zadaje elementu sa tekstom koji se nalazi iznad elementa sa slikom. Element u kome je tekst ima vidljivost 80%.


<style>
  .ef-multiply { mix-blend-mode: multiply; }
  .ef-screen { mix-blend-mode: screen; }
  .ef-overlay { mix-blend-mode: overlay; }
  .ef-darken { mix-blend-mode: darken; }
  .ef-lighten { mix-blend-mode: lighten; }
  .ef-color-dodge { mix-blend-mode: color-dodge; }
  .ef-color-burn { mix-blend-mode: color-burn; }
  .ef-hard-light { mix-blend-mode: hard-light; }
  .ef-soft-light { mix-blend-mode: soft-light; }
  .ef-difference { mix-blend-mode: difference; }
  .ef-exclusion { mix-blend-mode: exclusionl; }
  .ef-hue { mix-blend-mode: hue; }
  .ef-saturation { mix-blend-mode: saturation; }
  .ef-color { mix-blend-mode: color; }
  .ef-luminosity { mix-blend-mode: luminosity; }

  .kont {
    opacity: 0.8;
  }
  
  .original {
    background-image: url("img/pic-smederevo.jpg");
  }
  
  .t1 { color: #200; }
  .t2 { color: #ffd; }
  .t3 { color: #a6f; }
</style>
<div class="original">normal <div class="kont"> <p class="t1">TEXT</p> <p class="t2">TEXT</p> <p class="t3">TEXT</p> </div></div> <div class="original">multiply <div class="kont ef-multiply"> <p class="t1">TEXT</p> <p class="t2">TEXT</p> <p class="t3">TEXT</p> </div></div> <div class="original">screen <div class="kont ef-screen"> <p class="t1">TEXT</p> <p class="t2">TEXT</p> <p class="t3">TEXT</p> </div></div> <div class="original">overlay <div class="kont ef-overlay"> <p class="t1">TEXT</p> <p class="t2">TEXT</p> <p class="t3">TEXT</p> </div></div> <div class="original">darken <div class="kont ef-darken"> <p class="t1">TEXT</p> <p class="t2">TEXT</p> <p class="t3">TEXT</p> </div></div> <div class="original">lighten <div class="kont ef-lighten"> <p class="t1">TEXT</p> <p class="t2">TEXT</p> <p class="t3">TEXT</p> </div></div> <div class="original">color-dodge <div class="kont ef-color-dodge"> <p class="t1">TEXT</p> <p class="t2">TEXT</p> <p class="t3">TEXT</p> </div></div> <div class="original">color-burn <div class="kont ef-color-burn"> <p class="t1">TEXT</p> <p class="t2">TEXT</p> <p class="t3">TEXT</p> </div></div> <div class="original">hard-light <div class="kont ef-hard-light"> <p class="t1">TEXT</p> <p class="t2">TEXT</p> <p class="t3">TEXT</p> </div></div> <div class="original">soft-light <div class="kont ef-soft-light"> <p class="t1">TEXT</p> <p class="t2">TEXT</p> <p class="t3">TEXT</p> </div></div> <div class="original">difference <div class="kont ef-difference"> <p class="t1">TEXT</p> <p class="t2">TEXT</p> <p class="t3">TEXT</p> </div></div> <div class="original">exclusion <div class="kont ef-exclusion"> <p class="t1">TEXT</p> <p class="t2">TEXT</p> <p class="t3">TEXT</p> </div></div> <div class="original">hue <div class="kont ef-hue"> <p class="t1">TEXT</p> <p class="t2">TEXT</p> <p class="t3">TEXT</p> </div></div> <div class="original">saturation <div class="kont ef-saturation"> <p class="t1">TEXT</p> <p class="t2">TEXT</p> <p class="t3">TEXT</p> </div></div> <div class="original">color <div class="kont ef-color"> <p class="t1">TEXT</p> <p class="t2">TEXT</p> <p class="t3">TEXT</p> </div></div> <div class="original">luminosity <div class="kont ef-luminosity"> <p class="t1">TEXT</p> <p class="t2">TEXT</p> <p class="t3">TEXT</p> </div></div>
ptxt

Pogledajte na primeru kako je ovo urađeno.

css-blend-text-sr

Izazovi i rešenja

Kolorno miksovanje se može efikasno upotrebiti u svhu maskiranja. Na taj način npr. tekst može poslužiti kao maska za sliku radi postizanja određenog efekta. Prvi primer prikazuje jedan takav slučaj - kada se slika dovede u crno-belu verziju, a jedino što ostane u boji je tekst koji ide preko slike.

css-blend-komb-sr

Drugi primer je sličan, ali možda čak i atraktivniji - sliku koristimo kao teksturu kojom bojimo slova.

css-blend-komb2-sr

Znamo da blending modovi ne mogu biti animirani, ali isto tako znamo da njihov "intenzitet" možemo kontrolisati menjanjem providnosti elementa. U poslednjem primeru smo, koristeći tu tehniku, simulirali animaciju prelaska jednog blendinga u drugi.

css-blend-anim-sr
Svi elementi sajta Web'n'Study, osim onih za koje je navedeno da su u javnom vlasništvu, vlasništvo su autora i ne smeju se koristiti, u celosti ili delimično bez pismenog odobrenja autora. To uključuje tekstove, slike, ilustracije, animacije, prateći grafički materijal i programski kod.
Ovaj sajt koristi tehnologiju kolačića (cookies). Detaljnije o tome možete pročitati u tekstu o našoj politici privatnosti.