Here's the solution to your problem, with some added enhancements.
The issue you were facing was due to a mismatch in background alignment between ::before and the body. By consolidating the CSS styles into one, I've simplified the code for easier editing.
To offer more control over opacity, I replaced #hex values with background:rgba(). This allows for better customization of opacity settings.
I've inserted comments within the CSS to outline the modifications made and provide clarity on the changes.
NOTE: Removing opacity from the ::after class enhances transparency and visibility of the noise texture. It appears that the semi-transparency of the noise texture causes this behavior. If you have further insight or explanations, please share. I introduced classes .nested and .parent for separate styling options. The third example excludes both classes for comparison.
Update: I noticed the exclusion blend filter mentioned in the spec was missing, so I've incorporated it as well. References are provided below the snippet.
CSS & HTML Snippet with 3 variations:
/* Consolidating background styles
for seamless editing. Altering color
from #333 to #fff increases filter effect */
html,
.acrylic:before {
background: #333 url(https://source.unsplash.com/1600x900/?nature) 50% 100% fixed;
background-size: cover;
}
body {
margin: 0;
font: 1em/1.4 Sans-serif;
}
/*spacing adjustments*/
div {
margin: 5px;
}
main {
display: flex;
align-items: center;
justify-content: center;
flex-flow: row wrap;
height: 100vh;
}
.acrylic {
padding: 4em 6em;
position: relative;
overflow: hidden;
}
/*Added browser compatibility for blur and included the exclusion blend filter as per specification*/
.acrylic::before {
content: '';
position: absolute;
z-index: -1;
height: 100%;
top: 0;
right: 0;
left: 0;
filter: blur(8px);
-webkit-filter: blur(8px);
-moz-filter: blur(8px);
-o-filter: blur(8px);
-ms-filter: blur(8px);
background-blend-mode: exclusion;
}
/*changed color to rgba and removed opacity property*/
.acrylic::after {
content: "";
position: absolute;
height: 100%;
left: 0;
top: 0;
right: 0;
bottom: 0;
z-index: -1;
border: 1px solid #fff;
background-image: url(data:image/png;base64,iVBORw...); /*base64 encoded image*/
}
/*Individual control over
.nested and .parent opacity and color.*/
.parent::after {
background-color: rgba(230, 240, 255, 0.50);
opacity: 0.60;
}
.child::after {
background-color: rgba(230, 240, 255, 0.30);
opacity: 0.60;
}
.shadow {
box-shadow: 0 10px 30px rgba(0, 0, 0, 0.2), 0 1px 8px rgba(0, 0, 0, 0.4);
}
<body>
<main>
<div class="acrylic shadow parent">
<div class="acrylic child">
Acrylic material! <br />.parent on .child on
</div>
</div>
<div class="acrylic shadow">
<div class="acrylic child">
Acrylic material! <br />.parent off .child on
</div>
</div>
<div class="acrylic shadow">
<div class="acrylic">
Acrylic material! <br />.parent off .child off
</div>
</div>
</main>
</body>
Sources and additional notes:
You can refer to CSS Tricks for creating a glass effect using filters here.
If you wish to apply the effect across multiple images, maintaining a blurred version alongside the original may become cumbersome. Responsive designs often require swapping images based on screen size, which could benefit from generating the effect directly from the source image rather than retaining duplicates.
For broader browser support, consider adding SVG filters as a fallback option. While not included in this snippet, you can incorporate them like this:
While new, CSS Filters may need vendor prefixes and lack universal adoption. On the other hand, SVG filters applied within CSS via HTML have wider compatibility. Utilizing SVG filters as a substitute for unsupported CSS filters offers an effective workaround.
Include inline SVG definitions referencing the filter ID via a url(). You could also encode the SVG filter as a data URL, though readability might suffer.
An example provided:
SVG:
<svg xmlns="http://www.w3.org/2000/svg" version="1.1">
<defs>
<filter id="blur">
<feGaussianBlur stdDeviation="5" />
</filter>
</defs>
</svg>
CSS
.glass::before {
background-image: url('pelican.jpg');
/* Fallback to SVG filters */
filter: url('#blur');
filter: blur(5px);
}
Explore further about CSS filter blends at https://css-tricks.com/basics-css-blend-modes