CSS3 如何实现圆角的 outline 效果

本贴最后更新于 2506 天前,其中的信息可能已经沧海桑田

一、首先,outline 是个很牛逼的东西

温故而知鑫,10 年的时候写过一篇可用性方面的文章:“页面可用性之 outline 轮廓外框的一些研究”,还算挺有用的;3 年之后,也就是 13 年,介绍了个没什么使用价值的东西:“纯 CSS 实现的 outline 切换 transition 动画效果”。

个把星期前,微博上抛出了个问题:

有没有什么方法利用 CSS 以及使用一层标签实现下面这个加号效果,【不能使用::before, ::after 伪元素实现】【box-shadow 效果不好,我试过了,小尺寸 IE 会糊边】,兼容 IE9+ 浏览器。我没什么思路,但高手在民间!

果然高手在民间,结果 @ 大地 Dudy 巧妙使用 outline 实现了 Chrome 浏览器下的十字效果。demo 参见这里

—————–我是低调的分隔线,大家都看不到我—————

outline 知识点很多的,扩展开来可以写个长篇了,这里简单介绍点东西。

1. border 近亲
outlineborder 是近亲,为什么这么讲呢?首先,都是给元素外面套框框的;其次,支持的属性值几乎都是一样的,例如,outline-styleborder-styledotted, dashed, solid, ... 之类的,一些语法也几乎一样。如果这都不算近亲,你让绝对定位和浮动何言以对。

2. IE8+ 支持
outline 严格来讲属于 CSS3 属性,但是 IE8+ 浏览器就支持了。外挂一句,IE9+ 浏览器的 outline 还支持 invert,专门针对 outline-color. 所以,如果你的项目不用管 IE6/IE7 浏览器,可以把 outline 挂在心中,有时候说不定会帮忙。

3. 不占据空间
默认的盒模型下,假设元素 100*100 像素,我们给元素设置 border:10px solid,则实际该元素占据的尺寸至少就是 120*120 像素,元素的偏移、布局啊什么的,就需要多多思量。但是,outline 不一样,你哪怕 outline:100px solid,元素占据的尺寸还是 100*100 像素。这种行为表现,与 transform 以及 box-shadow 等 CSS3 属性很类似,虽然外形丰满了,但是,占据的真实空间没有影响。于是,我们在实现一些交互效果的时候,例如 hover 变化,我们就可以专注于效果本身,而不用被布局所左右,是很棒的体验。

4. 直角!圆角?
正好承上启下一下。

二、outline 的直角与圆角

现有此效果一枚:

一排 60*60 像素的直角图片,选中的图片外框 2 像素带圆角高亮。浏览器兼容要求,IE9+ 以及其他现代浏览器。

一般而言,我们的第一反应是使用 border + border-radius。但是,有个问题,就是,这里的外部高亮边框效果是外扩的,要知道,border 是会增加元素的尺寸的,于是,为了我们的完美对齐效果,还需要对选中元素做重定位,上下左右的 margin 值都需要改变。我丢,想想就烦!

像这种 UI 表现,天生就是 outline 干的事情。于是,我们大手一挥:

outline: 2px solid #26C2A7;

高亮的边框在哪里?在这里在这里!

但是,不是圆角啊!

亲爱的朋友,千万不要妄图通过 border-radius 来改变 outline 的圆角,要知道,outlineborder 是近亲,穿一个开裆裤长大的。但是,媳妇可不能共享哈!border-radiusborder 是登记在案的光明夫妻,看,连姓氏都随了夫君了,人家只认 border, 你 outline 没戏,找自己的媳妇止渴去。

但是,outline 貌似是个单身狗,没有媳妇啊,难道 outline 注定一辈子直角,掰不弯了?

三、outline 的圆角效果

茫茫 CSS 海,乍一看去,貌似没有能让 outline 圆角的东西。注意措辞,“貌似”,我们如果有双犀利的眼睛,还是会发现某处藏可以让 outline 圆角的东西。

在 FireFox 浏览器中,就有和 outline 匹对的圆角夫妻 outline-radius,

其关系,就和 borderborder-radius 的关系一样。

由于目前还只是 FireFox 浏览器私有的属性,因此,目前的使用需要加 -moz- 前缀,也就是-moz-outline-radius.

