CSS魔法堂:Box-Shadow没那么简单啦:)_html/css_WEB-ITnose
前言
说起box-shadow那第一个想法当然就是用来实现阴影,其实它还能用于实现其他好玩的效果的,本篇就打算说说box-shadow的那些事。
二话不说看效果
3D小球
<style type="text/css">.ball{ background: rgba(100,100,100,0.2); width: 100px; height: 100px; padding: 10px; border-radius: 50%; box-shadow: -14px 8px 100px #333 inset, 0 0 2px #888, 3px -1px 4px #444;}</style><div class="ball"></div>
纸张阴影(来自@张鑫旭老师)
<style type="text/css">.curved_box { display: inline-block; *display: inline; width: 200px; height: 248px; margin: 20px; background-color: #fff; border: 1px solid #eee; -webkit-box-shadow: 0 1px 4px rgba(0, 0, 0, 0.27), 0 0 60px rgba(0, 0, 0, 0.06) inset; -moz-box-shadow: 0 1px 4px rgba(0, 0, 0, 0.27), 0 0 40px rgba(0, 0, 0, 0.06) inset; box-shadow: 0 1px 4px rgba(0, 0, 0, 0.27), 0 0 40px rgba(0, 0, 0, 0.06) inset; position: relative; *zoom: 1;}.curved_box:before { -webkit-transform: skew(-15deg) rotate(-6deg); -moz-transform: skew(-15deg) rotate(-6deg); transform: skew(-15deg) rotate(-6deg); left: 15px;}.curved_box:after { -webkit-transform: skew(15deg) rotate(6deg); -moz-transform: skew(15deg) rotate(6deg); transform: skew(15deg) rotate(6deg); right: 15px;}.curved_box:before, .curved_box:after { width: 70%; height: 55%; content: ' '; -webkit-box-shadow: 0 8px 16px rgba(0, 0, 0, 0.3); -moz-box-shadow: 0 8px 16px rgba(0, 0, 0, 0.3); box-shadow: 0 8px 16px rgba(0, 0, 0, 0.3); position: absolute; bottom: 10px; z-index: -1; }</style><div class="curved_box"></div>
细读属性
看到上面这么绚丽的效果,是不是迫不及待想弄清box-shadow呢?下面我们来一步步解密它吧!
概述属性语法
box-shadow: none |
注意:我们可以同时设置多个阴影,而阴影的z-index值从左向右递减。
outer box-shadow 和 inner box-shadow怎么玩?
默认情况下采用的是outer box-shadow,当在box-shadow中添加inset关键词后,则采用inner box-shadow了,但到底它俩的效果是如何的呢?
<style type="text/css">.box{ float: left; background: #888; width: 100px; height: 100px; margin-right: 20px;}.outer-box-shadow{ box-shadow: 10px 10px #F00;}.inner-box-shadow{ box-shadow: 10px 10px #F00 inset;}</style><div class="box outer-box-shadow"></div><div class="box inner-box-shadow"></div></div>
outer-box-shadow特点:阴影落在元素的border box之外。实现原理:
- 创建一个与元素border box尺寸一致的阴影盒子;
- 将阴影盒子定位到于元素border box重合,并位于元素之下;
- 根据horizontal offset和vertical offset来相对原位置作移动;
- 根据spread distance缩放阴影盒子的尺寸(会影响盒子的位移);
- 根据blur radius对阴影盒子作加工;
- 最后将阴影盒子与元素border box重合部分剪切掉。 模拟一下:
<style type="text/css">.box{ background: #888; width: 100px; height: 100px;}.outer-box-shadow{ box-shadow: 90px 10px #F00;}</style><div class="box outer-box-shadow"></div></div>
로그인 후 복사<style type="text/css">.box{ position: relative;}.box-shadow{ position: absolute; z-index: -1; background: #F00; width: 100px; height: 100px; left: 20px; top: 20px;}.box-content{ background: #888; width: 100px; height: 100px;}</style><div class="box"> <div class="box-shadow"></div> <div class="box-content"></div></div>
로그인 후 복사
inner-box-shadow特点:阴影落在元素的padding box之内。实现原理(纯个人理解):
- 创建一个与元素padding box尺寸一致的阴影盒子;
- 将阴影盒子定位到于元素padding box重合,并位于元素之上;
- 水平和垂直各画两条线,分别跟元素padding edge重合;(共4条分别记为left/top/right/bottom-guideline)
- 根据horizontal offset和vertical offset移动left/top/right/bottom-guideline。
- 根据spread distance移动4条线。spread distance为正数时,left-guideline向右移动,top-guideline向下移动,right-guideline向左移动和bottom-guidelien向上移动;spread distance为负数时,则相反。
- 根据blur radius加工元素各padding edge至其对应的guideline间的区域.
- 对阴影盒子进行剪裁
- 剪切掉不与元素padding box重叠的部分;
- 仅显示元素各padding edge至其对应的guideline间的区域。 模拟一下:
<style type="text/css">.box{ float: left; background: #888; width: 100px; height: 100px; margin-right: 10px;}.box1{ box-shadow: 0 0 0 20px red inset;}.box2{ box-shadow: 10px 0 0 20px red inset;}.box3{ box-shadow: 10px 0 10px 20px red inset;}.box4{ box-shadow: 0 0 10px 50px red inset;}</style><div class="box box1"></div><div class="box box2"></div><div class="box box3"></div><div class="box box4"></div>
로그인 후 복사<style type="text/css">.box-shadow{ position: relative; display: inline-block; background: red; overflow: hidden;}.bg{ position: absolute; background: #888; left: 30px; right: 10px; top: 20px; bottom: 20px;}.content{ position: relative; z-index: 1; width: 80px; height: 80px; padding: 20px;}</style><div class="box-shadow"> <div class="bg"></div> <div class="content"></div></div>
로그인 후 복사
模糊边框 by blur radius
W3C spec中没有规定浏览器厂商使用哪种方式实现模糊效果,反正效果与高斯模糊效果差不多就是了。但有一点我们需要注意的,那就是模糊效果会扩大阴影的面积。
<style type="text/css">.outline{ border: 1px solid red; margin: 40px 0;}.s{ background: rgba(255, 100, 100, 0.1); width: 100px; height: 100px;}.s1{ box-shadow: 110px 0 0 #333;}.s2{ box-shadow: 110px 0 20px #333;}.s3{ box-shadow: 110px 0 40px #333;}</style><div class="outline"> <div class="s s1">sample1</div></div><div class="outline"> <div class="s s2">sample2</div></div><div class="outline"> <div class="s s3">sample3</div></div>
sample1是blur radius为0的效果,可以看到阴影尺寸与元素尺寸一模一样。而sample2是blur radius为20px的效果,可以看到阴影尺寸有所扩展了,而sample3则扩展得更多一些。现在我们感性上认知到blur radius值大于0时会扩展阴影尺寸,那么到底扩展多少呢?那我们要先明确模糊发生的起始位置了。
- 对于outer-shadow-box而言,模糊发生的起始位置就是阴影盒子的各边;
- 对于inner-shadow-box而言,模糊发生的起始位置就是各guideline。然后模糊效果是从发生的位置,对于水平方向的边或guideline则向垂直方向发散,对于垂直方向的边或guideline则向水平方向发散,且发散的距离相同。发散的距离相同,因此每个方向各发散为blur radius/2的距离。看sample3中阴影尺寸已经与元素盒子重叠了,因为阴影盒子左边框向左发散了20px了,超过它俩之间10px的水平距离了,而sample2则恰恰邻近而已。
缩放阴影尺寸 by spread distance
如果说blur radius是暗地里扩大阴影的尺寸,那么spread distance则是明目张胆地缩放阴影的尺寸了。
<style type="text/css">.outline{ border: 1px solid red; margin: 40px 0;}.s{ background: rgba(255, 100, 100, 0.1); width: 100px; height: 100px;}.s1{ box-shadow: 110px 0 0 #333;}.s2{ box-shadow: 110px 0 0 10px #333;}.s3{ box-shadow: 110px 0 0 -10px #333;}</style><div class="outline"> <div class="s s1">sample1</div></div><div class="outline"> <div class="s s2">sample2</div></div><div class="outline"> <div class="s s3">sample3</div></div>
还记得《CSS魔法堂:重拾Border之——解构Border》中提及通过border-top/right/bottom/left-colors实现彩虹边框吗?由于兼容性问题和1px对应一种color的缘故,实际应用得很少,但通过outer-box-shadow和spread distance我们就可以得到效果更好,兼容性很高的实现方案了。
<style type="text/css">.rainbow{ margin: 50px; width: 100px; height: 100px; box-shadow: 0 0 0 2px rgb(255,0,0), 0 0 0 5px rgb(255,165,0), 0 0 0 8px rgb(255,255,0), 0 0 0 10px rgb(0,255,0), 0 0 0 12px rgb(0,127,255), 0 0 0 15px rgb(0,0,255), 0 0 0 20px rgb(139,0,255);}</style><div class="rainbow"></div>
弄清各图层的z-index
上图可以看到没有阴影时,各图层的z-index顺序。那么阴影呢?
- 对于outer-box-shadow,则其z-index高于margin图层,低于background-color图层;
- 对于inner-box-shadow,则其z-index高于padding图层,低于content图层。
阴影的position
通过horizontal/vertical offset重定位阴影盒子,通过blur radius或spread distance缩放阴影盒子的尺寸,但请注意的是阴影盒子不影响其他盒子的布局,其实阴影盒子就相当于采用absolute定位一样,不会占据Normal flow的空间,也不会影响其他元素的布局,因此仅修改阴影位置或尺寸时,只会触发repaint,而不会触发reflow。
圆角or直角box-shadow傻傻分不清楚?
阴影不仅默认尺寸与元素盒子一致,默认形状也一致。也就是元素盒子采用圆角时,阴影的默认形状也是圆角的。既然说是默认形状一致,就是说可以不一致咯!那到底如何不一致呢,下面我们一起来看个究竟吧!
<style type="text/css">.s1{ background: #0EF; width: 100px; height: 100px; border-radius: 10px; box-shadow: 110px 0 0 -10px #333, 220px 0 0 0 #666, 360px 0 0 20px #888;}</style><div class="s1">sample1</div>
当设置spread distance后,border-radius的值也将随之变化,具体公式为border-radius + spread-distance * (1 + (border-radius / spread-distance - 1)^3)。因此spread distance为正数时,border-radius会变大; 而spread distance为负数时,border-radius会减小,直至为0px为止。
被割裂的box-shadow
当设置box-shadow的盒子被拆分为多个盒子时,其对应的box-shadow又会如何呢?其实这不仅仅是box-shadow的问题,如border、background-image等均会遇到同样的问题。CSS3中引入一个新特性box-decoration-break来设置上述情况时的渲染效果。box-decoration-break: slice | cloneslice是默认值,表示首先按未拆分时的状态渲染border、background-image等样式,然后再将其直接拆分为多个盒子;clone表示首先将其直接拆分为多个盒子,然后再逐个盒子渲染border、background-image等样式。
<style type="text/css">.intro{ font-size: 14px; line-height: 1.5; text-indent: 1em; width: 300px;}.intro span{ border: 1px solid #666; border-radius: 5px; box-shadow: 5px 3px 3px #AAA;}.slice{ -webkit-box-decoration-break: slice;}.clone{ -webkit-box-decoration-break: clone;}</style><p class="intro"><span class="slice">Hey there, welcome to be here to share something aboute CSS together:) My name is fsjohnhuang, a FE from Midea. Enjoy the evolution of FE, and feel excited in the work I'm doing now.</span></p><p class="intro"><span class="clone">Hey there, welcome to be here to share something aboute CSS together:) My name is fsjohnhuang, a FE from Midea. Enjoy the evolution of FE, and feel excited in the work I'm doing now.</span></p>
从上面可以看到,与其说box-decoration-break的属性值影响box-shadow的效果,还不如说是box-decoration-break的属性值影响border-radius和border作用到元素盒子的效果,然后由盒子的效果再间接影响box-shadow的效果。
兼容性IE和Edge均不支持,FF支持得最好,而Webkit内核的则要加-webkit-前缀。对于不支持的浏览器,其效果如同box-decoration-break:slice
兼容性
IE9都支持box-shadow多让人可喜可贺的消息啊(因为我工作中只需兼容IE9+就Ok了:))。但IE6~8呢?方案很多啦,上面也有简单的介绍到。@张鑫旭老师提到在模拟blur radius效果时,采用以下方案
.ieBlock{ height:100px; width:100px; background:#000; filter:progid:DXImageTransform.Microsoft.Blur(pixelradius=10); -ms-filter:"progid:DXImageTransform.Microsoft.Blur(pixelradius=10)"; }
要比采用以下方案要好!
.shadow { -moz-box-shadow: 3px 3px 4px #000; -webkit-box-shadow: 3px 3px 4px #000; box-shadow: 3px 3px 4px #000; /* For IE 8 */ -ms-filter: "progid:DXImageTransform.Microsoft.Shadow(Strength=4, Direction=135, Color='#000000')"; /* For IE 5.5 - 7 */ filter: progid:DXImageTransform.Microsoft.Shadow(Strength=4, Direction=135, Color='#000000');}
另外若想不假思索地用到生产环境中,还是用成熟的CSS库较好。具体请参考PIE使IE支持CSS3圆角盒阴影与渐变渲染
感谢
the-box-shadowbreak-decorationCSS3 box-shadow实现纸张的曲线投影效果CSS实现跨浏览器兼容性的盒阴影效果CSS实现跨浏览器的box-shadow盒阴影效果(2)PIE使IE支持CSS3圆角盒阴影与渐变渲染《图解CSS3核心技术与案例实战》 —— 3.5 CSS3盒子阴影属性
打赏支持作者写出更多好文章,谢谢!
打赏作者
打赏支持作者写出更多好文章,谢谢!
任选一种支付方式
关于作者:^-^肥仔John
偏前端的临栈工程师 个人主页 · 我的文章 · 1 ·

핫 AI 도구

Undresser.AI Undress
사실적인 누드 사진을 만들기 위한 AI 기반 앱

AI Clothes Remover
사진에서 옷을 제거하는 온라인 AI 도구입니다.

Undress AI Tool
무료로 이미지를 벗다

Clothoff.io
AI 옷 제거제

AI Hentai Generator
AI Hentai를 무료로 생성하십시오.

인기 기사

뜨거운 도구

메모장++7.3.1
사용하기 쉬운 무료 코드 편집기

SublimeText3 중국어 버전
중국어 버전, 사용하기 매우 쉽습니다.

스튜디오 13.0.1 보내기
강력한 PHP 통합 개발 환경

드림위버 CS6
시각적 웹 개발 도구

SublimeText3 Mac 버전
신 수준의 코드 편집 소프트웨어(SublimeText3)

뜨거운 주제











공식 계정 웹 페이지 업데이트 캐시, 이것은 간단하고 간단하며 냄비를 마시기에 충분히 복잡합니다. 공식 계정 기사를 업데이트하기 위해 열심히 노력했지만 사용자는 여전히 기존 버전을 열었습니까? 이 기사에서는이 뒤에있는 비틀기와 회전을 살펴 보고이 문제를 우아하게 해결하는 방법을 살펴 보겠습니다. 읽은 후에는 다양한 캐싱 문제를 쉽게 처리 할 수있어 사용자가 항상 가장 신선한 콘텐츠를 경험할 수 있습니다. 기본 사항에 대해 먼저 이야기 해 봅시다. 액세스 속도를 향상시키기 위해 브라우저 또는 서버는 일부 정적 리소스 (예 : 그림, CSS, JS) 또는 페이지 컨텐츠를 저장합니다. 다음에 액세스 할 때 다시 다운로드하지 않고도 캐시에서 직접 검색 할 수 있으며 자연스럽게 빠릅니다. 그러나 이것은 또한 양날의 검입니다. 새 버전은 온라인입니다.

이 기사에서는 브라우저에서 직접 사용자 입력을 검증하기 위해 필요한, Pattern, Min, Max 및 Length 한계와 같은 HTML5 양식 검증 속성을 사용하는 것에 대해 설명합니다.

이 기사는 CSS를 사용한 웹 페이지에 효율적인 PNG 테두리 추가를 보여줍니다. CSS는 JavaScript 또는 라이브러리에 비해 우수한 성능을 제공하며, 미묘하거나 눈에 띄는 효과를 위해 테두리 너비, 스타일 및 색상 조정 방법을 자세히 설명합니다.

기사는 HTML5 크로스 브라우저 호환성을 보장하기위한 모범 사례에 대해 논의하고 기능 감지, 점진적 향상 및 테스트 방법에 중점을 둡니다.

이 기사는 HTML & LT; Datalist & GT에 대해 논의합니다. 자동 완성 제안을 제공하고, 사용자 경험을 향상시키고, 오류를 줄임으로써 양식을 향상시키는 요소. 문자 수 : 159

이 기사는 HTML & lt; Progress & Gt에 대해 설명합니다. 요소, 그 목적, 스타일 및 & lt; meter & gt의 차이; 요소. 주요 초점은 & lt; progress & gt; 작업 완료 및 & lt; meter & gt; Stati의 경우

이 기사는 html5 & lt; time & gt; 시맨틱 날짜/시간 표현 요소. 인간이 읽을 수있는 텍스트와 함께 기계 가독성 (ISO 8601 형식)에 대한 DateTime 속성의 중요성을 강조하여 Accessibilit를 향상시킵니다.

이 기사는 HTML & lt; meter & gt에 대해 설명합니다. 범위 내에 스칼라 또는 분수 값을 표시하는 데 사용되는 요소 및 웹 개발의 일반적인 응용 프로그램. & lt; meter & gt; & lt; Progress & Gt; 그리고 Ex
