透明边框圆形图标在背景上

9

我该如何在CSS中实现这样的效果?

目标

我尝试了很多方法,但是深色背景仍然挡住了它,无法剪切,因此它下面的背景图片是不可见的...

.item {
  position: relative;
}
    
.item:before {
  content: '';
  size(100%);
  top: 0;
  left: 0;
  z-index: 1;
  background: rgba(0, 0, 0,0 0.1);
}
<div class="item">
   <img>
   <span class="rate">
     <span class="amount">10</span> امتیاز
   </span>
</div>  

我正在寻找一种方法,可以使黑色背景的部分变为透明,以便能够看到图像。

一个方案是:使用径向渐变来创建覆盖效果,这样你可以获得相同的效果,而不必依赖于任何新的和可疑支持的浏览器特性。 - DBS
圆形或背景使用径向渐变? - Amin
对于黑暗叠加,我将在答案中提供一个示例。 - DBS
您想奖励现有的答案还是对当前所有答案都不满意? - Temani Afif
4个回答

9
使用径向渐变可以实现这一目标,(示例已拆分为多行以便于阅读)。
background-image: radial-gradient(
   /* Position the circle at the center, 40px from the top */
  circle at center 40px,
  /* The center of the radius should be dark */
  rgba(0,0,0,0.4) 0%,
  /* This is the inner edge of the circle, we transition from dark-transparent between pixels 30 and 31 */
  rgba(0,0,0,0.4) 30px, rgba(0,0,0,0) 31px, 
  /* This is the outer edge of the circle, we transition back from transprent-dark between pixels 34 and 35*/
  rgba(0,0,0,0) 34px, rgba(0,0,0,0.4) 35px,  
  /* Everything outside of the circle should be dark */
  rgba(0,0,0,0.4) 100%
);

circle at center 40px指定了圆形相对于父元素的位置(水平居中,距离顶部向下40像素),请记住这是圆心的位置,因此您需要考虑其半径。

我们在渐变之间使用非常小的步长,使其看起来像实线而不是模糊的渐变(我发现1px的差异有助于防止线条上的锯齿,并使一切看起来更加平滑)。

您可以通过更改渐变中的30px31px34px35px值来调整圆的大小或线条的粗细。

工作示例:

.item {
  position: relative;
  width: 200px;
  height: 200px;
  background: url(https://picsum.photos/seed/picsum/200/200);
}

.item:before {
  position: absolute;
  content: '';
  top: 0;
  left: 0;
  bottom: 0;
  right: 0;
  z-index: 1;
  /* This is the ring itself, you can adjust it's size using the pixel values, leaving 1px differnce usually leaves the best result for smooth edges */
  background-image: radial-gradient(circle at center 40px, rgba(0, 0, 0, 0.4) 0%, rgba(0, 0, 0, 0.4) 30px, rgba(0, 0, 0, 0) 31px, rgba(0, 0, 0, 0) 34px, rgba(0, 0, 0, 0.4) 35px, rgba(0, 0, 0, 0.4) 100%);
}
<div class="item"></div>

(此方法与自2010年以来发布的几乎所有浏览器兼容)


5

overflow: hidden; 的无限阴影效果,我不知道对你是否有用,我只是尝试了一下 -

<style>
  .item img {
    max-width: 100%;
    vertical-align: top;
  }

  .item {
    font-family: 'Amiri', serif;
    width: 300px;
    margin: 20px auto;
    overflow: hidden; /* STEP-1 */
    position: relative;
  }

  .rate {
    position: absolute;
    width: 100px;
    height: 100px;

    border-radius: 100%;
    background: rgba(0,0,0,.7);
    top: 80px;
    left: 50%;
    transform: translatex(-50%);
    display: flex;
    flex-direction: column;
    align-items: center;
    justify-content: center;
    font-size: 22px;
    color: #fff;
  }

  .rate::before {
    position: absolute;
    content: '';
    width: calc(100% + 10px);
    height: calc(100% + 10px);
    top: -5px;
    left: 50%;
    transform: translatex(-50%);
    border-radius: 100%;
    box-shadow: 0 0 0 100vh rgba(0,0,0,.7); /* STEP-2 */
  }

  .amount {
    font-size: 20px;
    font-weight: 700;
    display: block;
  }
</style>



<link href="https://fonts.googleapis.com/css2?family=Amiri:wght@400;700&display=swap" rel="stylesheet">

<div class="item">
   <img src="https://images.pexels.com/photos/4888690/pexels-photo-4888690.jpeg?auto=compress&cs=tinysrgb&dpr=2&h=650&w=940" alt="Card title">
   <span class="rate">
     <span class="amount">١٠</span> امتیاز
   </span>
</div>


刚刚发现box-shadow中的扩散值可以使用vwvh单位,所以我更新了我的演示。这意味着这个演示的技巧比以前更加动态。 - Tanim

2
您可以使用几个带有 position: absolute 属性的 div 元素:

body {
  margin: 0;
}

.container {
  display: flex;
  justify-content: center;
  align-items: center;
}

.bg {
  height: 100vh;
  width: 100%;
  background-image: url('https://i.ytimg.com/vi/fqumdSlyLxg/maxresdefault.jpg');
  filter: brightness(0.4);
}

.circle {
  position: absolute;
  height: 150px;
  width: 150px;
  border-radius: 50%;
  backdrop-filter: brightness(5);
  -webkit-backdrop-filter: brightness(5);
  z-index: 0;
}

.inner-circle {
  position: absolute;
  height: 142px;
  width: 142px;
  border-radius: 50%;
  backdrop-filter: brightness(0.2);
  -webkit-backdrop-filter: brightness(0.2);
  z-index: 1;
}

.rate {
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: space-evenly;
  position: absolute;
  height: 142px;
  color: white;
  z-index: 2;
}

.amount {
  font-size: 30px;
  border-radius: 50%;
  text-shadow: 0px 0px 5px #fff;
}
<div class="container">
  <div class="bg"></div>
  <div class="circle"></div>
  <div class="inner-circle"></div>
  <div class="rate">
    <span class="amount">10</span>
    <span class="amount">امتیاز</span>
  </div>
</div>

使用backdrop-filter属性设置亮度,并在容器上使用display: flex使所有内容居中,然后对于文本使用text-shadow使其发光。

2
看起来不错,不幸的是 backdrop-filter 只有全球约 50% 的支持率。你知道有什么替代方法可以达到相同的效果吗? - Rene van der Lende
添加了“-webkit-”前缀,这意味着它可以在Safari、Edge、Chrome和Opera中使用。只有Firefox和IE似乎不喜欢它。 - Daniel_Knights
1
你做得很好,但我猜属性需要一段时间才能生效。看看我的替代方案...试试吧;-)...使用background-blend-mode和透明颜色。 - Rene van der Lende

