Is the 'Frosted Glass' Effect Implementable with CSS Only at This Time

Is the 'frosted glass' effect implementable with CSS only at this time?

What you are looking for is backdrop-filter, which has been in webkit since August 2015 (see post). It was shipped in Safari 9 (September 30, 2015, part of OS X El Capitan) and works in Chrome today by enabling the Experimental Web Platform features [...] flag.

With backdrop-filter, getting the 'live blur' is as easy as adding backdrop-filter: blur(10px) to a given element.

Demo here.

It's probably going to be a while until it becomes mainstream though, but it's going to enable us to do so much more than the frosted glass effect (i.e. night mode, read more here).
The good news is that tons of people are excited about it, so let's hope we don't have to wait long. If curios, here's the spec for it.

If you want to track progress on this feature, check out:

  • Mozilla bug
  • Chrome bug & Chrome status
  • Microsoft bug

Frosted glass effect using CSS for h2/h3 background area

I just googled "frosted glass effect" and the second result looked promising: https://css-tricks.com/frosting-glass-css-filters/. It links to codepen: http://codepen.io/adobe/pen/40cd4258f2d72a60f37a5e2f47124b7e

They use a blurred image for the blurry effect. Depending on the browsers you need to support you can use the CSS property filter instead. That way you only need to load the image you want to apply your effect to and not a second with the applied effect.

I made a fiddle for you: https://jsfiddle.net/hwvpch0u/1/

Basically it's mostly all about the following CSS:

.mycontainer {
background-image: url('<my-image>');
background-size: cover;
}
.mycontainer .glass {
/* all the properties for the "stand out" container */
}
.mycontainer .glass::before {
/*background-image: url('<my-blurry-image');*/ /* see: http://caniuse.com/#search=filter */
background-image: url('<my-iamge>');
-webkit-filter: blur(8px); /* blur only of original image is used instead of blurry */
filter: blur(8px); /* blur only of original image is used instead of blurry */
background-size: cover;
opacity: 0.4;
}


In your additionally added screenshot, I cannot see a blur effect. So if you don't need that, you can just apply an background-color having an alpha channel to the "frosted" container above the image, like:

.mycontainer .glass {
background-color: rgba(255, 255, 255, 0.5);
}

How to cover all but one div with frosted glass effect?

Note the new CSS I added, which excludes the <div> with a class of block3.

.wrapper {
display: block;
}

.block1 {
width: 100px;
height: 300px;
background-color: grey;
}

.block2 {
width: 100px;
height: 200px;
background-color: yellow;
}

.block3 {
width: 100px;
height: 50px;
background-color: green;
position: absolute;
top: 10%;
}

div.wrapper > div:not(.block3) {
filter: blur(10px);
}
<div class='wrapper'>
<div class='block1'>Block 1</div>
<div class='block2'>Block 2</div>
<div class='block3'>Block 3</div>
</div>

How to style the remaining space in Canvas

I assume this is real-time. You will need to create a 2 canvases to help with the FX.

The frosted glass is on one layer. To avoid setting the blur filter overhead the filter is left on at all times.

The second layer is the inset window. An ellipse is draw and then the image over that using composite operation "source-in" (only pixels set get changed)

The final step draws the two layers onto the canvas and then adds the border and highlights as ellipses.

The demo has a random image and animates its position (just to check performance as blur can be costly)

const ctx = canvas.getContext("2d");

ctx.fillText("Loading image please wait..", 10,20)

Math.TAU = Math.PI * 2;

const img = new Image;

img.src = "http://www.createjs.com/demos/_assets/art/flowers.jpg";

