CSS Filter funkcije

U CSS-u ostoji poseban atribut filter koji koristimo kada želimo da primenimo neki od specijalnih efekata (filtera) na neki elemenat. Filteri predstavljaju algoritamske transformacije slike. Sa njima se obično srećemo u softverskim alatima za obradu slike, poput Adobe Photoshopa. Najčešće je u pitanju manipulacija bojama, ali filteri mogu služiti i za generisanje proceduralnog grafičkog sadržaja (npr. lens flare, clouds, mosaic tiles i sl. efekti) ili manipulaciju pikselima (npr. blur, sharpen, offset, twirl...)

CSS za sada prepoznaje desetak osnovnih filtera, koji se uglavnom svode na kolor manipulaciju. U softverima za rad sa grafikom, većina ovih efekata i nisu zaista filteri, već prosto komande za obradu slike.

brightness() Promena osvetljenosti - boje se mogu posvetliti ili zatamniti
contrast() Promena kontrasta - kontrast je moguće smanjiti ili povećati
saturate() Promena zasićenosti boja - sliku je moguće učiniti drečavom ili potpuno izbledeti boje
hue-rotate() Promena nijanse (hue) boje - promena nijanse boja po kolornom krugu
invert() Inverzija boja - efekat foto-negativa
grayscale() Prevođenje boja u sive tonove - efekat crno-bele slike
sepia() Prevođenje boja u sepia tonove - efekat "stare fotografije"
drop-shadow() Efekat senke - element ili slika bacaju senku
opacity() Providnost - elemenat ili sliku je moguće učiniti poluprovidnom
blur() Efekat zamućenja - elemenat ili sliku je moguće "zamagliti"

Nabrojane CSS funkcije se zadaju preko atributa filter i odnose se na ceo elemenat (za sada je nemoguće primeniti filter samo npr. na pozadinu elementa). Takođe je moguće zadati više filter funkcija, s tim što se njihov efekat primenjuje od prve ka poslednjoj.

Još jedan atribut koji "prima" filter funkcije je backdrop-filter. Ovim atributom definišemo efekat koji će se primeniti na sve ono što se nalazi "iza" samog elementa. Ovo obično podrazumeva da element "prekriva" neke druge elemente (npr. ako je apsolutno pozicioniran) ili sliku u pozadini. Takođe, ovo ima smisla samo ako je sam element na nekim mestima providan ili bar poluprovidan (kako bi se videlo ono što je iza njega).

filter: filter-funkcija(); filter: filter-funkcija() filter-funkcija() ...; backdrop-filter: filter-funkcija(); backdrop-filter: filter-funkcija() filter-funkcija() ...;

Inače, atributi filter i backdrop-filter mogu biti animirani. Više o ovome pogledajte na kraju teksta.

Hajde sada da vidimo ono najzanimljivije - kako ovi efekti izgledaju. Možete se odmah baciti na isprobavanje. U ovom primeru smo objedinili sve filtere.

css-filter-probe-sr

brightness()
contrast()
saturate()

Najpre ćemo proći kroz osnovne tri CSS filterske funkcije, kojima se vrši korekcija boja.

Funkcija brightness() služi za promenu svetline boja. Kao parametar se navodi numerička vrednost ili adekvatni procenat koji predstavlja nivo osvetljenosti:

filter: brightness(1.3); --- JE ISTO KAO --- filter: brightness(130%);

Ne postoji neka unepred definisana maksimalna vrednost ili vrednost na kojoj će slika postati potpuno "bela" (to suštinski zavisi i od originala).

Pomoću funkcije contrast() vršimo podešavanje kontrasta slike, odnosno elementa. Vrednost takođe može biti numerik ili procenat:

Najzad, podešavanje zasićenosti boja postižemo pomoću funkcije saturate(). Vrednost i ovde može biti numerik ili procenat:

Primer za osnovnu manipulaciju bojama

