목차
前言
二话不说看效果
细读属性
概述属性语法
outer box-shadow 和 inner box-shadow怎么玩?
模糊边框 by blur radius
缩放阴影尺寸 by spread distance
弄清各图层的z-index
阴影的position
圆角or直角box-shadow傻傻分不清楚?
被割裂的box-shadow
兼容性
感谢
打赏支持作者写出更多好文章,谢谢!
关于作者:^-^肥仔John
웹 프론트엔드 HTML 튜토리얼 CSS魔法堂:Box-Shadow没那么简单啦:)_html/css_WEB-ITnose

CSS魔法堂:Box-Shadow没那么简单啦:)_html/css_WEB-ITnose

Jun 21, 2016 am 08:48 AM

前言

说起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 | [,]*默认值为none:inset? && {2,4} && ?shadow pattern,默认为outset,即采用outer box-shadow。通过设置为inset时,则采用inner box-shadow。horizontal offset,阴影距离原位置的水平位移,正数表示向右移动,负数表示向左移动。vertical offset,阴影距离原位置的垂直位移,正数表示向下移动,负数表示向上移动。blur radius,默认值为0,阴影模糊度半径。spread distance,默认值为0,扩展或缩小阴影的作用面积。,阴影颜色,默认与color属性一致。

注意:我们可以同时设置多个阴影,而阴影的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之外。实现原理:

  1. 创建一个与元素border box尺寸一致的阴影盒子;
  2. 将阴影盒子定位到于元素border box重合,并位于元素之下;
  3. 根据horizontal offset和vertical offset来相对原位置作移动;
  4. 根据spread distance缩放阴影盒子的尺寸(会影响盒子的位移);
  5. 根据blur radius对阴影盒子作加工;
  6. 最后将阴影盒子与元素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之内。实现原理(纯个人理解):

  1. 创建一个与元素padding box尺寸一致的阴影盒子;
  2. 将阴影盒子定位到于元素padding box重合,并位于元素之上;
  3. 水平和垂直各画两条线,分别跟元素padding edge重合;(共4条分别记为left/top/right/bottom-guideline)
  4. 根据horizontal offset和vertical offset移动left/top/right/bottom-guideline。
  5. 根据spread distance移动4条线。spread distance为正数时,left-guideline向右移动,top-guideline向下移动,right-guideline向左移动和bottom-guidelien向上移动;spread distance为负数时,则相反。
  6. 根据blur radius加工元素各padding edge至其对应的guideline间的区域.
  7. 对阴影盒子进行剪裁
    1. 剪切掉不与元素padding box重叠的部分;
    2. 仅显示元素各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时会扩展阴影尺寸,那么到底扩展多少呢?那我们要先明确模糊发生的起始位置了。

  1. 对于outer-shadow-box而言,模糊发生的起始位置就是阴影盒子的各边;
  2. 对于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顺序。那么阴影呢?

  1. 对于outer-box-shadow,则其z-index高于margin图层,低于background-color图层;
  2. 对于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 ·      

본 웹사이트의 성명
본 글의 내용은 네티즌들의 자발적인 기여로 작성되었으며, 저작권은 원저작자에게 있습니다. 본 사이트는 이에 상응하는 법적 책임을 지지 않습니다. 표절이나 침해가 의심되는 콘텐츠를 발견한 경우 admin@php.cn으로 문의하세요.

핫 AI 도구

Undresser.AI Undress

Undresser.AI Undress

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

AI Clothes Remover

AI Clothes Remover

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

Undress AI Tool

Undress AI Tool

무료로 이미지를 벗다

Clothoff.io

Clothoff.io

AI 옷 제거제

Video Face Swap

Video Face Swap

완전히 무료인 AI 얼굴 교환 도구를 사용하여 모든 비디오의 얼굴을 쉽게 바꾸세요!

뜨거운 도구

메모장++7.3.1

메모장++7.3.1

사용하기 쉬운 무료 코드 편집기

SublimeText3 중국어 버전

SublimeText3 중국어 버전

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

스튜디오 13.0.1 보내기

스튜디오 13.0.1 보내기

강력한 PHP 통합 개발 환경

드림위버 CS6

드림위버 CS6

시각적 웹 개발 도구

