使用 CSS 模糊背景滤镜元素的边缘

Posted

技术标签:

【中文标题】使用 CSS 模糊背景滤镜元素的边缘【英文标题】:Blur the edges of a backdrop-filter element with CSS 【发布时间】:2021-03-08 23:05:38 【问题描述】:

document.querySelector( 'style' ).innerhtml += `
  div 
    width: 40rem;
    height: 1rem;
    background-color: #444;
  
  .earth_orbit, .moon 
    width: 15rem;
    margin-left: 100%;
    background-color: #222;;
  
  .earth_orbit::before 
    width: 5rem;
    height: 5rem;
    background-color: #08f;
  
  .moon 
    width: 2.5rem;
    height: 2.5rem;
    background-color: #ddd;
  
  section 
    right: 5%;
    width: 37.5%;
    height: 50%;
    font-size: 5rem;
    font-weight: bold;
    text-align: center;
    backdrop-filter: blur( 2rem );
    -webkit-backdrop-filter: blur( 2rem );
    /* filter: blur( 1rem ); */ /* Only blur inside element, ignoring the paremter */
  
`;
*, * ::before, * ::after 
  margin: 0;
  padding: 0;
  box-sizing: border-box;

html, body, main 
  overflow: hidden;
  height: 100%;
  background-color: #111;
  color: #eee;

html 
  font-family: Arial;
  font-size: 1.5vmin;

main, div, section 
  display: flex;
  justify-content: center;
  align-items: center;

div, div::before, section 
  position: absolute;
  z-index: auto;
  width: 10rem;
  height: 10rem;
  background-color: #f90;
  border-radius: 5rem;
  content: '';

.moon::before 
  display: none;
<style>
  .sun_orbit, .earth_orbit, section 
    background-color: transparent;
  
  span 
    color: #ccc;
    font-size: 4rem;
  
  .rotate 
    animation-name: rotate;
    animation-duration: 4s;
    animation-timing-function: linear;
    animation-iteration-count: infinite;
  
  @keyframes rotate 
    0%  transform: rotate( 0deg ); 
    100%  transform: rotate( 360deg ); 
  
  .offset 
    animation-duration: 1s;
  
</style>
<main>
  <div class='sun_orbit rotate'>
    <div class='earth_orbit rotate offset'>
      <div class='moon'></div>
    </div>
  </div>
  <section>
    <p>blurred overlay<br><span>( backdrop-filter )</span></p>
  </section>
</main>

在使用 CSS 属性 backdrop-filter 的地方,元素边​​框总是有锐利的边缘。然而,模糊边缘本身以及下面的所有内容是理想的结果。在目标元素上设置filter: blur( *value* ) 似乎在我测试过的任何浏览器中都不起作用。

一年多以前有人问过this 的问题,但没有得到答案,也许还没有一个很清楚的例子来说明这里要完成的工作。每次“行星”在模糊的 div 后面时,您都可以看到 div 开始和结束的清晰边缘 - 就像脆玻璃一样。我想找到一种方法来保持此处的所有效果,但沿“玻璃”或背景覆盖层模糊边缘或边框。

【问题讨论】:

【参考方案1】:

我发现的唯一解决方法是通过复制所有受影响的元素来伪造backdrop-filter 模糊,然后创建一个“窗口”与定位到其确切位置的背景重叠,并应用常规filter: blur( n )

document.querySelector( 'style' ).innerHTML += `
  .earth_orbit, .moon 
    width: 15rem;
    margin-left: 100%;
    background-color: #222;;
  
  .earth_orbit::before 
    width: 5rem;
    height: 5rem;
    background-color: #08f;
  
  .moon::before 
    display: none;
  
  .moon 
    width: 2.5rem;
    height: 2.5rem;
    background-color: #ddd;
  
  .sun_orbit, .earth_orbit 
    background-color: transparent;
  
  footer 
    right: 5%;
    width: 20rem;
    height: 20rem;
    background-color: transparent;
  
  .rotate 
    animation-name: rotate; animation-duration: 4s;
    animation-timing-function: linear; animation-iteration-count: infinite;
      
`;
*, * ::before, * ::after 
  margin: 0;
  padding: 0;
  box-sizing: border-box;

html, body, main 
  overflow: hidden;
  height: 100%;
  background-color: #111;
  color: #eee;

html 
  font-family: Arial;
  font-size: 1.5vmin;

main, div, footer 
  display: flex;
  justify-content: center;
  align-items: center;

div, div::before, footer 
  position: absolute;
  z-index: auto;
  width: 10rem;
  height: 10rem;
  background-color: #f90;
  border-radius: 5rem;
  content: '';

div 
  width: 40rem; height: 1rem;
  background-color: #444;
<style>
  footer .sun_orbit  top: 9.5rem; left: -13.25vmax; 
  section  width: 70%; height: 70%; 
  p  
    position: relative; z-index: 10; font-size: 2rem; left: 30vh;
  
  footer 
    overflow: hidden; background-color: #111;
    z-index: 10; filter: blur( 1rem ); left: 54.5vmax;
    
  @keyframes rotate 
    0%  transform: rotate( 0deg );  
    100%  transform: rotate( 360deg ); 
   
  .offset  animation-duration: 1s;   
</style>
<main>
  <div class='sun_orbit rotate'>
    <div class='earth_orbit rotate offset'>
      <div class='moon'></div>
    </div>
  </div>
  <footer>
    <section>
      <div class='sun_orbit rotate'>
        <div class='earth_orbit rotate offset'>
          <div class='moon'></div>
        </div>
      </div>
    </section>
  </footer>
  <p>backdrop overlay<br>with faded edges</p>
</main>

额外的好处是整个效果现在可以在 Firefox 中使用,而最初它不能。另外:如果需要,这可以做出响应。

【讨论】:

以上是关于使用 CSS 模糊背景滤镜元素的边缘的主要内容,如果未能解决你的问题,请参考以下文章

CSS 背景过滤器透明模糊,边缘平滑

使用 CSS 将软边缘应用于图像

ps怎么把模糊的图片变清晰?

请教CSS,在有背景图的背景层上使用模糊滤镜,把内层的文字也模糊了,求不模糊文字的方法?

flash cs5.5中如何实现边缘模糊遮罩

在网页设计中,如何利用CSS让字体边缘有颜色,比如字体是白色的,他的边缘颜色是黑色的?