css 圆凹角_CSS如何实现内凹角效果_Houdini, CSS, gradient, masking, Vue, Vue组件, scooped-corners, CSS自定义属性 教程_w3cpl...

记得@Lea Verou的《CSS Secrets》一书和前几天@Chris Coyier刚发的帖子都介绍了CSS怎么实现元素斜切口的效果。我也尝试着借助Vue的能力,把这种效果构建成一个Vue组件。我把这种效果定义为外切口。而今天将要聊的是与其刚好相反的一个效果:CSS如何实现内凹角的效果。

上图展示的效果就是接下来所要聊的内凹角的效果。也就是说,通过下文的介绍,我们可以知道这种效果是如何做的,而且如何在多个元素上实现这样的内凹角效果。在实现这样的效果当中,将会遇到些什么棘手的问题,又是怎么绕过这些问题的。

最初的想法:box-shadow

对于box-shadow的属性,想必大家已经非常了解了,如果你从未接触过box-shadow属性,那么强烈建议您花一点时间去了解一下box-shadow相关的知识。这样能帮助你更好的理解后续的内容。

我先假设你对box-shadow有了一定的了解。就算你不了解,也没有关系。你也可以继续后面的内容。假设我们有一个div的元素。给这个元素添加了一个.box的类名:

我们可以显式的给这个.box元素设置大小或者通过其自己的内容来决定大小,不管是哪种方式,都并不很重要。这里为了简单起见,给其设置了max-width和min-height(也是用来设置其大小的)。另外为了能在浏览器中看到效果,其添加了一个outline的效果,让其看起来有边框的样子。或许你会问,为什么不直接使用border呢?这个问题留给大家去思考吧,因为不是这篇文章要探讨的内容。

.box {

outline: solid 2px;

max-width: 15em;

min-height: 10em;

}

接下来,通过伪元素::before来创建一个正方形,其边长等于圆角的直径(或者半径--r的两倍),而且对这个伪元素使用绝对定位。另外为了能在浏览器中看到效果,给这个伪元素添加了一个box-shadow和background属性。这只是用来辅助大家理解的,后续会删除的。

:root {

--r: 2em;

}

.box {

position: relative;

&::before {

content: '';

position: absolute;

padding: var(--r);

box-shadow: 0 0 7px #b53;

background: #95a;

}

}

特别声明:本文的实例代码都来自于@ANA TUDOR的《Scooped Corners in 2018》一文。不同的是我把文章中的Sass变量换成了CSS自定义变量。后续内容如无特别说明,都将类似的做了修改。

这个时候看到的效果如下:

效果如你所期望的一样。接下来对伪元素::before的border-radius值设置为50%,让它成为一个圆形,并且给它设置一个margin的负值,值等于它的半径--r。伪元素的中心点和它的父容器.box的左上角(0,0)重合。为了让溢出的.box的伪元素能隐藏起来,需要在.box中添加一个overflow:hidden。

:root {

--r: 2em;

}

.box {

position: relative;

overflow: hidden;

&::before {

content: '';

position: absolute;

padding: var(--r);

box-shadow: 0 0 7px #b53;

background: #95a;

margin: calc(var(--r) * (-1));

border-radius: 50%;

}

}

现在的结果是这样的:

但这样的效果仍然不是我们想要的。为了达到我们想要的效果,我们需要使用box-shadow的第四个参数值:box-shadow添加第四个参数值的效果,可以看下面这个Demo:

你可能已经猜到我们下一步要做什么了。把background和box-shadow前三个值(x和y轴的偏移值以及模糊半径)设置为0,并给box-shadow的扩展半径设置为一个较大的值。

box-shadow: 0 0 0 300px;

下面的这个示例演示了box-shadow的扩展半径如何让阴影效果覆盖容器更多的面积。

这里用到的一个技巧是让box-shadow有足够大的扩展半径,这样让伪元素的阴影能覆盖其容器更多的面积。这是非常有意思的一点,给.box设置box-shadow以及给其伪元素添加一个半透明的阴影效果。

.box {

overflow: hidden;

position: relative;

margin: .25em auto;

min-width: 15em;

max-width: 15em;

min-height: 10em;

border-radius: 1em;

&:before {

position: absolute;

margin: calc(var(--r) * -1);

padding: var(--r);

border-radius: 50%;

box-shadow: 0 0 0 300px rgba(#95a, .75);

content: ''

}

}

其实这是很关键的一步,如果你不仔细看,你或许会认为,那个凹角的效果是box-shadow实现的。或许你和我一样会纳闷,box-shadow是如何实现透明凹角的效果。事实并非如此,透明凹角部分是伪元素::before的background-color为transparent,而整个紫色部分是由::before的box-shadow实现的(就是阴影扩散半径有足够大的值,能铺满.box的容器大小)。我录一个视频给大家看看,或许能比文字更好的说明一切原理:

是不是一图胜过千言万语呀。

上面看到的效果,不难发现,凹角的大小是固定的。好在我们这里使用了CSS的自定义属性。因为使用CSS自定义属性之后,可以很容易的通过JavaScript来修改这个属性。这样一来,就可以很好的控制凹角的大小。比如:

:root { --r: 50px }

.box {

padding: var(--r);

&:before {

margin: calc(-1*var(--r));

padding: inherit;

}

}

这是实现凹角效果的关键样式。具体的不多说了,能只要仔细阅读上面的内容,你就能明白为什么。

值得一提的是,我们前面看到的效果都是.box中没有任何内容。也就是说.box里有内容的时候,我们是需要在样式上做一定的调整的。为什么这么说呢?先来看一个效果:

要解决这个问题,很简单,咱们只需要在.box的伪元素::before上添加z-index属性,并且给其设置值为-1。

另外通过.setProperty()来修改--r的值。这需要一些JavaScript代码来支持:

// 获取id为r的input元素 和 output元素

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值