当我看到 Chris 关于 凹槽盒 的文章时,我记得我之前遇到过一个挑战,要求以跨浏览器的方式用 CSS 实现如下所示的设计

它看起来与凹槽盒的概念非常相似,只是角现在是挖空的,我们只需要担心每个盒子的一个角。因此,让我们看看如何实现它,如何将该技巧扩展到多个角,会遇到哪些问题以及如何在不影响浏览器支持的情况下解决这些问题。
box-shadow
!
最初的想法:我们从一个盒子元素开始
<div class='box'></div>
我们可以给它一些尺寸,或者让它的尺寸由内容决定——这并不重要。为简单起见,我们只是在上面设置了 max-width
和 min-height
。我们还给它一个 outline
,以便我们能够看到它的边界。
.box {
outline: solid 2px;
max-width: 15em;
min-height: 10em;
}
接下来,我们将一个正方形的 ::before
伪元素绝对定位,其边长等于角部挖空的直径(或半径 $r
的两倍)。我们还给这个伪元素一个红色的 box-shadow
和一个虚拟的 background
(稍后我们将删除它),以便我们能够更好地看到它
$r: 2em;
.box {
position: relative;
/* same styles as before */
&:before {
position: absolute;
padding: $r;
box-shadow: 0 0 7px #b53;
background: #95a;
content: ''
}
}
到目前为止,这就是我们拥有的
查看 thebabydino 在 CodePen 上创建的 Pen。(@thebabydino)
嗯,它看起来还不够令人兴奋…… 不过!所以让我们继续,通过在上面设置 border-radius: 50%
将这个正方形变成一个圆盘,并给它一个等于其半径 $r
的负 margin
,以便它的中心点与父盒子的 (0,0)
点(左上角)重合。我们还在父盒子上设置 overflow: hidden
,以便将此伪元素在 .box
外部的任何部分裁剪掉。
$r: 2em;
.box {
overflow: hidden;
/* same styles as before */
&:before {
/* same styles as before */
margin: -$r;
border-radius: 50%
}
}
现在我们开始看到我们一直想要的形状了
查看 thebabydino 在 CodePen 上创建的 Pen。(@thebabydino)
但它仍然不是我们想要的。为了达到目的,我们使用 box-shadow
属性的第四个长度值:**扩展半径**。如果您需要复习一下 box-shadow
如何使用这四个值,您可以查看下面的交互式演示
查看 thebabydino 在 CodePen 上创建的 Pen。(@thebabydino)
您可能已经猜到我们接下来要做什么了。我们删除虚拟的 background
,将前三个 box-shadow
值(x 和 y 偏移量以及模糊半径)设为零,并为最后一个值(扩展半径)使用一个相当大的数字
box-shadow: 0 0 0 300px;
下面的交互式演示显示了如何通过增加扩展半径使其覆盖其父 .box
的越来越多的部分
查看 thebabydino 在 CodePen 上创建的 Pen。(@thebabydino)
因此,这里的技巧是拥有足够大的扩展半径以覆盖父元素的其余部分。这样做的好处是我们可以让 box-shadow
半透明或在父 .box
上具有圆角
.box {
/* same styles as before */
border-radius: 1em;
&:before {
/* same styles as before */
box-shadow: 0 0 0 300px rgba(#95a, .75);
}
}
查看 thebabydino 在 CodePen 上创建的 Pen。(@thebabydino)
当然,就像 Chris 在关于凹槽盒的文章中指出的那样,我们可以将挖空半径设为 CSS 变量,然后从 JavaScript 中轻松修改它。然后一切都会很好地更新,即使我们的盒子里有文本内容也是如此
:root { --r: 50px }
.box {
/* same styles as before */
padding: var(--r);
&:before {
/* same styles as before */
margin: calc(-1*var(--r));
padding: inherit;
}
请注意,当我们也有文本内容时,我们需要在 ::before
伪元素上设置一个负的 z-index
并明确地将其定位在角部,因为我们现在还在 .box
上有一个 padding
来补偿挖空。
.box {
/* same styles as before */
&:before {
/* same styles as before */
z-index: -1;
top: 0;
left: 0
}
查看 thebabydino 在 CodePen 上创建的 Pen。(@thebabydino)
应用此技巧
现在,让我们更进一步,看看如何应用此概念来重现我在开头显示的设计。在这种特定情况下,伪元素圆盘的中心点与盒子角不重合,而是在外部,位于盒子之间的空间中间。
使用的结构非常简单,只是一个 <header>
元素,后面跟着四个 <article>
元素,我在 Pug 循环中生成这些元素
while n--
article
h3 #{data[n].name}
section
p #{data[n].quote}
a(href='#') go
我们在 <body>
上使用一个包装 flexbox 布局,<header>
非常宽,并且每行有一个或两个 <article>
元素,具体取决于视口有多宽。

如果每行只有一个 <article>
,则没有挖角式边角,因此其半径为 0px
。否则,我们将此半径 --r
设置为非零值。
$min-w: 15rem; /* min width of an article element */
$m: 1rem; /* margin of such an element */
html { --r: 0px; }
article {
margin: $m;
min-width: $min-w;
width: 21em;
}
@media (min-width: 2*($min-w + 2*$m) /* enough for 2 per row */) {
html { --r: 4rem; }
article { width: 40%; }
}
现在,让我们只考虑每行有两个 <article>
元素的情况(当然,每个元素都有一个挖角式边角,因为这正是我们感兴趣的)。
在第一个元素的情况下,我们从圆盘最左边的限制开始,沿着其父元素的右边缘。到目前为止,它是 left: 100%
。为了将圆盘中心点的 x 坐标移动到其父元素的右边缘,我们减去圆盘的半径,这将我们带到 left: calc(100% - var(--r))
。但我们不希望它在右边缘,我们希望它向右偏移 <article>
边距 $m
,这将我们带到最终值
left: calc(100% - var(--r) + #{$m});
查看 thebabydino 在 CodePen 上创建的 Pen。(@thebabydino)
沿着 y 轴,我们从圆盘最顶部的限制开始,沿着其父元素的底边缘——即 top: 100%
。为了将圆盘的中心点放在父盒子的底边缘,我们将其向上移动一个半径,这将我们带到 top: calc(100% - var(--r))
。最后,我们希望此中心点位于父元素底边缘下方 $m
处,这将给我们最终的垂直偏移量
top: calc(100% - var(--r) + #{$m});
查看 thebabydino 在 CodePen 上创建的 Pen。(@thebabydino)
对于第二个 <article>
(同一行上的第二个),在垂直偏移量的情况下,我们具有相同的值。
查看 thebabydino 在 CodePen 上创建的 Pen。(@thebabydino)
然而,在水平方向上,我们从圆盘的左限制开始,沿着其父元素的左边缘——即 left: 0%
。为了将圆盘的中心点放在其父元素的左边缘,我们将其向左移动一个半径 --r
,从而得到 left: calc(0% - var(--r))
。但是,最终位置位于父元素左边缘左侧 $m
处
left: calc(0% - var(--r) - #{$m});
查看 thebabydino 在 CodePen 上创建的 Pen。(@thebabydino)
对于第三个 <article>
(最后一行上的第一个),我们沿 x 轴的偏移量与第一个元素的情况相同。
查看 thebabydino 在 CodePen 上创建的 Pen。(@thebabydino)
在垂直方向上,我们从圆盘的顶部限制开始,沿着其父元素的顶部边缘——即 top: 0%
。为了将圆盘的中心点放在父元素的顶部边缘,我们将其向上移动一个半径 --r
,从而得到 top: calc(0% - var(--r))
。但是我们希望它位于父元素顶部边缘上方 $m
处,因此最终的顶部偏移量为
top: calc(0% - var(--r) - #{$m});
查看 thebabydino 在 CodePen 上创建的 Pen。(@thebabydino)
对于最后一个(最后一行上的第二个),我们具有与上方的元素相同的水平偏移量,以及与同一行左侧的元素相同的垂直偏移量。
查看 thebabydino 在 CodePen 上创建的 Pen。(@thebabydino)
因此,我们的偏移量可以写成
article:nth-of-type(1) { /* 1st */
left: calc(100%/* 2*50% = (1 + 1)*50% = (1 + i)*50% */ - var(--r) + /* i=+1 */#{$m});
top: calc(100%/* 2*50% = (1 + 1)*50% = (1 + j)*50% */ - var(--r) + /* j=+1 */#{$m});
}
article:nth-of-type(2) { /* 2nd */
left: calc( 0%/* 0*50% = (1 - 1)*50% = (1 + i)*50% */ - var(--r) - /* i=-1 */#{$m});
top: calc(100%/* 2*50% = (1 + 1)*50% = (1 + j)*50% */ - var(--r) + /* j=+1 */#{$m});
}
article:nth-of-type(3) { /* 3rd */
left: calc(100%/* 2*50% = (1 + 1)*50% = (1 + i)*50% */ - var(--r) + /* i=+1 */#{$m});
top: calc( 0%/* 0*50% = (1 - 1)*50% = (1 + j)*50% */ - var(--r) - /* j=-1 */#{$m});
}
article:nth-of-type(4) { /* 4th */
left: calc( 0%/* 0*50% = (1 - 1)*50% = (1 + i)*50% */ - var(--r) - /* i=-1 */#{$m});
top: calc( 0%/* 0*50% = (1 - 1)*50% = (1 + j)*50% */ - var(--r) - /* j=-1 */#{$m});
}
这意味着圆盘中心点的位置取决于 <article>
元素之间的间隙(此间隙是我们在其上设置的 margin: $m
的两倍)、圆盘半径 r
以及几个水平和垂直乘数(分别为 --i
和 --j
)。这两个乘数最初都为 -1
。
对于前两个 <article>
元素(2x2
网格的第一行),我们将垂直乘数 --j
更改为 1
,因为我们希望圆盘中心点的 y 坐标位于底部边缘下方,而对于奇数元素(第一列),我们将水平乘数 --i
更改为 1
,因为我们希望 x 坐标位于右边缘右侧。
html { --i: -1; --j: -1 } /* multipliers initially set to -1 */
h3, section {
&:before {
/* set generic offsets */
top: calc((1 + var(--j))*50% - var(--r) + var(--j)*#{$m});
left: calc((1 + var(--i))*50% - var(--r) + var(--i)*#{$m});
}
}
@media (min-width: 2*($min-w + 2*$m)) {
article {
/* change vertical multiplier for first two (on 1st row of 2x2 grid) */
&:nth-of-type(-n + 2) { --j: 1 }
/* change horizontal multiplier for odd ones (on 1st column) */
&:nth-of-type(odd) { --i: 1 }
}
请注意,我们只在前两个 <article>
元素的 <section>
元素上以及最后两个元素的 <h3>
上具有可见的圆盘挖空。因此,对于前两个 <article>
元素,标题的 ::before
伪元素上的半径 --r
为 0
,而对于最后两个元素,部分的 ::before
伪元素上的此半径为 0
@media (min-width: 2*($min-w + 2*$m)) {
article {
&:nth-of-type(-n + 2) h3,
&:nth-of-type(n + 3) section { &:before { --r: 0 ; } }
}
}
以类似的方式,我们向 <article>
元素的子元素添加了不同的填充
$p: .5rem;
h3, section { padding: $p; }
@media (min-width: 2*($min-w + 2*$m)) {
article {
&:nth-of-type(-n + 2) section,
&:nth-of-type(n + 3) h3 {
padding-right: calc(.5*(1 + var(--i))*(var(--r) - #{$m}) + #{$p});
padding-left: calc(.5*(1 - var(--i))*(var(--r) - #{$m}) + #{$p});
}
}
}
这有助于我们获得我们想要的结果
查看 thebabydino 在 CodePen 上创建的 Pen。(@thebabydino)
上述演示在所有主要浏览器的当前版本中均有效,如果我们可以使用重复而不是使用 CSS 变量,我们可以将支持一直扩展到 IE9。
上述方法的潜在问题
虽然这是一种快速简便的跨浏览器方法,可以在这种特定情况下获得期望的结果,但我们可能并不总是能如此幸运地使用这种方法。
首先,我们需要为每个挖空的角创建一个伪元素,所以如果我们希望所有角都具有这种效果,则需要引入一个额外的元素。可怜的熊猫。
其次,我们可能并不总是希望使用纯色的background
。我们可能希望使用半透明的(如果我们想要多个挖空的角,就会变得很难实现),渐变的(虽然我们可以用box-shadow
模拟一些径向渐变,但这不是一个理想的解决方案),甚至是一个图像background
(几乎无法实现,唯一的解决方案是使用mix-blend-mode
,而这会导致失去对Edge的支持,并且没有优雅的回退方案)。
对于非常大的盒子,我们设置的扩散范围不够怎么办?糟糕。
因此,让我们探索其他更可靠的方法,这些方法具有不同程度的浏览器支持。
灵活性和良好的浏览器支持?使用SVG吧!
这可能并不奇怪,但如果我们想要一个灵活且可靠的跨浏览器解决方案,完整的SVG解决方案效果最好。这种解决方案涉及在盒子内容之前使用一个SVG元素。这个SVG包含一个<circle>
,我们在这个圆上设置了一个半径r
属性。
<div class='box'>
<svg>
<circle r='50'/>
</svg>
TEXT CONTENT OF BOX GOES HERE
</div>
我们在这个盒子内绝对定位这个SVG,并将其大小调整为完全覆盖其父元素。
.box { position: relative; }
svg {
position: absolute;
width: 100%;
height: 100%;
}
到目前为止,没什么太有趣的,所以让我们给<circle>
一个id
,并在其他角复制它。
<circle id='c' r='50'/>
<use xlink:href='#c' x='100%'/>
<use xlink:href='#c' y='100%'/>
<use xlink:href='#c' x='100%' y='100%'/>
请注意,如果我们想要排除一个或多个角,我们只需不复制它到那里。
查看thebabydino在CodePen上的Pen(@thebabydino)。
好吧,但我们在这里所做的是在角上创建圆圈,而我们真正想要的是……完全相反的东西!接下来,我们将这些圆圈放在一个<mask>
中,覆盖在一个白色、全尺寸(覆盖整个SVG)的矩形上,然后在另一个全尺寸矩形上使用这个mask
。
<mask id='m' fill='#fff'>
<rect id='r' width='100%' height='100%'/>
<circle id='c' r='50' fill='#000'/>
<use xlink:href='#c' x='100%'/>
<use xlink:href='#c' y='100%'/>
<use xlink:href='#c' x='100%' y='100%'/>
</mask>
<use xlink:href='#r' fill='#f90' mask='url(#m)'/>
结果如下所示。
查看thebabydino在CodePen上的Pen(@thebabydino)。
如果我们有文本,我们需要根据角半径调整盒子的padding
,将其设置为与SVG圆圈的半径相同的值,并使用JavaScript保持它们同步。
查看thebabydino在CodePen上的Pen(@thebabydino)。
当然,我们背景矩形的fill
不必是纯色。它可以是半透明的(就像上面演示中那样),或者我们可以使用SVG渐变或图案。后者还可以让我们使用一个或多个背景图像。
查看thebabydino在CodePen上的Pen(@thebabydino)。
但我来这里是为了CSS糖果!
好吧,很高兴你问!我们可以做很多事情来将遮罩方法的权重从SVG转移到CSS。
遗憾的是,这些方法都不是跨浏览器的,但它们简化了事情,并且绝对值得在不久的将来或更远的将来关注。
改为在HTML元素上使用CSS遮罩
我们在这里所做的是从SVG中移除mask
之外的所有内容。然后,从CSS中,我们设置一个background
(可以是半透明的、CSS渐变、图像、多个背景的组合……任何CSS可以提供的)和.box
元素上的mask
属性。
.box {
/* any kind of background we wish */
mask: url(#m);
}
请注意,目前只有Firefox支持在HTML元素上设置内联SVG遮罩!

.box
的版本(实时演示,仅限Firefox)。从CSS设置圆圈半径
这意味着从我们的<circle>
中移除r
属性,并在CSS中将其设置为与盒子填充相同的变量。
.box { padding: var(--r); }
[id='c'] { r: var(--r); }
这样,当我们更改--r
的值时,挖空的半径和.box
内容周围的padding
都会更新!
请注意,目前只有Blink浏览器支持从CSS设置SVG元素的几何属性!

<circle>
半径的版本(实时演示,仅限Blink)。结合前两种方法
虽然这会很酷,但遗憾的是,目前在任何浏览器中都无法实现。但好消息是,我们可以做得更好!
使用CSS渐变进行遮罩
请注意,目前Edge根本不支持在HTML元素上使用CSS遮罩,尽管它被列为“开发中”,并且已经出现在about:flags
中(目前不起作用)的标志。
我们完全放弃SVG部分,开始构建我们的CSS渐变mask
。我们使用径向渐变在盒子的角上创建圆圈。以下CSS在盒子的左上角创建了一个半径为--r
的圆圈。
.box {
background: radial-gradient(circle at 0 0, #000 var(--r, 50px), transparent 0);
}
您可以在下面的演示中看到它,我们还在盒子上添加了一个红色的轮廓,以便我们可以看到它的边界。
查看thebabydino在CodePen上的Pen(@thebabydino)。
我们对mask
使用完全相同的渐变。
.box {
/* same as before */
/* any CSS background we wish */
mask: radial-gradient(circle at 0 0, #000 var(--r, 50px), transparent 0);
}
请注意,WebKit浏览器仍然需要为mask
属性添加-webkit-
前缀。
然后,我们在其他角添加圆圈。
$grad-list: radial-gradient(circle at 0 0 , #000 var(--r, 50px), transparent 0),
radial-gradient(circle at 100% 0 , #000 var(--r, 50px), transparent 0),
radial-gradient(circle at 0 100%, #000 var(--r, 50px), transparent 0),
radial-gradient(circle at 100% 100%, #000 var(--r, 50px), transparent 0);
.box {
/* same as before */
/* any CSS background we wish */
mask: $grad-list
}
这令人难以置信地重复,要么需要写很多代码,要么需要复制粘贴很多,所以让我们看看我们能做些什么。
首先,我们为停止列表使用CSS变量。这消除了生成的CSS中的重复。
$grad-list: radial-gradient(circle at 0 0 , var(--stop-list)),
radial-gradient(circle at 100% 0 , var(--stop-list)),
radial-gradient(circle at 0 100%, var(--stop-list)),
radial-gradient(circle at 100% 100%, var(--stop-list));
.box {
/* same as before */
/* any CSS background we wish */
--stop-list: #000 var(--r, 50px), transparent 0;
mask: $grad-list;
}
但这并没有好多少,所以让我们在循环中生成角。
$grad-list: ();
@for $i from 0 to 4 {
$grad-list: $grad-list,
radial-gradient(circle at ($i%2)*100% floor($i/2)*100%, var(--stop-list));
}
.box {
/* same as before */
/* any CSS background we wish */
--stop-list: #000 var(--r, 50px), transparent 0;
mask: $grad-list;
}
就代码而言,这要好得多,因为现在我们不必多次编写任何内容,并且避免了以后可能无法在所有地方更新的风险。但到目前为止的结果并非我们想要的结果。

在这里,我们剪掉了除了角之外的所有内容,这与我们想要的结果相反。
我们可以做的一件事是反转渐变,使角圆圈transparent
,其余部分为black
,使用
--stop-list: transparent var(--r, 50px), #000 0;
当我们只对一个角使用一个渐变时,这可以解决问题。

但是,当我们将所有四个(甚至只是两个)叠加在一起时,我们会得到一个与盒子大小相同的black
矩形作为mask
,这意味着实际上没有任何内容被遮罩了。

因此,我们将每个渐变限制在盒子的四分之一——width
的50%
和height
的50%
,从而为每个获得25%
(四分之一)的区域。
这意味着我们还需要设置mask-size
为50% 50%
,mask-repeat
为no-repeat
,并将每个mask-image
定位到所需的角。
$grad-list: ();
@for $i from 0 to 4 {
$x: ($i%2)*100%;
$y: floor($i/2)*100%;
$grad-list: $grad-list
radial-gradient(circle at $x $y, var(--stop-list)) /* mask image */
$x $y; /* mask position */
}
.box {
/* same as before */
/* any CSS background we wish */
--stop-list: transparent var(--r, 50px), #000 0;
mask: $grad-list;
mask-size: 50% 50%;
mask-repeat: no-repeat;
}
请注意,WebKit浏览器仍然需要为mask
属性添加-webkit-
前缀。
但这里最大的问题是……一般来说,除法和四舍五入的问题——我们的四个部分加在一起并不总是能够再次构成一个整体,因此它们之间会出现间隙。

好吧,我们并不是不能用细长的linear-gradient()
条纹来覆盖这些间隙,或者将mask-size
增加到比如51%
。

mask-size
可以解决间隙问题(在线演示)。但是,有没有更优雅的方法呢?
嗯,如果我们在恢复到全尺寸渐变层时将其设置为intersect
,则可以使用mask-composite
属性来帮助我们。
$grad-list: ();
@for $i from 0 to 4 {
$grad-list: $grad-list,
radial-gradient(circle at ($i%2)*100% floor($i/2)*100%, var(--stop-list));
}
.box {
/* same as before */
/* any CSS background we wish */
--stop-list: transparent var(--r, 50px), #000 0;
mask: $grad-list;
mask-composite: intersect;
}
这非常酷,因为它是一个纯CSS解决方案,无需SVG,但不太好的消息是,支持仅限于Firefox 53+。

mask-composite: intersect
的结果(在线演示)。但是,我们至少有非标准的-webkit-mask-composite
替代方案(取不同的值!)用于WebKit浏览器。因此,这比我们在涉及挖角时拥有的最终选项的支持要好得多。
corner-shape
选项
Lea Verou大约五年前提出了这个想法,甚至为它创建了一个预览页面。遗憾的是,它不仅还没有被任何浏览器实现,而且规范在此期间也没有取得太大进展。它仍然是未来需要牢记的东西,因为它提供了很大的灵活性,代码很少——重新创建我们的效果只需要以下内容
padding: var(--r);
corner-shape: scoop;
border-radius: var(--r);
没有标记冗余,没有冗长的渐变列表,只有这段非常简单的CSS代码。也就是说……当它最终得到浏览器的支持时!
说到
corner-shape
选项,CSS Houdini Paint API将有助于对其进行polyfill,如这里所示https://lab.iamvdo.me/houdini/corner-shape负面的是,这将是一个JS解决方案。
有一种更简单的方法来处理box-shadow技巧中的这些box-shadow位置。与其进行那些非常复杂的位置计算,不如改用translate转换。
以下是如何放置右下角:(仅包含定位代码)
嗯……恕我不同意。
首先,它们没有放置在角上。它们放置在角落外,距离为
$m
,该距离不依赖于盒子的尺寸(因此您不能以%
表示并将其混合到偏移量中)或铲斗半径的尺寸(因此您不能以%
表示并将其混合到平移量中)。因此,您要么必须无论如何使用calc()
,要么添加margin
(这意味着您将使用4个属性而不是仅2个属性来获得相同的结果)。其次,将转换用于初始2D定位是最好避免的事情(确实有其有效的用例,但这绝对不是其中之一),即使现在CSS变量已跨浏览器支持并且它们可以使此问题不那么严重。问题是,您可能希望这些铲斗不是圆形的,而是用诸如倾斜之类的元素修改其形状。但是,如果您已经将
transform
用于定位,则需要将倾斜链接到平移。如果您想动画化倾斜,则需要在每个该死的关键帧中都链接该平移——太糟糕了!第三,您只提供了一个角的示例。其他角落呢?如果您想编写可维护的代码,该代码不会在您进行更改时被弄乱,您仍然需要想出一个对所有四个角都有效的公式,因此您又回到了这些计算,无论您是将所有内容都放在偏移量中并节省
transform
属性以备将来真正需要时使用,还是愚蠢地浪费它。如果您有一个统一的所有角的公式,那么以后您只需要在一个地方更改一次。如果您认为坐下来思考一下以想出一个统一的公式太复杂了,那么祝您好运,以后永远不要在四个不同的地方更改相同的事物四次时出错。我个人不喜欢编写懒惰且容易出错的代码。我宁愿在编写代码之前坐下来思考一下,并想出一个健壮而有效的解决方案。PS – 再一次,如果没有必要,请不要链接转换。
translate(-50%, -50%)
与translateX(-50%) translateY(-50%)
完全相同。尽管这是一个愚蠢的尝试,但我认为这也可以通过使用
radial-gradient
以及上面的linear-gradient
来实现。使用这种方法,也可以使用一些linear-gradient
作为背景。此外,还有另一种可能更优雅的方法
.box {
box-sizing: border-box;
width: 30rem;
min-height: 20rem;
margin: 5rem auto 0;
padding: 2rem;
–rad-col: #0000ff;
text-align: center;
color: #f1f1f1;
background-color: #0000ff00;
background: radial-gradient(circle at top left, transparent 10%, red 0), radial-gradient(circle at top right, transparent 10%, var(–rad-col) 0), radial-gradient(circle at bottom right, transparent 10%, var(–rad-col) 0), radial-gradient(circle at bottom left, transparent 10%, var(–rad-col) 0);
background-position: top left, top right, bottom right, bottom left;
background-size: 50% 50%;
background-repeat: no-repeat;
}
哦,是的,这绝对是可能的,但我选择不在文章中包含它。
首先,因为这是一种已经写过的方案(Lea在……什么,2010年写过一篇关于它的文章?)并且我在某些地方见过它被使用,我想专注于我以前没有解释过的技术(由于我倾向于详细解释,我总是担心文章会变得太长,以至于任何人都无法阅读)。
其次,由于渐变的渲染问题。渲染问题是指这(该死,Chrome,不敢相信它还没有修复)以及我用于遮罩渐变的那些间隙。虽然在遮罩渐变的情况下问题不大,因为我始终可以使用
background-size: 51% 51%
技巧……但在半透明背景的情况下,此技巧会导致重叠。但是,如果您对铲斗使用非锐利过渡技巧并具有纯色
background
或知道元素的尺寸,则这绝对是一种可能性。因为这样您就可以使用一个radial-gradient()
,并使用适当的background-position
,该位置在水平方向上是已知width
的一半,在垂直方向上是已知height
的一半。类似这样
在线结果.