.container.blob.blob
#ex--basic-blobs .blob{/* dimensions */border-radius:50%;background:white;filter:blur(9px)}#ex--basic-blobs.container{/* layout */background:black;filter:contrast(27)}
.container.blob.blob
#ex--wrong-blobs .blob{/* dimensions */border-radius:50%;background:linear-gradient(#42033d,#ff9b54);filter:blur(9px)}#ex--wrong-blobs.container{/* layout */filter:contrast(27)}
blur()
and contrast()
basicsblur(0px)
preserves the input and so does contrast(1)
contrast()
doesn't affect the alpha channel
blur()
: grids!
4px×4px
element
3×3
weight grid
3×3 grid (Σ=4)
5×5 grid (Σ=16)
7×7 grid (Σ=64)
Grid Size(n) |
Vector | Weight Sum(2n-1) |
---|---|---|
1 |
|
1 |
2 |
|
2 |
3 |
|
4 |
4 |
|
8 |
5 |
|
16 |
6 |
|
32 |
7 |
|
64 |
8 |
|
128 |
9 |
|
256 |
blur()
consequencesfloor(n/2)
(semitransparent) pixelsfloor(n/2)
pixels from each edge inside original boundaries semitransparent (n
is the size of the weight grid)#ex--blur-prob .box{/* dimensions */background:linear-gradient(#42033d 25%,#ff9b54 0) 0/ 1% 20%}#ex--blur-prob .blur{filter:blur(9px)}
blur()
conclusionsbackground
background
on an element and then be able to somehow recover it post-blur< 1
0,255
interval0
⇒ always a fully grey
(that's a 50%
grey: hsl(h, 0%, 50%)
) element> 1
0,255
interval0
or 255
, such that we only have:#000
rgb(0,0,0)
black
#00f
rgb(0,0,255)
blue
#0f0
rgb(0,255,0)
lime
#0ff
rgb(0,255,255)
cyan
(aqua)
#f00
rgb(255,0,0)
red
#f0f
rgb(255,0,255)
fuchsia
(magenta)
#ff0
rgb(255,255,0)
yellow
#fff
rgb(255,255,255)
white
contrast()
consequences0
or 255
contrast()
conclusions0
or 255
8px×8px
element7×7
weight grida₀ + a₁ - a₀·a₁
<.5
,>.5
for example: .3 + .3 - .3·.3 = .6 - .09 = .51
background:white
#808080
, high contrast on container pushes it to black
white
<.5
means a grey darker than #808080
ch₀ + (ch₁ - ch₀)·a₁
multiply
and screen
0
is always 0
255 ➝ 100% ➝ 1
220,20,60 ➝ 86%,8%,24% ➝ .86,.08,.24
multiply
ch₀·ch₁
black
has all RGB channels 0
0
is 0
black
⇒ result also black
1
remains unchangedwhite
⇒ result identical to other layer's corresponding pixelmix-blend-mode:multiply
screen
multiply
(multiply ➝ AND, screen ➝ OR
)1
minus channel values, subtract all from 1
1 - (1 - ch₀)·(1 - ch₁)
white
has all RGB channels 1
white
➝ result pixel also white
1 - (1 - 1)·(1 - ch₁) = 1 - 0·(1 - ch₁) = 1
black
⇒ result identical to other layer's corresponding pixel1 - (1 - 0)·(1 - ch₁) = 1 - 1·(1 - ch₁) = ch₁
mix-blend-mode:screen
.group.panel.grd.panel.container.blob.blob.group.panel.img.panel.container.blob.blob
#ex--full-blobs .panel{/* basic styles */mix-blend-mode:multiply;transform:translatey(0)}#ex--full-blobs .group{/* basic styles */mix-blend-mode:screen;transform:translate(0)}
.container.iso.hollow.hollow
#ex--plain-hollow.container{/* basic styles */--bg:black;background:var(--bg)}#ex--plain-hollow .hollow{/* basic styles */border-color:white;background:var(--bg);mix-blend-mode:screen;mix-blend-mode:multiply} #ex--plain-hollow .iso{isolation:isolate}
.group.panel.grd.panel.container.iso.hollow.hollow.group.panel.img.panel.container.iso.hollow.hollow
#ex--full-hollow .hollow{filter:blur(5px)}#ex--full-hollow .container{filter:contrast(27)}#ex--full-hollow .panel{/* same as before */mix-blend-mode:multiply;transform:translatey(0)}#ex--full-hollow .group{/* same as before */mix-blend-mode:screen;transform:translate(0)}
linear-gradient(red,transparent)
alpha
masksmask
is, for each pixel, its initial background alpha multiplied with corresponding mask
pixel alphaa = aₑ·aₘ
[0, 1]
interval≤ 1
gives us a result that's ≤ smallest of the two valuesmask
is never bigger than beforemask
, but never lessblack
and the element is on top a white
one, visual result is grey, lighter or darker, depending on each top pixel's alpha.container: .halftone
#ex--halftone .halftone{/* inherit dimensions */background:radial-gradient(black,transparent)0 0/ var(--s) var(--s)repeat;mask:linear-gradient(red,rgba(0,0,0,1) 100%)}#ex--halftone.container{/* set dimensions */--s:2em;background:white;filter:contrast(27)}
mask-mode
mask-mode
only supported in Firefoxmask-mode: luminance
makes pixels corresponding to black
in the mask
fully transparent and those corresponding to white
fully opaquemask-type
in SVG also lets us switch between alpha
and luminance
mask-type
is applied on SVG <mask>
, while mask-mode
is applied on masked element#ex--img-blend.halftone::after{/* inherit dimensions */--s:1.25em;background:radial-gradient(black,white)0 0/ var(--s) var(--s)repeat;mix-blend-mode:screen}#ex--img-blend.halftone{filter:contrast(9)}#ex--img-blend.halftone::before{/* inherit dimensions */background:url(/img/portrait_tiger.jpg)50%/ cover;filter:grayscale(0) blur(0px)}
background: radial-gradient(black, white) 0 0/ .25em .25em repeat,
filter(url(tiger.jpg) 50%/ cover, invert(1) blur(2px));
background-blend-mode: screen;
filter: contrast(9)
Questions? Send them @anatudor