假设您正在尝试实现一种设计效果,其中元素的角被切掉了。也许你是 《太空堡垒卡拉狄加》的粉丝?或者也许您只是喜欢这种不寻常的效果,因为它避免了看起来像一个典型的矩形。

我怀疑有很多方法可以做到这一点。当然,您可以使用 多个背景 在角落放置图像。您也可以在背景中使用一个灵活的 SVG 形状。我敢肯定,还有一种奇特的方法可以使用渐变来实现它。
但是,我喜欢简单地拿起剪刀剪掉那些该死的角的想法。多亏了 clip-path
,我们实际上可以做到这一点。我们可以使用 polygon()
函数,提供 X
和 Y
坐标的列表,并剪掉它们外部的内容。
看看如果我们列出三个点会发生什么:中间顶部、底部右侧、底部左侧。
.module {
clip-path:
polygon(
50% 0,
100% 100%,
0 100%
);
}

让我们不要只列出三个点,而是列出带缺口角所需的全部八个点。我们可以使用像素,但这很危险。我们可能并不真正知道元素的像素宽度或高度。即使我们知道,它也可能发生变化。所以,这里使用百分比表示
.module {
clip-path:
polygon(
0% 5%, /* top left */
5% 0%, /* top left */
95% 0%, /* top right */
100% 5%, /* top right */
100% 95%, /* bottom right */
95% 100%, /* bottom right */
5% 100%, /* bottom left */
0 95% /* bottom left */
);
}

这可以,但是请注意缺口没有形成完美的 45 度角。这是因为元素本身不是正方形。元素越不像正方形,情况就越糟糕。
我们可以使用 calc()
函数来解决这个问题。我们必须在需要的时候使用百分比,但只需从百分比中减去即可获得所需的位置和角度。
.module {
clip-path:
polygon(
0% 20px, /* top left */
20px 0%, /* top left */
calc(100% - 20px) 0%, /* top right */
100% 20px, /* top right */
100% calc(100% - 20px), /* bottom right */
calc(100% - 20px) 100%, /* bottom right */
20px 100%, /* bottom left */
0 calc(100% - 20px) /* bottom left */
);
}
你知道吗?这个数字被重复了太多次,我们不妨把它定义为一个 变量。如果以后需要更新这个数字,我们只需要更改一次,而不是所有这些单独的时间。
.module {
--notchSize: 20px;
clip-path:
polygon(
0% var(--notchSize),
var(--notchSize) 0%,
calc(100% - var(--notchSize)) 0%,
100% var(--notchSize),
100% calc(100% - var(--notchSize)),
calc(100% - var(--notchSize)) 100%,
var(--notchSize) 100%,
0% calc(100% - var(--notchSize))
);
}
发布吧。
查看 CodePen 上 Chris Coyier 的 带缺口的盒子 (@chriscoyier)。
这可能不言而喻,但请确保您有足够的填充来处理裁剪。如果您想变得更花哨,您也可以在填充值中使用 CSS 变量,这样您剪掉的越多,填充就越多。
但也许不要立即发布?IE/Edge 似乎在任何版本中都不支持 clip-path。 https://caniuse.cn/#search=clip-path
所以角落就不会有缺口,对吧?好吧。但这并不意味着不要这样做。
如果您知道盒子的尺寸或至少它的纵横比,您可以在文本内容后面使用 旋转的伪元素。我已经使用了 CSS 变量来保持代码 DRY,但是您可以使用完整的 Sass 路线,不使用 CSS 变量,然后我相信支持应该可以追溯到 IE9(还没有实际测试)。
回到现在,如果您想加快 Edge 中功能的实现,请在他们的开发者反馈跟踪器中投票,因为投票确实很重要。以下是
clip-path
的页面。我喜欢这种效果,但您需要为 safari 添加前缀。(也许在 codepen 中打开“autoprefixer”)
非常棒!谢谢
有人可以添加使用 SVG clip-path 的示例,以实现更广泛的浏览器支持吗?
对于只想在右上角添加缺口的人
不错。CSS Tricks 上真正的 CSS 技巧。:-)
您是否有方法在这个技巧中也使用盒子阴影?因为我想用它!
我发誓我在最初测试时用
filter: drop-shadow()
使其生效,但现在却无法弄清楚。如果您真的需要阴影,可能值得探索其他可能性,例如在内容后面放置一个绝对定位的、灵活的 SVG 元素。过滤器是在
clip-path
之前应用的,因此,一般来说,解决方案是在被剪切元素的父元素上设置drop-shadow()
过滤器。在这种情况下,我将在覆盖整个盒子的绝对定位的
::before
伪元素上设置background
和clip-path
,然后在实际的盒子中应用filter
。工作演示。我更改了以下内容
在盒子中设置
position: relative
和drop-shadow()
过滤器添加了一个绝对定位的
::before
,覆盖了它的父盒子(top: 0; right: 0; bottom: 0; left: 0;
),我想让它显示在文本内容之前(z-index: -1
)将
background
和clip-path
移动到这个伪元素我在 7 年前写过关于如何用渐变实现这一点的文章。在所有地方都能使用,不需要太多代码,而且
filter: drop-shadow()
也可以正常工作,因为您没有剪切形状。 http://lea.verou.me/2011/03/beveled-corners-negative-border-radius-with-css3-gradients/我们还在努力通过 corner-shape 属性将此添加到 CSS 中,但实现兴趣一直很小。
这就是
corner-shape: bevel
的用途。(notch
不同。)Lea Verou 的想法怎么样了?它已经进入了规范的第 4 级 https://drafts.csswg.org/css-backgrounds-4/#corner-shaping,但据我所知,还没有浏览器支持它。Can I use 还没有列出它。
我一直试图用透明背景和边框实现这一点。我可能不得不坚持使用某种版本的 svg!有什么想法吗?
使用这篇博文中介绍的
clip-path
,您需要在绝对定位的伪元素上设置背景,并使用 此技术 剪切掉它的内部部分。这样,您将得到一个“边框”。这是一行代码:https://codepen.io/anon/pen/yKMOqm
background: radial-gradient(ellipse, #f06d06 93.7%, rgba(0, 0, 0, 0) 94%);
但这并不是完美的像素解决方案。
一个很好的资源,可以帮助您塑造您的想法并享受使用 clip-path 的乐趣。
http://bennettfeely.com/clippy/
https://jsfiddle.net/frownonline/1hov6jp2/ ::before 和 ::after 对我来说很有效…