11
头图

Through this article, you can understand

  1. The most basic use of CSS backdrop-filter achieve the effect of frosted glass (frosted glass)
  2. 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:

image

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:

image

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:

  1. 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:

image

CodePen Demo - Use background-attachment: fixed | filter: bulr() to optimize the frosted glass effect

  1. 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:

  1. For compatibility backdrop-filter of, .g-glossy code inside will directly take effect, and .g-glossy-firefox not show
  2. For Firefox browser, because backdrop-filter necessarily incompatible, so .g-glossy in backdrop-filter: blur(10px) not take effect and @supports (background: -moz-element(#bg)) style will take effect within this time .g-glossy-firefox will use background: -moz-element(#bg) no-repeat; simulated id is bg 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 use background-attachment: fixed with filter: blur() for simulation
  • For firefox browser, you can also use moz-element() with filter: 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.


chokcoco
12.3k 声望18.5k 粉丝