img.onload = () => {

// settings

const blurAmount = 12; // in pixels

const glassBlur = "blur(" + blurAmount + "px)"; // the blur filter

const glassColor = "#EEE";

const glassOpacity = 0.45;

const faceRadius2 = canvas.height * (1/4);

const faceRadius1 = canvas.width * (1/3);

const borderWidth = canvas.width * (1/25);

const insetBorderColor = "#999";

const highlightColor = "255,255,255";

// background image holds frosty glass

const bg = document.createElement("canvas");

bg.width = canvas.width;

bg.height = canvas.height;

bg.ctx = bg.getContext("2d");

bg.ctx.drawImage(img, 0, 0);

bg.ctx.filter = glassBlur; // IMPORTANT TO SET FILTER EARLY or will cause

// slowdown is done on the fly

// create the mask for the window

const windowMask = document.createElement("canvas");

windowMask.width = canvas.width;

windowMask.height = canvas.height;

windowMask.ctx = windowMask.getContext("2d");

// create the gradient for the highlights

const highlight = ctx.createLinearGradient(

0,

canvas.height / 2 - faceRadius1 + borderWidth,

0,

canvas.height / 2 + faceRadius1 - borderWidth,

);

highlight.addColorStop(0, "rgba("+highlightColor +",1)");

highlight.addColorStop(0.25,"rgba("+highlightColor +",0.4)");

highlight.addColorStop(0.5,"rgba("+highlightColor +",0)");

highlight.addColorStop(0.75,"rgba("+highlightColor +",0.4)");

highlight.addColorStop(1, "rgba("+highlightColor +",1)");

ctx.lineCap = "round"; // for the highlight

var x,y; //position of image for demo

// animate moving image

requestAnimationFrame(loop);

function loop(time) {

x = -(Math.cos(time / 2000) * 20 + 20);

y = -(Math.sin(time / 2000) * 20 + 20);

frosty(img);

faceWindow(img);

drawFace();

requestAnimationFrame(loop);



}

// draws frosted glass to bg canvas

function frosty(img) {

const w = bg.width;

const h = bg.height;

bg.ctx.drawImage(img, x, y);

bg.ctx.fillStyle = glassColor;

bg.ctx.globalAlpha = glassOpacity;

bg.ctx.fillRect(-blurAmount, -blurAmount, w + blurAmount * 2, h + blurAmount * 2);

bg.ctx.globalAlpha = 1;

}



// creates inset window

function faceWindow(img) {

const w = windowMask.width;

const h = windowMask.height;

windowMask.ctx.clearRect(0, 0, w, h);

windowMask.ctx.beginPath();

windowMask.ctx.ellipse(w / 2, h / 2, faceRadius1, faceRadius2, 0, 0, Math.TAU);

windowMask.ctx.fill();

windowMask.ctx.globalCompositeOperation = "source-in";

windowMask.ctx.drawImage(img, x, y,); // draw face

windowMask.ctx.globalCompositeOperation = "source-over";

}

// puts it all together.

function drawFace() {

const w = canvas.width;

const h = canvas.height;

ctx.drawImage(bg, 0, 0); // draw glass

ctx.drawImage(windowMask, 0, 0); // draw face in window

// draw border

ctx.lineWidth = borderWidth;

ctx.strokeStyle = insetBorderColor;

ctx.beginPath();

ctx.ellipse(w / 2, h / 2, faceRadius1, faceRadius2, 0, 0, Math.TAU);

ctx.stroke();

// draw highlights

ctx.strokeStyle = highlight; // gradient

ctx.globalCompositeOperation = "lighter";

ctx.globalAlpha = 0.65;

ctx.beginPath();

ctx.ellipse(w / 2, h / 2, faceRadius1 - borderWidth * 2, faceRadius2 - borderWidth * 2, 0, 0, Math.PI / 2);

ctx.stroke();



ctx.beginPath();

ctx.ellipse(w / 2, h / 2, faceRadius1 - borderWidth * 2, faceRadius2 - borderWidth * 2, 0, Math.PI, Math.PI * 1.5);

ctx.stroke();

ctx.globalCompositeOperation = "source-over";

ctx.globalAlpha = 1;

}

}
canvas { border: 2px solid black; }
<canvas id="canvas" width="200" height="350"> </canvas>

CSS: Workaround to backdrop-filter?

As of Chrome M76, backdrop-filter is now shipped, unprefixed, and without a needed flag.

https://web.dev/backdrop-filter/

NOTE: (since this answer keeps getting downvoted because Mozilla hasn’t yet shipped it): this feature is available in Safari, Chrome, and Edge, but not yet in Firefox. Mozilla is planning to ship it very soon, but hasn’t yet. So this answer doesn’t contain a “workaround” but simply more information about which browsers require a workaround. Which still seems like useful information.



Related Topics



Leave a reply



Submit