0
作为替代方案,我将.item及其子元素设置为Flexbox容器,以便轻松定位。
圆圈只是一个带边框的圆形元素。
现在你所要做的就是调整大小、颜色和透明度。
为了好玩,我添加了一些:hover效果...
带有注释的片段

/* All are FBL containers, for easy positioning */
.item, .item>*, .rate {
    display: flex;
    justify-content: center; align-items: center;
}
.rate { flex-direction: column }

/* item content */
.item {
    position: relative; /* position child elements to this parent */
    width: 400px;
    height: 600px;

    /* set image to background of item */
    background-image: url("https://i.ytimg.com/vi/fqumdSlyLxg/maxresdefault.jpg");
    background-repeat: no-repeat;
    background-size: cover;             /* clip/stretch when too large/small */

    background-color: rgba(0,0,0,0.3);  /* some tranparent black */
    background-blend-mode: overlay;     /* mix bg-color with image */

    /* eye-candy */
    margin: 5rem auto; /* center */

    font-size: 1.5em;
    font-weight: bold;
    color: rgba(255,255,255,.6);
    border-radius: 12px;
}

.item>* {
    position: absolute; /* position child inside parent */
    width : 100px; height: 100px;
    
    opacity: 0.7;
}

.rate { text-shadow: 0px 0px 7px rgba(255,255,255,.8) }

.circle { 
    border: 5px solid rgba(255,255,255,.3);
    border-radius: 50%;

    filter: blur(1px);
}

/******************************/
/* HOVER eye-candy, demo only */
/******************************/
.item:hover {
    background-blend-mode: normal;
    color: rgba(255,255,255,1);
}

.item:hover>* {
    opacity: 1;
}
.item:hover .circle {
    border-color: rgba(255,255,255,.8);
}


/* demo eye-candy */
.item {
    /* GMC elevation 1dp */
    box-shadow: 0px 2px 1px -1px rgba(0,0,0,.20),
                0px 1px 1px  0px rgba(0,0,0,.14),
                0px 1px 3px  0px rgba(0,0,0,.12);
}
.item:hover {
    transform: scale(1.01);
    /* GMC elevation 3dp */
    box-shadow: 0px 3px 3px -2px rgba(0,0,0,.20),
                0px 3px 4px  0px rgba(0,0,0,.14),
                0px 1px 8px  0px rgba(0,0,0,.12);
}
/*.item:active:not(:focus) { transform: scale(1) }/* enable for some animation */
<div class="item">
    <div class="circle"></div>
    <div class="rate">
        <span class="amount">10</span>
        <span>text</span>
    </div>
</div>


不错,但它不透明,你无法清晰地看到背景图片。 - Amin
不确定您的意思,但这在火狐、谷歌和 Edge 上都可以正常工作。so63035636-1.jpg - Rene van der Lende
请查看第一篇帖子中的截图,重点是圆圈必须切割深色背景,就像我们从深色背景中分离出一个圆圈。 - Amin
在我制作的所有模糊和不透明度效果中,很难看出圆形和文本确实按照您的意图被剪切。我将调整代码片段并使效果更加清晰。使用background-blend-modemix-blend-mode,您可以使用颜色黑色(使用叠加、相乘)和白色(使用屏幕、强光、柔光)来增强/降低元素(或图像)的暗度和亮度,类似于Photoshop中的图层蒙版或老式照片冲洗中的Dodge&Burn。混合模式非常强大,但许多人不知道如何使用它们。我会回来发布一个迷你教程。 - Rene van der Lende

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接