小tip: CSS3如何实现圆角的outline效果?

这篇文章发布于 2015年04月30日,星期四,01:02,归类于 CSS相关。 阅读 87088 次, 今日 5 次 32 条评论

 

一、首先,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

效果如下截图:
FireFox浏览器下outline-radius效果截图

相关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的投影也是圆弧形的。于是,我们这里最终的效果就如下图所示:
box-shadow模式圆角outline效果截图

下面简单解释下两行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就可以了。

五、结语

祝大家五一快乐,玩得开心!

(本篇完)

分享到:


发表评论(目前32 条评论)

  1. 羽林说道:

    现在 border-radius 能够同时使 border 和 outline 都拥有一样的圆角效果了

  2. huoshen说道:

    这个box-shadow不能解决 dashed等样式问题

  3. Zhoukaka说道:

    是31,不是30

  4. lbca说道:

    厉害!真是精通呀

  5. 说道:

    border是会增加元素的尺寸的。感觉这句话怪怪的,是减少吧

  6. aaa说道:

    想说看了大神的结语变短了有股淡淡的忧伤

  7. lal说道:

    水平恒高,就是废话太多

  8. saber说道:

    受教了~不过美女图似乎过了很多年还没换 哈哈

  9. mrszhao说道:

    很棒,实现了不占据布局空间的外边框圆角效果。不管是用box-sizing还是transparent的border,都还是内边框。学习了。

  10. 子非鱼说道:

    我一直用这个方法感觉更加的方便呀。
    box-sizing:border-box;border:2px solid #000;border-radius:500px;

  11. 狸五郎说道:

    我一直是这么干的,也没觉得太麻烦。事件也好做。

    .nomo_box{
    font-size:60px;
    font-family:-webkit-pictograph;
    display: inline-block;
    height: 50px;
    width: 50px;
    border-radius: 5px;
    font-weight: bolder;
    background-color:#666;
    color: #fff;
    text-align: center;
    line-height:50px;
    cursor: pointer;
    }

    +

  12. nevermore说道:

    既然有outline可以这样实现,那样太麻烦了
    .bd-otl
    {
    width:120px;
    height:120px;
    border:40px dotted blue;
    box-sizing:border-box;
    outline:40px solid blue;
    }

  13. TEDG说道:

    强烈要求换江一燕!!

  14. yndry说道:

    提个建议,能不能换个美女图片,看太多审美疲劳了。。。

  15. fengge9413说道:

    文笔幽默,探索精神十足。

  16. chasonma说道:

    不错,涨知识了!

  17. youxianbo说道:

    之前一直都是使用border,border-redius的,先定义一个和背景色一样的border , 要显示边框的时候就变色

    • WingMeng说道:

      定义和背景色一样的border维护起来不方便,我自己是用透明border先“占位”,hover时再改变border-color即可,百试不爽。

  18. proudrain说道:

    学到了~
    不过感觉还是挺蛋疼的。。
    相比直接在开始设置透明边框进行布局感觉没有方便太多呢。

  19. 深海。说道:

    好腻害~~~ 收不收徒~~~~~

  20. sikaco说道:

    好文,赞+1

    前段时间温习发现了outline这东东,一直奇怪为啥平时没见人用过.
    受教了。

    顺便小白问个小问题,现在应届生想进tx还有机会么

  21. 小白说道:

    .box{
    box-sizing:border-box;
    -moz-box-sizing:border-box; /* Firefox */
    -webkit-box-sizing:border-box; /* Safari */
    width:100px;
    height:100px;
    boder:3px solid #000;
    border-radius:3px;
    }
    box-sizing:border-box;宽度,高度神马的.随便撸~

  22. lee说道:

    每追更新都有收获!

  23. 大怪兽说道:

    不错,很给力的鑫哥

  24. Bob说道:

    看代码的时候愣了一下,好凶残