A napokban elég sokat olvastam a különböző css effektekről. Sokszor van, hogy a grafikus speciális effekteket pakol egy-egy képre és ezeket meg kellene próbálni a lehető legélethűbb módon visszaadni. Ilyen effekt a mai tejüveg effekt vagy angolul a frosted glass effect.
GIMP alatt készítettem egy mintát, hogy körülbelül milyennek kellene lennie a a végső képünknek.
Nekünk innen az 5 pixelnyi külső keret fog kelleni. Ez is egy olyan effekt, amit legtöbbször a kép túlvágásával érünk el, így ha módosul a háttér, változtatunk a környezeten, akkor a képet ismét körbe kell vágni, és ráadásul pngben kell elmentenünk, ami az átlátszóság miatt jóval nagyobb méretű lesz.
Tehát, most el kell dönteni, hogy mit használunk. Első körben teljesen CSS alapokon akartam megcsinálni blur filter
rel és CSS mask
kal, de a böngésző támogatottságunk még mindig nem teljes. Canvast is használhatnánk, de ahhoz javascript szükséges. Így marad az SVG, aminek a böngésző támogatottsága is jó.
Első körben szükségünk lesz a háttérre, ezt a fenti képhez hasonlóan be állítjuk, majd a középső elemet beformázzuk. Mivel a középső elemünk is kép, így kell egy overflow:hidden;
a kerekített elemre, hogy a kép ne lógjon ki a boxból.
HTML:
<div class="background">
<img src="http://lorempixel.com/640/480/nature/5/">
<div class="rounded-center">
<img src="http://lorempixel.com/200/200/city/9/">
</div>
</div>
CSS:
.background {
position: relative;
}
.rounded-center {
background: #fff;
border-radius: 50%;
height: 200px;;
width: 200px;
position: absolute;
text-align: center;
overflow:hidden;
left: 220px;
top: 140px
}
A külső div
nek mindig meg kell kapnia a position: relative;
css-t egyébként, ha egy oldal kódjába illesztjük be, az absolute
pozicionált elemünk a body
hoz fog pozicionálódni.
Így minden esetben a div.background
közepére fog kerülni az elem.
Ez lesz a szórakoztatóbb, a fenti kódot szerintem bárki meg tudná csinálni, aki már készített weboldalt és kicsit beleásta magát a CSS-be.
Tehát most alakítjuk ki az SVG elemünket. Ehhez három dologra lesz szükségünk, magára a háttérre, a filterre és a maszkra. Kicsit ehhez szétbontom a htmlt, hogy könnyebb legyen értelmezni.
A háttér
<div class="background">
...
<svg class="frosted-glass">
<image id="background-image" width="640" height="480" xlink:href="http://lorempixel.com/640/480/nature/5/" />
</svg>
...
</div>
Hozzá tartozó css
.frosted-glass {
height: 100%;
left: 0;
position: absolute;
top: 0;
width: 100%;
}
Tehát az SVG hátterünket pozicionáljuk a bal felső sarokba és legyen ugyanakkora méretű, mint a háttérnek használt képünk.
A filter
<div class="background">
...
<svg class="frosted-glass">
...
<filter id="background-blur">
<feGaussianBlur stdDeviation="10" />
</filter>
...
</svg>
...
</div>
Hozzá tartozó css
#background-image {
filter:url(#background-blur);
}
Ezzel egy Gaussian-blur effektet hoztunk létre, mely 10 pixeles és CSS-sel engedélyezzük az SVG-ben létrehozott háttérképünkön.
Jöhet a végső lépés:
A maszk
<div class="background">
...
<svg class="frosted-glass">
...
...
<clipPath id="background-mask">
<circle cx="320" cy="240" r="105" />
</clipPath>
...
</svg>
...
</div>
A clipPath
elemünk fogja meghatározni a maszkunkat. Jelenleg, mivel a képünk 200 px széles középen, és a tervben 5 px a túlnyúlás, így 105 px a kör sugara (r)
, és az x
, y
koordináta természetesen az alap háttérkép közepére kerül.
Néhány apróság van már csak hátra. Kicsit ki kell bővítenünk a SVG hátterünket, hogy a maszkot használja:
Bővített háttér
<image id="background-image" width="640" height="480" xlink:href="http://lorempixel.com/640/480/nature/5/" clip-path="url(#background-mask)" />
Ha a hátterünk sok semleges részt tartalmaz, egyszínű részek, égbolt, hasonlók, akkor előfordul, hogy az elmosásunk beleolvad a hátterébe.
Erre egy egyszerű css trükköt alkalmazunk:
#background-image {
filter:url(#background-blur);
-webkit-transform: translate(-80px, -80px);
transform: translate(-80px, -80px);
}
#background-mask {
-webkit-transform: translate(80px, 80px);
transform: translate(80px, 80px);
}
A háttérképet eltoljuk CSS-sel transform
ot használva, majd a maszkot ellensúlyozzuk egy ellentétes eltolással. Így már sokkal jobban néz ki.
Azért választottuk ezt a megoldást, mert a böngészők jobban támogatják, mint a CSS filtereket. De az SVG támogatás csak az Internet Explorer 9-es verziójában került be, az SVG filterek pedig csak az Internet Explorer 10-től támogatott.
Tehát IE9 alatt nem működik majd az effektünk. De csak úgy nem hagyhatjuk, - bár szívem szerint azt tenném - így sajnos kompromisszumot kell kötnünk. Az effektünk nem ugyanazt fogja visszaadni IE9 alatt, de nem csak egy körülvágott képet, vagy egy kört mutatunk nekik.
A trükkhöz szükségünk van a modernizr-re, így meghatározhatjuk, hogy az adott böngésző támogatja-e az SVG filtereket. Ha nem tudjuk a filtert alkalmazni, akkor egy egyszerű rgba border készítünk az elemre. Tudom-tudom, nem épp a legjobb, de mint említettem, kompormisszumot kell kötnünk.
Tehát a css
.no-svgfilters #background-image {
display: none;
}
.no-svgfilters .rounded-center {
border: 5px solid rgba(255,255,255,.6);
background-clip: padding-box;
}
Ezután Internet Explorerben ezt kapjuk:
És persze nem maradhat el a szokásos DEMO oldal sem, ahol megnézheted a forrást is. A kész oldalra én még feltettem egy box-shadow
t is, így még eléggé hasonlít az eredetileg megtervezett képre.