Through this article, you can understand
- The most basic use of CSS
backdrop-filter
achieve the effect of frosted glass (frosted glass) - In the firefox browser that is not compatible with
backdrop-filter
so far, how to use some tricky operations to achieve the frosted glass effect ingeniously, so that this effect can really be used in business
What is backdrop-filter
backdrop-filter
CSS property allows you to add graphic effects (such as blur or color shift) to the area behind an element. Because it applies to all elements behind the element, in order to see the effect, the element or its background must be at least partially transparent.
backdrop-filter
is filter
. The values that can be taken are the same, but one acts on the entire element, and the other only acts on the area behind the element.
Comparison between backdrop-filter
and filter
We use backdrop-filter
and filter
to achieve a ground glass effect at the same time as a comparison, the pseudo code is as follows:
<div class="bg">
<div>Normal</div>
<div class="g-filter">filter</div>
<div class="g-backdrop-filter">backdrop-filter</div>
</div>
.bg {
background: url(image.png);
& > div {
width: 300px;
height: 200px;
background: rgba(255, 255, 255, .7);
}
.g-filter {
filter: blur(6px);
}
.g-backdrop-filter {
backdrop-filter: blur(6px);
}
}
CodePen Demo - filter and backdrop-filter comparison
Before backdrop-filter
, it was still very difficult to achieve the above-mentioned filter effect only to the element background, and for static pictures, if the background is still a dynamic background that can be scrolled, CSS is usually powerless.
backdrop-filter
was born just to add filters to the content behind the element without affecting the element itself. It can be very convenient to achieve the effect of frosted glass (frosted glass)!
backdrop-filter
compatibility
backdrop-filter
has been born for quite a while, however, firefox is not compatible with it so far!
For some PC-side businesses that have abandoned IE, firefox still needs to be compatible. If you want to use backdrop-filter
achieve ground glass effect applications, the compatibility problem of firefox must be solved.
Realize the frosted glass effect in firefox
OK, the focus of this article is how to restore the effect of ground glass backdrop-filter
First, let’s take a look. If backdrop-filter
is used normally, or the above example has the following effect, there is no ground glass effect:
Use background-attachment: fixed to be compatible with static background images
If you want to use ground glass effect on firefox. The background of applying ground glass elements is just a static background image, in fact, there are many ways.
We only need to superimpose a same picture behind the element, use background-attachment: fixed
to locate the picture superimposed under the element to the same coordinates as the background, and then use filter: blur()
to blur it.
The pseudo code is as follows:
<div class="g-glossy">frosted glass effect </div>
$img: 'https://static.pexels.com/photos/373934/pexels-photo-373934.jpeg';
body {
height: 100vh;
display: flex;
background-image: url($img);
background-repeat: no-repeat;
background-attachment: fixed;
background-size: cover;
}
.g-glossy {
position: relative;
width: 600px;
height: 300px;
background-color: rgba(255, 255, 255, 0.5);
overflow: hidden;
z-index: 10;
&::before {
content: "";
position: absolute;
top: 0;
left: 0;
right: 0;
bottom: 0;
background-image: url($img);
background-repeat: no-repeat;
background-attachment: fixed;
background-size: cover;
filter: blur(10px);
z-index: -1;
}
}
The effect is as follows:
This method is also one of the most commonly used methods to achieve simple frosted glass effects in various browsers before backdrop-filter
CodePen Demo - Use background-attachment: fixed | filter: bulr() to achieve ground glass effect
Use background-attachment: fixed to be compatible with the disadvantages of static background images
However, this method also has two disadvantages:
- Since the pseudo-element is used to overlay a layer of background, the background of the parent element is at the bottom layer due to the hierarchical relationship, so the background color of the element itself is not fully reflected. You can compare the actual renderings of the following two methods:
The solution is to superimpose a layer of background color with another pseudo element. This background color should be originally assigned to the parent element itself.
The effect after stacking is as follows:
- The above effect is very close. If you want to be thorny, it is that the edge of the pseudo element with the blur filter has white edge defects. This is actually a problem of the filter itself, and it is also very easy to solve. We only need to deal with the pseudo element. Just expand the scope a bit:
.g-glossy {
overflow: hidden;
....
&::before {
content: "";
position: absolute;
top: -100px;
left: -100px;
right: -100px;
bottom: -100px;
}
}
The positioning code is changed top: 0px;
top: -100px
, which is sufficient for all four directions. In this way, it can be basically a 100% simulation.
Use moz-element()
filter: blur()
achieve the complex background frosted glass effect
The following method is very clever. Normally, using ground glass effect background elements is not as simple as a picture! Behind is usually the complex structure of the entire page, the nesting of multiple layers of DOM.
Then by superimposing a simple picture, it will not work, we have to find a way to simulate the entire DOM element.
It just so happens that in Firefox, there is such an attribute - -moz-element()
.
What is -moz-element()
? MDN-element ) The explanation is that the CSS function element()
<image>
value generated from any HTML element. The image value is real-time, which means that if the specified HTML element is changed, the background of the element to which the attribute is applied will also change accordingly.
It is actually a draft specification, but for a long time, only Firefox supports it - CAN I USE - CSS element() :
What does it do?
How to use -moz-element()
So how to use -moz-element()
In short, it can replicate the UI rendered inside an element and can synchronize changes in real time.
Suppose we have such a simple structure, the element background and content are in motion:
<div id="bg" class="g-normal">
<p>Content</p>
</div>
.g-normal {
margin: auto;
width: 200px;
height: 200px;
animation: change 5s infinite;
background: linear-gradient(deeppink, yellowgreen);
}
p {
animation: move 5s infinite;
}
@keyframes change {
0% {
filter: hue-rotate(0);
}
100% {
filter: hue-rotate(360deg);
}
}
@keyframes move {
0% {
transform: translate(0, 0);
}
100% {
transform: translate(150px, 150px);
}
}
Its effect is roughly like this:
We assume that this structure is the content of a certain part of our page, and then we can use background: -moz-element(#id)
this way to completely copy the UI content drawn in this element to another element to see the effect.
We add an element <div class="g-element-copy"></div>
to simulate the content in #bg
<div id="bg" class="g-normal">
<p>Content</p>
</div>
<div class="g-element-copy"></div>
.g-element-copy {
margin: auto;
width: 200px;
height: 200px;
// 核心代码
background: -moz-element(#bg);
}
It can completely copy the UI drawn in another element, and can track real-time changes:
CodePen Demo -- -moz-element Demo(Firefox Only)
Use element to copy the UI in firefox and use it as the background of frosted glass elements
In this way, with the above foreshadowing, the following content will be easier to understand.
Compared with the above background-attachment: fixed
solution, we still superimpose a layer of background through pseudo-elements, but the content in the background changes from a simple picture to the entire UI content copied -moz-element()
Secondly, in the above scheme, we use background-attachment: fixed
to align the position of the background image and the image superimposed in the pseudo element. Here, we need to use Javascript to perform simple calculations to determine the relative position of the background content element and calculate the alignment amount.
Look at such a DEMO:
<div id="bg" class="bg">
<div>模拟真实 DOM</div>
<div>模拟真实 DOM</div>
<div>模拟真实 DOM</div>
<div>模拟真实 DOM</div>
<div>模拟真实 DOM</div>
<div>模拟真实 DOM</div>
<div>模拟真实 DOM</div>
<div>模拟真实 DOM</div>
<div>模拟真实 DOM</div>
</div>
<div class="g-glossy">frosted glass effect </div>
<div class="g-glossy-firefox"></div>
Among them, .g-glossy
is our frosted glass element when backdrop-filter
compatible under normal circumstances .g-glossy-firefox
is not compatible with backdrop-filter
, we need to simulate the entire DOM background UI element, which can be controlled CSS @support
Core CSS code:
.bg {
// 整个页面的 DOM 结构
}
.g-glossy {
position: fixed;
width: 600px;
height: 300px;
background-color: rgba(255, 255, 255, 0.5);
backdrop-filter: blur(10px);
}
.g-glossy-firefox {
display: none;
}
@supports (background: -moz-element(#bg)) {
.g-glossy-firefox {
display: block;
position: fixed;
width: 600px;
height: 300px;
background: -moz-element(#bg) no-repeat;
filter: blur(10px);
}
}
A brief explanation:
- For compatibility
backdrop-filter
of,.g-glossy
code inside will directly take effect, and.g-glossy-firefox
not show - For Firefox browser, because
backdrop-filter
necessarily incompatible, so.g-glossy
inbackdrop-filter: blur(10px)
not take effect and@supports (background: -moz-element(#bg))
style will take effect within this time.g-glossy-firefox
will usebackground: -moz-element(#bg) no-repeat;
simulated id isbg
elements
Of course, here we need to use a certain JavaScript code to calculate the element .g-glossy-firefox
our simulated page UI relative to its simulated #bg
element, which is a positioning deviation of the page layout:
$(function() {
let blur = $('.g-glossy-firefox')[0].style;
let offset = $('.g-glossy').eq(0).offset();
function updateBlur() {
blur.backgroundPosition =
`${-window.scrollX - offset.left}px ` +
`${-window.scrollY - offset.top}px`;
}
document.addEventListener('scroll', updateBlur, false), updateBlur();
});
OK, so far, we can perfectly achieve the effect of frosted glass on Firefox:
Compared with the first solution above, the biggest difference is that it can simulate various background elements, and the background element can be more than just a picture! It can be a variety of complex structures!
Feng Hailiu in my CSS group. It is very clever, and he also has a complete explanation of this scheme himself, you can here to see: 160dda74512ff1 in the webpage To achieve the "frosted glass" effect of the title bar , this article was also reorganized and issued with his consent.
For the complete code of the above effect, you can click here:
CodePen Demo - Compatible with Firefox's complex background frosted glass (frosted glass) effect
in conclusion
A brief summary of the above content:
- You can use
backdrop-filter
to realize the frosted glass (frosted glass) effect very easily for browsers compatible with it - For browsers that are not compatible with
backdrop-filter
, if it is just a simple background, you can usebackground-attachment: fixed
withfilter: blur()
for simulation - For firefox browser, you can also use
moz-element()
withfilter: blur()
achieve a complex background frosted glass effect - For other browsers that are not compatible with the above 3 effects, the elements of the frosted glass effect can be set by setting
background: rgba(255, 255, 255, 0.5)
to make it fall back to a translucent effect, which is also a very reasonable degradation effect and will not cause Bug
At last
Okay, this concludes this article, I hope it helps you :)
If you want to get the most interesting CSS information, don’t miss my account - 160dda74513123 iCSS front-end interesting 160dda74513124 😄
More wonderful CSS technical articles are summarized in my Github - iCSS , which will be updated continuously. Welcome to click a star to subscribe to the collection.
If you have any questions or suggestions, you can exchange more, original articles, limited writing style, and lack of knowledge. If there are any irregularities in the article, please let me know.
**粗体** _斜体_ [链接](http://example.com) `代码` - 列表 > 引用
。你还可以使用@
来通知其他用户。