I accidentally saw such a question in How does 1619b07c38a7c8 make part of a div transparent while other parts are blurred? , the final effect is like this
Furthermore, it can also achieve the hollowing effect of any shape
The place where the mouse passes is clearly visible, and other places are blurred.
You may not be able to start at the beginning, don't worry, you can start with simple and similar effects, try step by step, let's take a look.
1. Ordinary translucent effect
For example, in normal development, it may be a translucent effect, which is a bit similar to a searchlight (the area outside the mouse is a translucent mask, which looks a little darker). as follows:
Let's start with this effect first, suppose there is such a layout:
<div class="wrap" id="img">
<img class="prew" src="https://tva1.sinaimg.cn/large/008i3skNgy1gubr2sbyqdj60xa0m6tey02.jpg">
</div>
So how to draw a hollow circle? First introduce a method
In fact, it's very simple. You only need a large enough projection. The principle is as follows
Here you can use the pseudo-element ::before
to draw, the structure is more streamlined. The code implementation is
.wrap::before{
content:'';
position: absolute;
width: 100px;
height: 100px;
border-radius: 50%;
left: 50%;
top: 50%;
transform: translate(-50%,-50%); /*默认居中*/
box-shadow: 0 0 0 999vw rgba(0, 0, 0, .5); /*足够大的投影*/
}
Can get this effect
Second, pass the mouse position with the help of CSS variables
According to past experience, the style attribute of the element may be directly modified in js, similar to this
img.addEventListener('mousemove', (ev) => {
img.style.left = '...';
img.style.top = '...';
})
However, such interaction and business logic are mixed together, which is not conducive to later maintenance. In fact, we only need the coordinates of the mouse, and the following effect can be fully realized in CSS.
With the help of CSS variables here, everything is easy! Assuming that the coordinates of the mouse are [--x,--y]
(range is [0, 1]
), then the coordinates of the mask can be calculated calc
.wrap::before{
left: calc(var(--x) * 100%);
top: calc(var(--y) * 100%);
}
Then the mouse coordinates can be calculated using JS, which is also relatively easy, as follows
img.addEventListener('mousemove', (ev) => {
img.style.setProperty('--x', ev.offsetX / ev.target.offsetWidth);
img.style.setProperty('--y', ev.offsetY / ev.target.offsetHeight);
})
In this way, the hollow effect of the translucent effect is completed
The complete code can be accessed: backdrop-shadow (codepen.io)
Third, the gradient can also achieve a translucent effect
In addition to the above shadow expansion method, CSS radial gradient can also achieve this effect
Draw a gradient from transparent to semi-transparent, as follows
.wrap::before{
content: '';
position: absolute;
width: 100%;
height: 100%;
left: 0;
top: 0;
background: radial-gradient( circle at center, transparent 50px, rgba(0,0,0,.5) 51px);
}
Can get this effect
Then, just map the mouse coordinates. From here you can see the benefits of CSS variables, without modifying JS, only in CSS modify the gradient center point position can be achieved
.wrap::before{
background: radial-gradient( circle at calc(var(--x) * 100% ) calc(var(--y) * 100% ), transparent 50px, rgba(0,0,0,.5) 51px);
}
Fourth, the background blur effect try
There is a property in CSS specifically for the background (the area behind the element): backdrop-filter . The usage is exactly the same as filter
backdrop-filter: blur(10px);
The following is a schematic effect in MDN
backdrop-filter
is to behind the area where the element is located. To see the effect, the element itself needs to be semi-transparent or completely transparent; and filter
is to blur the element itself are interested can check this article: 1619b07c39977c Introduction to CSS backdrop-filter and Apple iOS frosted glass effect« Zhang Xinxu-Xin Space-Xin Life (zhangxinxu.com)
It should be noted that this blur has nothing to do with the background 1619b07c39979c, even if the element itself is transparent, it will still have an effect. For example, the following is the effect after removing the background, the whole block is blurred
What if you apply the above example directly?
1. Shadow Realization
backdrop-filter
first example above
.wrap::before{
content:'';
position: absolute;
width: 100px;
height: 100px;
border-radius: 50%;
left: 50%;
top: 50%;
transform: translate(-50%,-50%); /*默认居中*/
box-shadow: 0 0 0 999vw rgba(0, 0, 0, .5); /*足够大的投影*/
backdrop-filter: blur(5px)
}
The effect is as follows
You can see that the circular area is blurred, just the opposite of the desired effect. In fact, it is easy to understand that only the circular area is the real structure, and the outside is all shadows, so the final effect is only the circular part.
2. Gradient realization
backdrop-filter
in the second example
.wrap::before{
content: '';
position: absolute;
width: 100%;
height: 100%;
left: 0;
top: 0;
background: radial-gradient( circle at calc(var(--x) * 100% ) calc(var(--y) * 100% ), transparent 50px, rgba(0,0,0,.5) 51px);
backdrop-filter: blur(5px)
}
The effect is as follows
It's all blurred, but it's darker outside the circular area. Because ::before
occupies the entire container, the entire back is blurred, and the outside of the circle is darker because of the effect of the translucent gradient.
In short, we still cannot meet our needs, and we need to find new solutions.
Five, CSS MASK achieves hollowing
It is not so much to make the circular area not blurry, it is better to hollow out that area. Just like before, it was a whole piece of frosted glass, and then CSS MASK 1619b07c39a01f, so that it must be clear to see through the round hole.
You can slightly modify the second example, draw a transparent circle through a radial gradient, and the rest is a pure color mask layer, as shown below
The code implementation is
.wrap::before{
content: '';
position: absolute;
width: 100%;
height: 100%;
left: 0;
top: 0;
-webkit-mask: radial-gradient( circle at calc(var(--x, .5) * 100% ) calc(var(--y, .5) * 100% ), transparent 50px, #000 51px);
background: rgba(0,0,0,.3);
backdrop-filter: blur(5px)
}
This achieves the effect at the beginning of the article
The complete code can be viewed: backdrop-mask (codepen.io)
Six, CSS MASK COMPOSITE achieves a richer hollowing effect
In addition to using the radial gradient to draw the mask layer, it can also be achieved by CSS MASK COMPOSITE (mask composition) . The standard key values are as follows (firefox support):
/* Keyword values */
mask-composite: add; /* 叠加(默认) */
mask-composite: subtract; /* 减去,排除掉上层的区域 */
mask-composite: intersect; /* 相交,只显示重合的地方 */
mask-composite: exclude; /* 排除,只显示不重合的地方 */
What does mask composition mean? It can be analogous to the shape synthesis in photoshop, almost one-to-one correspondence
-webkit-mask-composite is different from the standard value, and there are many attribute values, as follows (chorme, safari support)
-webkit-mask-composite: clear; /*清除,不显示任何遮罩*/
-webkit-mask-composite: copy; /*只显示上方遮罩,不显示下方遮罩*/
-webkit-mask-composite: source-over;
-webkit-mask-composite: source-in; /*只显示重合的地方*/
-webkit-mask-composite: source-out; /*只显示上方遮罩,重合的地方不显示*/
-webkit-mask-composite: source-atop;
-webkit-mask-composite: destination-over;
-webkit-mask-composite: destination-in; /*只显示重合的地方*/
-webkit-mask-composite: destination-out;/*只显示下方遮罩,重合的地方不显示*/
-webkit-mask-composite: destination-atop;
-webkit-mask-composite: xor; /*只显示不重合的地方*/
Are you stunned? I have made a corresponding rendering here. If you are not familiar with it, you know that there is such a function when you use it, and then just look for it.
Back here, you can draw a whole background and a circular background, and then pass the mask synthesis to exclude ( mask-composite: exclude
) and punch a hole, the realization is as follows
.wrap::before{
content: '';
position: absolute;
width: 100%;
height: 100%;
left: 0;
top: 0;
-webkit-mask: url("data:image/svg+xml,%3Csvg width='50' height='50' viewBox='0 0 50 50' fill='none' xmlns='http://www.w3.org/2000/svg'%3E%3Ccircle cx='25' cy='25' r='25' fill='%23C4C4C4'/%3E%3C/svg%3E"), linear-gradient(red, red);
-webkit-mask-size: 50px, 100%;
-webkit-mask-repeat: no-repeat;
-webkit-mask-position: calc(var(--x, .5) * 100% + var(--x, .5) * 100px - 50px ) calc(var(--y, .5) * 100% + var(--y, .5) * 100px - 50px ), 0;
-webkit-mask-composite: xor; /*只显示不重合的地方, chorem 、safari 支持*/
mask-composite: exclude; /* 排除,只显示不重合的地方, firefox 支持 */
background: rgba(0,0,0,.3);
backdrop-filter: blur(5px)
}
Need to pay attention -webkit-mask-position
, this can also achieve this effect well
The complete code can be viewed: backdrop-mask-composite (codepen.io)
You may have found that the circle in the above example is drawn through svg, and mask synthesis is also used, which seems to be more cumbersome. In fact, this is a more versatile solution that can bring unlimited possibilities. For example, I need a star ⭐️ hollow effect, it’s very simple, first draw one through a drawing software
Then escape this svg code. It is recommended to use the SVG online compression and merging tool
Just replace it with the example just now.
.wrap::before{
content: '';
position: absolute;
width: 100%;
height: 100%;
left: 0;
top: 0;
-webkit-mask: url("data:image/svg+xml,%3Csvg width='96' height='91' viewBox='0 0 96 91' fill='none' xmlns='http://www.w3.org/2000/svg'%3E%3Cpath d='M48 0l11.226 34.55h36.327l-29.39 21.352L77.39 90.45 48 69.098 18.61 90.451 29.837 55.9.447 34.55h36.327L48 0z' fill='%23C4C4C4'/%3E%3C/svg%3E"), linear-gradient(red, red);
-webkit-mask-size: 50px, 100%;
-webkit-mask-repeat: no-repeat;
-webkit-mask-position: calc(var(--x, .5) * 100% + var(--x, .5) * 100px - 50px ) calc(var(--y, .5) * 100% + var(--y, .5) * 100px - 50px ), 0;
-webkit-mask-composite: xor; /*只显示不重合的地方, chorem 、safari 支持*/
mask-composite: exclude; /* 排除,只显示不重合的地方, firefox 支持 */
background: rgba(0,0,0,.3);
backdrop-filter: blur(5px)
}
The effect of star hollowing is as follows
The complete code can be viewed: backdrop-star (codepen.io)
Another example is a heart shape ❤, the effect is as follows
The complete code can be viewed: backdrop-heart (codepen.io)
Only unexpected, nothing impossible
Seven, summary and explanation
The above achieves a mouse-following hollowing effect, from simple to complex, from single to universal. Although a little bit of JS is used, it is only the role of "tool man". The interaction logic is all completed by CSS. Here is a summary:
- A sufficiently large shadow is a small trick to achieve a circular hollow effect
- CSS gradient can also easily draw a circular hollow background
- With the help of CSS variables, you can easily use the mouse position to achieve the desired effect
- The backdrop-filter can be imagined as the function of frosted glass
- CSS Mask can perforate frosted glass to achieve the effect of hollowing out
- With the help of mask synthesis features and SVG, it is possible to achieve hollowing out of any shape
CSS MASK is still very powerful, it is necessary to master it. Finally, if you think it’s pretty good, if it’s helpful to you, please like, bookmark, and forward ❤❤❤
**粗体** _斜体_ [链接](http://example.com) `代码` - 列表 > 引用
。你还可以使用@
来通知其他用户。