Ovde vidimo primere kako izgleda osnovna kolor-manipulacija. Ono što je zajedničko za ove tri CSS funkcije je što se na osnovu vrednosti parametra rezultat može kretati u dva smera. Znači slika može biti zatamnjena ili posvetljena, sa smanjenim ili pojačanim kontrastom, sa sivljim ili drečavijim bojama.

Kod sve tri funkcije se "umanjenje" postiže vrednostima između 0 i 1, a "uvećanje" vrednostima preko 1. Vrednost 1 je "neutralna", odnosno ne izaziva promenu.

Autor sličice koju smo koristili u primerima je David Revoy, a preuzeta je sa njegovog open-source strip projekta Pepper and Carrot.


<style>
  div {
    background-size: cover; 
    background-image: url("img/pic-pepper-and-carrot-stare.jpg");
  }
  
  .bright-1 { filter: brightness(0.4); }
  .bright-2 { filter: brightness(1); }
  .bright-3 { filter: brightness(1.8); }
  
  .cont-1 { filter: contrast(0.3); }
  .cont-2 { filter: contrast(1); }
  .cont-3 { filter: contrast(2); }
  
  .sat-1 { filter: saturate(30%); }
  .sat-2 { filter: saturate(100%); }
  .sat-3 { filter: saturate(200%); }
</style>
<div class="bright-1"> brightness(0.4) </div> <div class="bright-2"> brightness(1) (Original) </div> <div class="bright-3"> brightness(1.8) </div> <div class="cont-1"> contrast(0.3) </div> <div class="cont-2"> contrast(1) (Original) </div> <div class="cont-3"> contrast(2) </div> <div class="sat-1"> saturate(30%) </div> <div class="sat-2"> saturate(100%) (Original) </div> <div class="sat-3"> saturate(200%) </div>

Možemo videti kako izgledaju rezultati ovih funkcija.

p1

hue-rotate()

Kao što znamo, ceo spektar boja, odnosno nijansi može se predstaviti kolornim krugom. Dakle možemo krenuti od crvene, preko narandžaste do žute, odatle preko zelene do plave, da bismo preko ljubičaste opet stigli do crvene. To je upravo ono što vidimo na slici.

Kolorni krug nijansi / Hue color wheel
Kolorni krug nijansi sa obeleženim stepenima

Šta je onda "rotiranje" kroz nijanse? Pogledajte ponovo sliku. Recimo da vršimo rotaciju boja za 90o:

Upravo takvu kolor-rotaciju obavlja funkcija hue-rotate(). Dakle, kao parametar se zadaje ugao predstavljen u npr. stepenima (deg) ili obrtajima (turn). Pri tom je npr. ugao od 90o izražen kao 90deg (90 stepeni) ili 0.25turn (četvrtina obrta).

Ugao može biti i negativan. Na primer, ugao od -60o je isti kao 300o, ili u obrtajima, npr. -0.15turn je isto kao 0.85turn.

Ako navedemo vrednost 0deg (isto i 360deg) ili 0turn (isto kao 1turn), to je onda jednako originalnom izgledu slike.

Pomoću ove funkcije možemo neznatno promeniti nijanse na slici ili učiniti da izgleda potpuno "vanzemaljski".

Primer za promenu nijanse

Ovde imamo jedan osnovni primer gde smo izvrteli pun krug i od originala, preko nekih 5 koraka promena, stigli opet do originala.


<style>
  div {
    background-size: cover; 
    background-image: url("img/pic-pepper-and-carrot-stare.jpg");
  }
  
  .hue-1 { filter: hue-rotate(0turn); }
  .hue-2 { filter: hue-rotate(0.2turn); }
  .hue-3 { filter: hue-rotate(0.4turn); }
  .hue-4 { filter: hue-rotate(0.6turn); }
  .hue-5 { filter: hue-rotate(0.8turn); }
  .hue-6 { filter: hue-rotate(1turn); }
