首页 > 解决方案 > 如何淡化元素背景图像的边缘以与主背景图像融合?

问题描述

我遇到了一个问题,试图淡化 div 背景图像的边缘,使其看起来与整个站点的背景图像混合(因此背景图像应用于主体)。

body{
    background-image: url('some url here') !important;
    background-repeat: no-repeat;
    background-attachment: fixed;
    background-position: 100%;
    background-size: 1150px;
  }
  #blendElement{
    background: url('some other url here');
    background-attachment: fixed;
    background-repeat: no-repeat;
    background-size: 100%;
  }
<head>
</head>

<body>
 <div>
   <div id="blendElement"> This should have edges blending to the main (body's) background image behind it.
   </div>
 </div>
</body>

如果您曾经使用过 PowerPoint 并尝试过一种称为软边缘的图像效果,那么这正是我在这里尝试做的。我能找到的唯一相关“答案”是通过使用带有插图的 box-shadow 来获得实体背景颜色:

box-shadow: 25px 25px 50px 0 (color matching background color) inset;

但是由于主体有一个背景图像而不是纯色,所以没有办法让它看起来像是融入其中。显然,在盒子阴影中使用透明颜色只会显示 div 背景图像,就像它通常看起来一样。

有人可以帮我解决这个问题吗?(而且我无法编辑 div 图像以使其具有透明的褪色边缘,因此必须直接使用 CSS 或 JS 完成)

标签: javascripthtmlcssimage

解决方案


可以使用mask-*CSS 属性来实现效果。

下面的例子产生一个 10px 长的淡入淡出边缘。

.body {
  display: grid;
  width: 200px;
  height: 200px;
  /* replace with the image you like here */
  background-image: repeating-linear-gradient(-45deg,
      yellow,
      yellow 20px,
      black 20px,
      black 40px);
}

.content {
  margin: 25px;
  /* replace with the image you like here */
  background-image: linear-gradient(to top, blue 0%, blue 100%);
  
  /* for webkit-based browsers */
  -webkit-mask-image:
    linear-gradient(to top, black 0%, black 100%),
    linear-gradient(to top, transparent 0%, black 100%),
    linear-gradient(to right, transparent 0%, black 100%),
    linear-gradient(to bottom, transparent 0%, black 100%),
    linear-gradient(to left, transparent 0%, black 100%);
  -webkit-mask-position:
    center,
    top,
    right,
    bottom,
    left;
  -webkit-mask-size:
    100% 100%,
    100% 10px,
    10px 100%,
    100% 10px,
    10px 100%;
  -webkit-mask-repeat:
    no-repeat,
    no-repeat,
    no-repeat,
    no-repeat,
    no-repeat;
   -webkit-mask-composite:
    source-out,
    source-over,
    source-over,
    source-over;
    
   /* for browsers which have implemented the official spec */
  mask-image:
    linear-gradient(to top, black 0%, black 100%),
    linear-gradient(to top, transparent 0%, black 100%),
    linear-gradient(to right, transparent 0%, black 100%),
    linear-gradient(to bottom, transparent 0%, black 100%),
    linear-gradient(to left, transparent 0%, black 100%);
  mask-position:
    center,
    top,
    right,
    bottom,
    left;
  mask-size:
    100% 100%,
    100% 10px,
    10px 100%,
    100% 10px,
    10px 100%;
  mask-repeat:
    no-repeat,
    no-repeat,
    no-repeat,
    no-repeat,
    no-repeat;
  mask-composite:
    subtract,
    add,
    add,
    add;
}
<div class="body">
  <div class="content"></div>
</div>


它是如何工作的以及如何定制?

它通过将 5 个子图像合成在一起并使用合成图像作为元素的掩码来工作。

让我们分离图像:(这里我使用background-*属性来模拟合成图像的效果)

.body {
  display: grid;
  width: 200px;
  height: 200px;
  grid-template: 200px / repeat(2, 200px 20px) 200px;
}

span {
  place-self: center;
}

.content1 {
  margin: 25px;
  background-image:
    linear-gradient(to top, black 0%, black 100%);
  background-position:
    center;
  background-size:
    100% 100%;
  background-repeat:
    no-repeat;
}

.content2 {
  margin: 25px;
  background-image:
    linear-gradient(to top, transparent 0%, black 100%),
    linear-gradient(to right, transparent 0%, black 100%),
    linear-gradient(to bottom, transparent 0%, black 100%),
    linear-gradient(to left, transparent 0%, black 100%);
  background-position:
    top,
    right,
    bottom,
    left;
  background-size:
    100% 10px,
    10px 100%,
    100% 10px,
    10px 100%;
  background-repeat:
    no-repeat,
    no-repeat,
    no-repeat,
    no-repeat;
  background-blend-mode:
    normal,
    normal,
    normal;
}

.content3 {
  margin: 25px;
  background-color: black;
  -webkit-mask-image:
    linear-gradient(to top, black 0%, black 100%),
    linear-gradient(to top, transparent 0%, black 100%),
    linear-gradient(to right, transparent 0%, black 100%),
    linear-gradient(to bottom, transparent 0%, black 100%),
    linear-gradient(to left, transparent 0%, black 100%);
  -webkit-mask-position:
    center,
    top,
    right,
    bottom,
    left;
  -webkit-mask-size:
    100% 100%,
    100% 10px,
    10px 100%,
    100% 10px,
    10px 100%;
  -webkit-mask-repeat:
    no-repeat,
    no-repeat,
    no-repeat,
    no-repeat,
    no-repeat;
   -webkit-mask-composite:
    source-out,
    source-over,
    source-over,
    source-over;
  mask-image:
    linear-gradient(to top, black 0%, black 100%),
    linear-gradient(to top, transparent 0%, black 100%),
    linear-gradient(to right, transparent 0%, black 100%),
    linear-gradient(to bottom, transparent 0%, black 100%),
    linear-gradient(to left, transparent 0%, black 100%);
  mask-position:
    center,
    top,
    right,
    bottom,
    left;
  mask-size:
    100% 100%,
    100% 10px,
    10px 100%,
    100% 10px,
    10px 100%;
  mask-repeat:
    no-repeat,
    no-repeat,
    no-repeat,
    no-repeat,
    no-repeat;
  mask-composite:
    subtract,
    add,
    add,
    add;
}
<div class="body">
  <div class="content1"></div>
  <span>-</span>
  <div class="content2"></div>
  <span>=</span>
  <div class="content3"></div>
</div>

第一个图像将整个框填充为黑色。

第二幅图像是使用该add操作合成剩余 4 个子图像的结果。此图像定义边缘应如何褪色。请注意,图像是反转的,即外边缘是纯黑色,而内边缘是透明的。

第三幅图像是通过从第一幅图像中减去第二幅图像而创建的。图像用作蒙版。

应用蒙版时,黑色像素表示不褪色元素像素,50% 透明度像素表示将元素像素褪色 50%,而 100% 透明度像素表示将元素像素褪色 100%(不可见)。

您可以通过调整子图像的属性来自定义效果:

  • mask-size要控制褪色的长度,请通过属性调整子图像的大小
  • 要进行非线性褪色,请在linear-gradient()声明中添加更多色标
  • 要使边缘不完全褪色,请为色标使用不太透明的颜色,例如rgba(0, 0, 0, 0.5)

推荐阅读