With the advent of Microsoft's Fluent Design System and the propagation of the new Acrylic Material around the Windows ecosystem, I thought it would be great to use it in some Web layouts.
Acoording to the spec, the composition of an acrylic layer is:
So I went to try a CSS-only approach inspired by the layers in that picture, this way:
body {
margin: 0;
font: 1em/1.4 Sans-serif;
background: url("http://www.wallpapers-web.com/data/out/191/5484624-sunset-wallpapers.jpg") center center;
background-size: 100vw auto;
}
main {
display: flex;
align-items: center;
justify-content: center;
height: 100vh;
}
.acrylic {
padding: 4em 6em;
position: relative;
overflow: hidden;
}
.acrylic::before {
background: url("http://www.wallpapers-web.com/data/out/191/5484624-sunset-wallpapers.jpg") center center;
background-size: 100vw auto;
filter: blur(10px);
content: "";
position: absolute;
left: -10px;
top: -10px;
width: calc(100% + 20px);
height: calc(100% + 20px);
z-index: -1;
}
.acrylic::after {
content: "";
position: absolute;
left: 0;
top: 0;
right: 0;
bottom: 0;
z-index: -1;
opacity: 0.65;
border: 1px solid #fff;
background: #fff;
background-image: url(data:image/png;base64,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);
}
.shadow {
border-radius: 1px;
box-shadow: 0 10px 30px rgba(0, 0, 0, 0.1), 0 1px 8px rgba(0, 0, 0, 0.2);
}
<main>
<div class="acrylic shadow">
Acrylic material!
</div>
</main>
The result is really close to the spec and is also responsive, but has a big problem: just stack another .acrylic
div and the background trick doesn't work anymore.
The question is: is there some smarter way to gaussian blur without duplicating the body background for each children? Or maybe some smarter way to dinamically calculate its position?
There are two ways to do this...
.acrylic
Complex implementation but runs on most modern browsers.backdrop-filter
on.acrylic
Very simple implementation but lacks browser support.1. Blurred bg on
.acrylic
We need to duplicate bg on
.acrylic
guys too, because just bringing down opacity will show the content behind them not in them, which AFAIK is not covered by blur filter...Smart way to calc positions would be to set
background-attachment: fixed
for both parent element (body
) and.acrylic
guys, this will allow you to have multiple.acrylic
guys as well ;)Since we use same background for parent and children, we can club them together ;)
Here is a working snippet ;) Turned opacity on
.acrylic:after
a bit down so background is a bit more visible ;)2. (Less supported)
backdrop-filter
on.acrylic
As far as I know there is no smarter way in this case to achieve that, since the
background image
and thefilter
have to be set to the same div to create this desired effect.As far as I understood, the issue is that with every additional div
.acrylic
the background part of the image gets duplicated.Since you're using the same background image you could fix this by simply adding
background-attachment: fixed
to the div.acrylic::before
.This answer solves the problem and I've enhanced it aswell.
I think the only problem you had was background alignment applied to the ::before and the body were different. So by combining the CSS used into one, I've shortcutted this to make updating and editing it easier.
I used background:rgba() instead of #hex values to give more flexibility over the opacity controls.
I've added notes throughout the CSS to explain the changes I've made to make them more apparent.
NOTE: Removing the opacity from the ::after class causes transparency to increase and increases the visibility of the noise texture. I believe it is being caused by the noise texture itself being semi transparent, but it is an odd behaviour, if anyone else knows and has a better explanation I'd be interested to know. I've added classes .nested and .parent. as it may be preferable to have control over these things separately. I've removed .parent in the second example and both in the third.
Update: Noticed the exclusion blend filter mentioned in spec wasn't included, so I've added that in too. Provided sources below the snippet.
Hope this helped. :)
CSS & HTML Snippet with 3 examples:
Sources and extra notes:
You can find a source for front glass effect on CSS Tricks here.
They also say that if you want to offer even more browser support you can add in SVG filter as a fall back, although I haven't added it to my own snippet they say this:
And provided a code example
SVG:
CSS
For more about the CSS filter blends, go here https://css-tricks.com/basics-css-blend-modes