</style>
<div class="hue-1"> hue(0turn) (Original) </div> <div class="hue-2"> hue(0.2turn) </div> <div class="hue-3"> hue(0.4turn) </div> <div class="hue-4"> hue(0.6turn) </div> <div class="hue-5"> hue(0.8turn) </div> <div class="hue-6"> hue(1turn) (Original) </div>

Ovde vidimo kako ovaj efekat funkcioniše:

p3

Colorize efekat

Ok, znamo da još nismo stigli do sepia() funkcije, ali evo primera kako kombinovanjem te funkcije sa hue-rotate() možemo da dobijemo "colorize" ili makar sličan efekat, kada se cela slika prebaci u monohromatske nijanse neke boje.


<style>
  div {
    background-size: cover; 
    background-image: url("img/pic-pepper-and-carrot-stare.jpg");
  }
  
  .hue-1 {
    filter: sepia(100%) hue-rotate(-0.3turn) saturate(80%);
  }
  .hue-2 {
    filter: sepia(100%) hue-rotate(0turn);
  }
  .hue-3 {
    filter: sepia(100%) hue-rotate(0.3turn) saturate(80%);
  }
</style>
<div class="hue-1"> hue(-0.3turn) </div> <div class="hue-2"> hue(0turn) (Sepia) </div> <div class="hue-3"> hue(0.3turn) </div>

Za ovo nam je upravo i trebao sepia() filter, pošto on ne uklanja boje već ih upravo svodi na monohromatske nijanse. Posle toga ostaje samo da "izvrtimo" boje kako bismo postigli drugu nijansu. Za ovo nam ne bi značio grayscale(1) ili saturate(0), pošto tada nema boja koje bismo mogli da "vrtimo".

p3a

invert()
grayscale()
sepia()

Sad ćemo objasniti tri funkcije koje služe za primenu određenog kolornog efekta. Za sve tri funkcije, kao parmetar se navodi numerička vrednost od 0..1 ili procenat (0% do 100%). Vrednost 0 označava situaciju kada nema efekta, odnosno sliku koja je jednaka originalu. Vrednost 1 (ili 100%) predstavlja maksimalnu primenu efekta. Svaka druga vrednost predstavlja neku "međufazu".

Šta rade ove funkcije? Funkcija invert() "obrće" boje na slici, odnosno praktično kreira negativ slike. Svaka međufaza predstavlja neki od prelaza od originalne do "negativne" slike. Tako, sticajem okolnosti, srednja vrednost od 0.5 generiše "ravnu" sivu sliku.

Funkcija grayscale() stvara crno-belu verziju slike, odnosno sliku sastavljenu samo od sivih nijansi. Praktično isti efekat dobijamo kompletnom desaturizacijom, odnosno korišćenjem filtera saturate(0). Svaka međufaza vrednosti od 0..1 predstavlja sve "sivlju" sliku, dok se boje potpuno ne izgube.

Treća funkcija, sepia() stvara efekat "stare fotografije" tako što svodi sliku na žućkaste monohromatske nijanse. Slično kao kod funkcije grayscale(), međufaze između 0..1 polako umanjuju boje i idu ka monohromatskoj slici.

Primer za efekat promene boje

U ovom primeru isprobavamo manipulaciju bojama slike koristeći specijalne efekte. Sve tri funkcije imaju vrednost od 0..1, gde 0 predstavlja originalnu sliku (efekat se ne primenjuje) a 1 predstavlja maksimalnu primenu efekta.


<style>
  div {
    background-size: cover; 
    background-image: url("img/pic-pepper-and-carrot-stare.jpg");
  }
  
  .inv-1 { filter: invert(0); }
  .inv-2 { filter: invert(0.6); }
  .inv-3 { filter: invert(1); }

  .sep-1 { filter: sepia(0); }
  .sep-2 { filter: sepia(0.5); }
  .sep-3 { filter: sepia(1); }

  .gray-1 { filter: grayscale(0); }
  .gray-2 { filter: grayscale(0.5); }
  .gray-3 { filter: grayscale(1); }