SublimeText3 Mac 버전

SublimeText3 Mac 버전

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

HTML은 초보자를 위해 쉽게 배우나요? HTML은 초보자를 위해 쉽게 배우나요? Apr 07, 2025 am 12:11 AM

HTML은 간단하고 배우기 쉽고 결과를 빠르게 볼 수 있기 때문에 초보자에게 적합합니다. 1) HTML의 학습 곡선은 매끄럽고 시작하기 쉽습니다. 2) 기본 태그를 마스터하여 웹 페이지를 만들기 시작하십시오. 3) 유연성이 높고 CSS 및 JavaScript와 함께 사용할 수 있습니다. 4) 풍부한 학습 리소스와 현대 도구는 학습 과정을 지원합니다.

HTML, CSS 및 JavaScript의 역할 : 핵심 책임 HTML, CSS 및 JavaScript의 역할 : 핵심 책임 Apr 08, 2025 pm 07:05 PM

HTML은 웹 구조를 정의하고 CSS는 스타일과 레이아웃을 담당하며 JavaScript는 동적 상호 작용을 제공합니다. 세 사람은 웹 개발에서 의무를 수행하고 화려한 웹 사이트를 공동으로 구축합니다.

HTML의 시작 태그의 예는 무엇입니까? HTML의 시작 태그의 예는 무엇입니까? Apr 06, 2025 am 12:04 AM

anexampleStartingtaginhtmlis, whithbeginsaparagraph.startingtagsareessentialinhtmlastheyinitiate rements, definetheirtypes, andarecrucialforstructurituringwebpages 및 smanstlingthedom.

HTML, CSS 및 JavaScript 이해 : 초보자 안내서 HTML, CSS 및 JavaScript 이해 : 초보자 안내서 Apr 12, 2025 am 12:02 AM

WebDevelopmentReliesonHtml, CSS 및 JavaScript : 1) HtmlStructuresContent, 2) CSSSTYLESIT, 및 3) JAVASCRIPTADDSINGINTERACTIVITY, BASISOFMODERNWEBEXPERIENCES를 형성합니다.

Gitee Pages 정적 웹 사이트 배포 실패 : 단일 파일 문제를 해결하고 해결하는 방법 404 오류? Gitee Pages 정적 웹 사이트 배포 실패 : 단일 파일 문제를 해결하고 해결하는 방법 404 오류? Apr 04, 2025 pm 11:54 PM

GiteEpages 정적 웹 사이트 배포 실패 : 404 오류 문제 해결 및 해결시 Gitee ...

웹 주석에서 y 축 위치의 적응 형 레이아웃을 구현하는 방법은 무엇입니까? 웹 주석에서 y 축 위치의 적응 형 레이아웃을 구현하는 방법은 무엇입니까? Apr 04, 2025 pm 11:30 PM

웹 주석 기능에 대한 Y 축 위치 적응 알고리즘이 기사는 Word 문서와 유사한 주석 기능을 구현하는 방법, 특히 주석 간격을 다루는 방법을 모색합니다 ...

CSS3 및 JavaScript를 사용하여 클릭 후 주변 사진을 흩어지고 확대하는 효과를 얻는 방법은 무엇입니까? CSS3 및 JavaScript를 사용하여 클릭 후 주변 사진을 흩어지고 확대하는 효과를 얻는 방법은 무엇입니까? Apr 05, 2025 am 06:15 AM

이미지를 클릭 한 후 주변 이미지를 산란 및 확대하는 효과를 얻으려면 많은 웹 디자인이 대화식 효과를 달성해야합니다. 특정 이미지를 클릭하여 주변을 만들 수 있습니다 ...

라우터 폴더 아래의 index.js 파일에서 vue.use (vuerouter)를 호출 해야하는 이유는 무엇입니까? 라우터 폴더 아래의 index.js 파일에서 vue.use (vuerouter)를 호출 해야하는 이유는 무엇입니까? Apr 05, 2025 pm 01:03 PM

vue 응용 프로그램을 개발할 때 라우터 폴더 아래에 index.js 파일에 vuerouter를 등록해야 할 필요성이 있으면 종종 라우팅 구성에 문제가 발생합니다. 특별한...

See all articles