闻名不如见面,若是火狐,您可以狠狠地点击这里:FireFox 下 outline radius 圆角效果 Demo

效果如下截图:

相关 CSS 代码如下:

img {
outline: 30px solid #cd0000;
-moz-outline-radius: 30px;
}

是不是很松松啊!如果你观察足够仔细,会发现,outline-radiusborder-radius 还是有区别的?看出来没,区别在哪里?答对有奖……哈,没错,你们都答错了!没有任何区别,outline-radius 的圆角规则、语法之类跟 border-radius 就是一样的。

唯一的区别,也就是兼容性问题,不是看出来的,是试出来的。告诉大家一个不幸的消息,目前,除了 FireFox 浏览器支持 outline-radius,其他浏览器都是空大屁!

如果是仅 webkit/blink 浏览器支持还好说,至少移动端还可以用用,搞了个仅仅 FireFox 支持,玩毛线啊!不对,连毛线都没得玩!

亲,不要绝望啊,车到山前必有路,此路进去……

四、box-shadow 模拟 outline 的圆角效果

outline-radius 虽然没戏了,但是,我们可以使用其他属性,可以实现类似的效果,比方说,图形构建大神之一的 box-shadow.

我们平时使用 box-shadow 最多的是前面 3 个参数,水平/垂直偏移以及模糊大小,可能有一些小伙伴并不清楚其第 4 个可选参数值究竟有何用?box-shadow 第 4 个参数值,名外扩展,可以把投影范围扩大,当然,扩大的区域是实色区域。我们就可以利用这一特性,模拟实现不影响元素占据尺寸的 outline 实色边框效果啦!

实例先行,您可以狠狠地点击这里:CSS3 box-shadow 模拟 outline radius 圆角 Demo

CSS 代码如下:

img {
border-radius: 1px;
box-shadow: 0 0 0 30px #cd0000;
}

CSS3 用的多的小伙伴应该知道,box-shadow 的投影形状与 border-radius 一脉相承,也就是 border-radius 是圆角的,box-shadow 的投影也是圆弧形的。于是,我们这里最终的效果就如下图所示:

下面简单解释下两行 CSS 代码的含义:

  1. border-radius: 1px 表示圆角大小 1 像素。有同学可能奇怪了,怎么是 1 像素啊,截图圆角明明好几十像素,下面正好就解释了;

  2. box-shadow: 0 0 0 30px #cd0000 出现了 4 个数值,分别是水平偏移 0, 垂直偏移 0,模糊 0(纯色), 扩展大小 30 像素。我们可以想象成,光线直接从盒子的正上方照下来,因为没有偏移没有模糊,我们看不到任何阴影。实际上,盒子的阴影正好就是盒子的大小(外带 1 像素圆角),此时,扩展 30 像素,我们可以脑补一下,1 像素圆角的阴影再扩展 30 像素。哟,不就是我们需要的效果嘛,不就是截图展示的效果嘛!

    知道 border-radius 1 像素的左右了吧,扩展 30 像素后,圆角就是 30 像素大小了。

然而,虽然肉眼看不出来,上面的方法实际有瑕疵,因为图片不是纯正的直角,有 1 像素的圆角。如果你想实现完美的内方外圆的效果,可以套一层标签,外面的标签使用 border-radiusbox-shadow 就可以了。

原文传送门:http://www.zhangxinxu.com/wordpress/?p=4765

  • B3log

    B3log 是一个开源组织,名字来源于“Bulletin Board Blog”缩写,目标是将独立博客与论坛结合,形成一种新的网络社区体验,详细请看 B3log 构思。目前 B3log 已经开源了多款产品:SymSoloVditor思源笔记

    1063 引用 • 3453 回帖 • 203 关注
  • 前端

    前端技术一般分为前端设计和前端开发,前端设计可以理解为网站的视觉设计,前端开发则是网站的前台代码实现,包括 HTML、CSS 以及 JavaScript 等。

    247 引用 • 1348 回帖

相关帖子

欢迎来到这里!

我们正在构建一个小众社区,大家在这里相互信任,以平等 • 自由 • 奔放的价值观进行分享交流。最终,希望大家能够找到与自己志同道合的伙伴,共同成长。

注册 关于
请输入回帖内容 ...