</style>
<div class="inv-1"> invert(0) (Original) </div> <div class="inv-2"> invert(0.6) </div> <div class="inv-3"> invert(1) </div> <div class="sep-1"> sepia(0) (Original) </div> <div class="sep-2"> sepia(0.5) </div> <div class="sep-3"> sepia(1) </div> <div class="gray-1"> grayscale(0) (Original) </div> <div class="gray-2"> grayscale(0.5) </div> <div class="gray-3"> grayscale(1) </div>

Rezultat je sledeći:

p2

drop-shadow()
opacity()
blur()

Konačno dolazimo do pravih specijalnih efekata. Za razliku od svih do sada opisanih filter funkcija, ove funkcije se ne bave običnim podešavanjima boje, već zaista izvode neki efekat nad elementom.

Funkcija drop-shadow() kreira senku elementa. Na prvi pogled, deluje potpuno isto kao CSS atribut box-shadow. Čak su i parametri isti:

Međutim, filter kreira senku po mnogo kompleksnijem algoritmu. Dok box-shadow iscrtava senku samo na osnovu dimenzija i zaobljenosti objekta, filter drop-shadow() uzima u obzir i providnost elementa, kao i sve podelemente koji utiču na "siluetu" objekta.

Na sličan način bismo mogli da poistovetimo i filter funkciju opacity() sa CSS atributom opacity. Ova funkcija, kao i pomenuti atribut, kontroliše providnost elementa. Paramater funkcije je istovetan vrednosti atributa - u pitanju je numerička vrednost između 0..1 (funkciji se može zadati i procenat od 0% do 100% sa istim značenjem). Vrednost 0 označava potpuno providan objekat dok vrednost 1 označava objekat koji je potpuno vidljiv (nema transparencije). Sve međuvrednosti označavaju neki nivo poluprovidnosti.

Generalno, zavisno od web čitača, trebalo bi da se filter CSS funkcije iscrtavaju brže od adekvatnih CSS atributa, pošto bi (bar u teoriji) crtanje trebalo da se usmerava direktno na grafičku kartu.

Zaista, na prvi pogled nećemo uočiti razliku, sve dok ne uvežemo opacity() funkciju u "lanac" filtera. Tada ćemo primetiti da se ovako zadata providnost uzima u obzir za efekte koji su kasnije navedeni u filter atributu. Ovo se najbolje vidi ako posle poziva opacity() funkcije pozovemo drop-shadow(). Primetićemo da je senka uzela u obzir i poluprovidnost elementa.

Najzad imamo i funkciju blur() koja vrši zamućenje objekta. Za poznavaoce aplikacija za obradu slike, dovoljno je reći da ovom funkcijom primenjujemo Gaussian blur efekat. Kao parametar se zadaje metrika koja označava veličinu zamućenja, odnosno koliko piksela se "stapa". Što je ova vrednost veća, to je slika mutnija. Ako pokušamo da umesto metrike zadamo procenat, funkcija neće raditi.

Primer za specijalne efekte

Funkcija drop-shadow()

Hajde najpre da vidimo kako se ponaša filter drop-shadow() i kako se razlikuje u odnosu na CSS atribut box-shadow.


<style>
  aside {
    position: relative;
    width: 250px;
    height: 80px;
    background-color: #ffb;
    border: 2px solid black;
    box-sizing: border-box;
  }
  div {
    position: absolute;
    width: 100px;
    height: 20px;
    top: 15px;
    right: -30px;
    background-color: #fff;
    color: red;
    border: 2px solid red;
    font-size: 8pt;
  }
  .mod {
    background-color: transparent;
    border: 10px solid white;
  }
  .senka {
    box-shadow: 4px 4px 6px #000;
  }
  .senka-filter {
    filter: drop-shadow(4px 4px 6px #000);
  }
</style>

<aside class="senka"> 
  box-shadow 
  <div>Mali okvir</div>  
</aside>
<aside class="senka-filter"> 
  filter: drop-shadow()
  <div>Mali okvir</div>  
</aside>

<aside class="mod senka"> 
  box-shadow 
  <div>Mali okvir</div>  
</aside>
<aside class="mod senka-filter"> 
  filter: drop-shadow()
  <div>Mali okvir</div>  
</aside>
<br />
<aside> 
  <img src="/graf/prof-sandy-left.png" class="senka" width="150" >
</aside> 
<aside> 
  <img src="/graf/prof-sandy-left.png" class="senka-filter" width="150" >
</aside> 
  

Kapo što vidimo u primeru, senka se odnosi na veliki aside element. E, sad, obratite pažnju na senku kod div bloka, koji izviruje iz aside elementa. CSS atribut box-shadow kreira senku isključivo oblika elementa za koji je zadat, dok filter funkcija drop-shadow() uzima u obzir realan oblik, i na osnovu njegovih podelemenata - tako će senka biti nacrtana i za div blok.

U drugom primeru vidimo da funkcija drop-shadow() uzima u obzir i providne delove elementa, tako da suštinski može zameniti i text-shadow atribut.

Najzad, vidimo da drop-shadow() uzima u obzir i providnost slike.

p4

Funkcija opacity()

Pogledajmo sada kako funkcioniše filter opacity().


<style>
  aside {
    position: relative;
    width: 250px;
    height: 70px;
    background-color: #ffb;
    border: 2px solid black;
    box-sizing: border-box;
  }
  div {
    position: absolute;
    width: 100px;
    height: 20px;
    top: 25px;
    right: -30px;
    background-color: #fff;
    color: red;
    border: 2px solid red;
  }
  .atr-shadow {
    box-shadow: 4px 4px 6px #000;
  }
  .atr-opacity {
    opacity: 0.4;
  }
  .fun-shadow {
    filter: drop-shadow(4px 4px 6px #000);
  }
  .fun-opacity {
    filter: opacity(0.4);
  }
  .fun-shadow-opacity {
    filter: drop-shadow(4px 4px 6px #000) opacity(0.4);
  }
  .fun-opacity-shadow {
    filter: opacity(0.4) drop-shadow(4px 4px 6px #000);
  }
</style>

<aside class="atr-opacity fun-opacity"> 
  opacity<br />filter: opacity()
  <div>DIV</div>  
</aside>
<aside class="atr-shadow atr-opacity"> 
  box-shadow<br />opacity
  <div>DIV</div>  
</aside>
<br />
<aside class="atr-shadow fun-opacity"> 
  box-shadow<br />filter: opacity()
  <div>DIV</div>  
</aside>
<aside class="atr-opacity fun-shadow">
  opacity<br />filter: drop-shadow()
  <div>DIV</div>  
</aside>
<br />
<aside class="fun-shadow-opacity"> 
  filter: drop-shadow() opacity()
  <div>DIV</div>  
</aside>
<aside class="fun-opacity-shadow"> 
  filter: opacity() drop-shadow()
  <div>DIV</div>  
</aside>
<br />
<aside class="atr-opacity"> 
  opacity
  <div class="atr-opacity">opacity</div>  
</aside>
<aside class="fun-opacity"> 
  filter: opacity()
  <div class="fun-opacity">filter: opacity()</div>  
</aside>

Ovde se vidi da je CSS funkcija opacity() veoma slična atributu opacity. Međutim, možemo primetiti dva efekta koji predstavljaju specifičnost korišćenja funkcije. Najpre, u prvom primeru primećujemo da ako na element primenimo i atribut opacity i filter opacity(), dobijamo pojačanu providnost elementa. To znači da jednu ili drugu stvar možemo koristiti kao "korekciju" ranije zadate providnosti, bez menjanja "originala".

Druga značajna stvar se primećuje kada "ulančavamo" funkciju opacity() sa drugim funkcijama u atributu filter. Najočiglednije je kada je to funkcija drop-shadow(). Vidimo da je jedini slučaj kada je poluprovidnost uzeta u obzir pri iscrtavanju senke (koja se onda providi kroz element) onaj u kome je prvo zadata funkcija opacity() a posle nje funkcija drop-shadow().

p5

Funkcija blur()

Konačno dolazimo do potpuno originalne CSS filter funkicje - blur(), koja nema svoj pandan među CSS atributima.


<style>
  .blur-0 { filter: blur(0); }
  .blur-1 { filter: blur(1px); }
  .blur-2 { filter: blur(3px); }
  .blur-3 { filter: blur(5px); }
  .blur-4 { filter: blur(7px); }
  .blur-5 { filter: blur(10px); }
</style>
<aside><div class="blur-0"> </div> <span> blur(0)<br />(Original) </span> </aside> <aside><div class="blur-1"> </div> <span> blur(1px) </span> </aside> <aside><div class="blur-2"> </div> <span> blur(3px) </span> </aside> <aside><div class="blur-3"> </div> <span> blur(5px) </span> </aside> <aside><div class="blur-4"> </div> <span> blur(7px) </span> </aside> <aside><div class="blur-5"> </div> <span> blur(10px) </span> </aside>

Kao što se vidi, parametar je metrika i označava veličinu zamućenja. Što je ova vrednost veća, slika je mutnija. Pošto blur() zamućuje sve što se nalazi unutar elementa na koji se primenjuje, morali smo malo više da se potrudimo da bi se tekst iznad slika uopšte video. Koristili smo kontejner i dva apsolutno pozicionirana elementa unutar njega - jedan sa zamućenjem i jedan sa tekstom.

p6

Animacija i kombinacija filtera

Ostali smo vam dužni još objašnjenje vezano za animaciju filtera. Već smo rekli da atributi filter i backdrop-filter mogu biti animirani. To znači da možemo zadati kontinuiranu promenu tokom nekog vremena od jednog do drugog "stanja".

Međutim, postoji jedno ograničenje. Animacija će raditi samo ako smo i početni i završni izgled definisali na potpuno isti način - dakle, koristeći iste CSS funkcije, zadate istim redosledom. Jedino što sme da se menja su parametri funkcija.

Dakle, ovo bi moglo:

filter: brightness(50%) blur(5px); --- PRELAZI U --- filter: brightness(120%) blur(0);

Ali ovo ne bi prošlo:

filter: brightness(50%) blur(5px); --- NEĆE PREĆI U --- filter: brightness(120%); <-- NEDOSTAJE BLUR()! filter: brightness(50%) blur(5px); --- NEĆE PREĆI U --- filter: blur(0) brightness(120%); <-- DRUGAČIJI REDOSLED!

Primer - Animacija filtera

Ovde smo zadali tri jednostavna primera. Pređite mišem preko svakog elementa kako biste videli animirani efekat.


<style>
  .primer-1 {
    filter: grayscale(100%) brightness(60%);
    transition-duration: 0.5s;
    transition-property: filter;
  }
  .primer-1:hover {
    filter: grayscale(0%) brightness(120%);
  }

  .primer-2 {
    filter: brightness(160%) blur(5px);
    transition-duration: 0.5s;
    transition-property: filter;
  }
  .primer-2:hover {
    filter: brightness(1) blur(0);
  }
  
  .primer-3 {
    filter: hue-rotate(180deg) contrast(1.7);
    transition-duration: 0.5s;
    transition-property: filter;
  }
  .primer-3:hover {
    filter: hue-rotate(0deg) contrast(1);
  }
</style>
<div class="primer-1"> Pređite mišem! </div> <div class="primer-2"> Pređite mišem! </div> <div class="primer-3"> Pređite mišem! </div>
p1a
  1. Mozilla Developer Network, Filter
  2. Quackit, CSS Functions
  3. S. Greig (2013): CSS3 Pushing the Limits, Wiley, Chichester
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.