关于CSS阴影,我之前写过一篇文章,box-shadow和filter:drop-shadow详解和技巧,介绍了box-shadow的一些用法。最近有个新项目CSS-Inspiration,发现了很多关于CSS阴影的其他想法,都是之前文章没有涉及到的新内容,有些还很有意思,所以打算另开一篇。这篇文章的标题是CSSShadowTipsandDetails。CSS阴影,但不一定是box-shadow和filter:drop-shadow,为什么?因为其他属性也可以用来模拟阴影,而且有各种各样的阴影。下面我就来说说吧~单面投影先从单面投影说起。关于box-shadow,大多数时候,我们用它来生成双面投影,或者四面投影。如下:OK,如果要生成单面投影怎么办?我们看一下box-shadow的用法定义:{box-shadow:none|[插图?&&[<偏移量-x><偏移量-y><模糊半径>?<扩散半径>?<颜色>?]]#}以box-shadow:1px2px3px4px#333为例,4个值的含义分别是x方向的偏移值,y方向的偏移值,模糊半径,以及扩张半径。这里有个小技巧,展开半径可以为负。继续,如果阴影的模糊半径与负扩散半径重合,那么我们将看不到任何阴影,因为生成的阴影将包含在原始元素下,除非它被赋予方向偏移。所以这个时候,我们可以通过给一个方向的偏移值来实现单边投影:CodePenDemo--cssone-sidedprojection投射背景/背景动画继续上面的。很明显,0=-0,所以当box-shadow的blurradius和expansionradius都为0时,我们也可以得到一个和元素一样大小的阴影,但是被元素本身挡住了,我们试着让它抵消了。CSS代码如下:div{width:80px;高度:80px;边框:1px实心#333;框大小:边框框;box-shadow:80px80px00#000;}得到如下结果:有什么用?这似乎没有意义。嗯,好像真的不行。但是,我们注意到box-shadow可以设置多层,即多层阴影,可以进行过渡动画(tweenanimation)。但是background-image:linear-gradient(),即渐变背景不能补间。这是去哪儿了。好吧,让我们回来吧。利用以上特点,我们可以使用box-shadow来实现只能使用渐变来实现的背景图:使用box-shadow,实现它的CSS代码如下(可以简化):.shadow{position:相对;宽度:250px;height:250px;}.shadow::before{content:"";位置:绝对;宽度:50px;高度:50px;顶部:-50px;左:-50px;000,150px50px#000,250px50px#000,50px100px#000,150px100px#000,250px100px#000,50px150px#000,150px#000,150px150px#000,250px150px#000,50px#000,50px#000PX#000PX#000PX#000PX#000PX#000PX#000PX#000PX#000PX#000,250px200px#000,50px250px#000,150px250px#000,250px250px#000;}如果用渐变来实现的话,只需要这样:.gradient{width:250px;高度:250px;背景图像:线性渐变(90deg,#0000%,#00050%,#fff50%,#fff100%);background-size:100px100px;}为什么选择更复杂的box-shadow?因为它可以进行补间动画,像这样,用渐变是做不到的:CodePenDemo--box-shadow实现背景动画当然,这只是一个sampledemo,有很多有趣的效果稍加想象,再贴吧一:CodePenDemo--CSSCheckerIllusion(ByDavidKhourshid)嗯,很有趣,很实用可能不如立体投影,让我们继续。下一个主题是立体投影。这个说法很奇怪。阴影的出现是为了让原本的元素看起来更有立体感。那么这里所谓的三维投影是一种怎样的三维方法呢?这里所谓的立体投影并不是一定要用box-shadow、text-shadow或drop-shadow,而是我们用其他的元素或属性来模拟元素的阴影。这样做的目的是为了突破box-shadow等元素的一些定位限制。使阴影的位置、大小和模糊更加灵活。好吧,让我们来看看。对于这样一个元素,我们希望通过自定义阴影的位置,使其更加立体:上图中的div只有一个很浅的box-shadow,看上去与三维度无关。接下来,我们利用div的伪元素生成一个类似于原图角形状的图形,然后通过transform对其进行移位,可能是这样的:OK,最后对生成的元素进行一些虚化效果伪元素(filterorbox-shadow),可以实现像角被撕裂的三维效果:代码很简单,伪CSS代码如下:div{position:relative;宽度:600px;高度:100px;背景:hsl(48、100%、50%);border-radius:20px;}div::before{content:"";位置:绝对;顶部:50%;左:5%;右:5%;底部:0;边界半径:10px;背景:hsl(48、100%、20%);变换:平移(0,-15%)旋转(-4deg);变换原点:中心中心;box-shadow:0020px15pxhsl(48,100%,20%);}所以总结一下:立体投影的关键点就是帮助伪元素生成一个和父元素大小相近的元素元素,然后旋转它,定位到合适的位置,然后给它加上阴影操作颜色的使用也很重要。影子的颜色通常比它本身的颜色深。这里用hsl来表示颜色比较方便。l控制颜色明暗的场景还有很多:CodePenDemo--StereoscopicprojectiontextStereoscopicprojection/text长阴影的三维效果完全不适用于文字,所以我们需要另辟蹊径来处理文字的立体阴影效果。通常,我们使用text-shadow来生成文字阴影,像这样:
TxtShadow
-----div{text-shadow:6px6px3pxhsla(14,100%,30%,1);}很好,但不是三维的。那么要实现三维文字阴影,最常用的方法就是使用多层文字阴影叠加。Tips:和box-shadow一样,text-shadow可以多层叠加!但是对于单个元素,drop-shadow只能是一层。那么,对于上面的文字,我们来试试添加50层的文字阴影。嗯,手写50层其实很快~嗯,手写真的太慢了??,容易出错,所以这里需要借助SASS/LESS来写一个生成50层阴影的函数。向右和向下偏移1px以生成一层文本阴影:@functionmakeLongShadow($color){$val:0px0px$color;@for$i从1到50{$val:#{$val},#{$i}px#{$i}px#{$color};}@return$val;}div{text-shadow:makeLongShadow(hsl(14,100%,30%));}上面的SCSS代码。编译后会生成如下CSS:div{text-shadow:0px0px#992400,1px1px#992400,2px2px#992400,3px3px#992400,4px4px#992400,5px5px#992400,6px6px#99,7px7px#992400,8px8px#992400,9px9px#992400,10px10px#992400,11px11px#992400,12px12px#992400,13px13px#992400,14px#992400,15px15px192400,16px16px16PX,17px17px#992400,18px18px#992400,19px19px#992400,20px20px#992400,21px21px#992400,22px22px#992400,23px23px#992400,24px24px#992400,25px25px#992400,26px26px#992400,27px27px#992400,28px28px#992400,29px29px#992400,30px30px#992400,31px31px#992400,32px32px#992400,33px33px#992400,34px34px#992400,35px35px#992400,36px36px#992400,37px37px#992400,38px38px#992400,39px39px#992400,40px40px#992400,41px41px41px#992400,42px42px42px42px#992400,43px43px43px#992400#44px44px44px44px44px44px44px44px44px44px44px44px44px44px44px44px44px44px44px44px#992400,48px48px#992400,49px49px#992400,50px50px#992400;}看看效果:嗯,很好,很有立体感,就是丑,怪怪的。问题是什么?阴影实际上有亮度和透明度的变化。因此,对于每一层渐变的文字阴影,明度和透明度应该是不断变化的。SASS可以很好的实现这个需求。这里有两个SASS颜色函数:fade-out改变颜色的透明度,使颜色更透明desaturate改变颜色的饱和度值,使颜色不那么饱和。关于SASS颜色函数,可以看这里:SassBasics—ColorFunction我们使用上面的两个SASS颜色函数来修改我们的CSS代码,主要是修改上面的makeLongShadow函数函数:@functionmakelongrightshadow($color){$值:0px0px$颜色;@for$i从1到50{$color:fade-out(desaturate($color,1%),.02);$val:#{$val},#{$i}px#{$i}px#{$color};}@return$val;}好了,看看最后的效果:好了,大功告成,这次顺眼多了~CodePenDemo--三维文字阴影当然,CSS的使用方法有很多种生成三维文字阴影,下面贴出另一个例子,使用透明色的多个线性渐变叠加在背景色上,实现文字的三维阴影。有兴趣的同学可以去看看具体实现:带阴影的线性渐变实现条纹三维阴影。上面说的stripewordlengthprojection。多层阴影叠加,实现文字立体阴影。它也可以用在div容器上。当然,这里还有一个有趣的方法。假设我们有一个矩形元素,想给它添加一个长投影,如下:要生成这个长投影,我们可以叠加刚才提到的多个阴影,然后使用元素的两个伪元素。其实上图是这样的:重点是我们通过两个伪元素的变换:skew()变换和背景色由纯色变为透明色来实现长阴影的效果:CodePenDemo--线性渐变模拟长阴影颜色投影一般来说,我们生成阴影的方式大多是box-shadow,filter:drop-shadow(),text-shadow。然而,使用它们生成的阴影通常只能是单色或同色调。你这么说,还能生成渐变阴影吗?好吧,当然不是。这确实行不通,但通过巧妙地使用filter:blur模糊滤镜,我们可以假装生成渐变或色彩丰富的阴影。假设我们有这样一张头像图片:接下来使用滤镜添加一层与原图颜色相近的阴影效果。核心CSS代码如下:.avator{position:relative;background:url($img)no-repeatcenter中心;背景大小:100%100%;&::之后{内容:“”;位置:绝对;前10名%;宽度:100%;高度:100%;尺寸:100%100%;过滤器:模糊(10px)亮度(80%)不透明度(.8);z-指数:-1;}}看效果:简单的原理就是用伪元素生成一张和原图一样大小的新图叠加在原图下,然后用filter:blur()和其他亮度合成/contrast,transparency等滤镜,营造出虚幻的阴影,伪装成原图的阴影效果。嗯,最重要的是这个线过滤器:blur(10px)brightness(80%)opacity(.8);.CodePenDemo--filtercreateshadow使用box-shadow来达到很好的光照效果。以上主要是实现各种阴影的一些方法,接下来是效果篇。让我们看一下使用box-shadow实现的一些光照效果。box-shadow实现neon霓虹灯文字效果这种效果也叫Neon。Codepen上有很多类似的效果,本质上都是大范围的box-shadow过渡效果和白色文字的叠加:CodePenDemo--box-shadow实现Neon霓虹灯文字效果使用box-shadow实现阴影灯光秀是类似于上面的效果,本质上是一个多重阴影的过渡效果,也许是一些3D效果?合理搭配,效果更佳:CodePenDemo——利用box-shadow实现阴影光照展示Usedrop-shadow|box-shadow实现单标签抖音LOGO呵呵,既然标题讲的是你所不知道的CSS阴影技巧和细节,那么这篇文章应该也有小技巧吧。我们先来看这个。单个标签实现仿抖音LOGO。当然,因为仅限于一个元素,细节上还是有很多瑕疵。之所以想模仿,是因为有一天在刷抖音的时候心血来潮看到了这个LOGO。CSS写的太多了,我会条件反射地想,这能不能用CSS来实现。先来看看抖音的LOGO:其实很简单,主体其实是由3个不同颜色的J字形组成的。而单独拿出一个的话,可以分成四分之三,|和?。正好一个元素加上它的两个伪元素刚好可以组成这三种形状。让我们尝试实现以下目标。简单的CSS代码如下:
---div{position:relative;宽度:37px;高度:218px;背景:#fff;&::之前{内容:“”;位置:绝对;宽度:100px;高度:100px;边框:37px实心#fff;-半径:50%;顶部:123px;左:-137px;变换:旋转(45度);}&::after{内容:“”;位置:绝对;宽度:140px;高度:140px;border:30pxsolid#fff;border-right:30pxsolidtransparent;border-top:30px实心透明;左边框:30px实心透明;顶部:-100px;右:-172px;}}上面的代码可以生成整个形状的主体:接下来就是轮到filter:drop-shadow()了,可以在元素渲染之前为元素的渲染提供一些效果,最常见的一种是用它来渲染整体阴影。我们通常用它来实现对话框的小三角和整个对话框的阴影效果,如下图,左边是使用drop-shadow的效果,右边是使用普通框的效果-阴影。本文假设读者已经了解了阴影的基本用法。上图效果来自这里:CodePenDemo--Drop-shadowvsbox-shadow(2)ByKsesoOK,回到我们的正文,我们使用下面的filter:drop-shadow()在左边生成一个蓝色阴影它的第一层,在主div中添加:div{position:relative;宽度:37px;高度:218px;背景:#fff;过滤器:阴影(-10px-10px0#24f6f0);&::before,&::after{...}}得到如下效果:OK,那我们只需要在右侧再添加一层红色滤镜:drop-shadow()就大功告成了!ETC!怎么了,我上面说了,和box-shadow一样,text-shadow可以多层叠加!但是对于单个元素,drop-shadow只能是一层。也就是说,我们不能再在div上使用filter:drop-shadow()在另一边生成红色投影了,还好我们还有两个伪元素滤镜:drop-shadow()和box-shadow还没有使用它,经过一些试验:div{position:relative;宽度:37px;高度:218px;背景:#fff;滤镜:阴影(-10px-10px0#24f6f0)对比度(150%)亮度(110%);框阴影:11.6px10px00#fe2d52;&::before{....filter:drop-shadow(16px0px0#fe2d52);}&::after{....filter:drop-shadow(14px00#fe2d52);}}我们分别使用div的box-shadow和两个伪元素的filter:drop-shadow()。在单个标签的限制下,最终效果如下:CodePenDemo--SingleLabelimplementation抖音LOGO总结一下:主要用两个伪元素实现整体结构,一层整体阴影在阴影的帮助下生成。Drop-shadow只能是单层阴影,所以其他层的阴影需要尝试更多的contrast(150%)brightness(110%)可以增强图像的对比度和亮度,会更接近效果抖音LOGO的更新于2018-11-9关于上面的抖音LOGO,小伙伴们提醒一下,应该就是两种J型的形状相互重叠,重叠部分为白色,非-重叠部分以各自的原色。我一开始觉得很复杂,但是我尝试了这个效果。也可以使用CSS的mix-blend-mode来实现。下面给出实现方法。有兴趣的同学可以看看:CodePenDemo——使用mix-blend-mode实现抖音LOGO当然,关于CSS阴影还有很多有趣的技巧和细节,本文限于篇幅就不一一列举了一。我在Git上开了一个仓库,CSS-Inspiration,以分类的形式,展示不同的CSS属性或者使用CSS解决不同问题的各种方法。更多有趣的CSS技巧可以在这里找到,并且每天更新。最后,感谢您的耐心阅读。更多精彩CSS技术文章汇总在我的Github——iCSS,持续更新。欢迎点个星订阅收藏。好了,本文到此结束,希望对大家有所帮助:)有什么问题或者建议可以多交流,原创文章,文笔有限,知识匮乏,如有不妥之处,敬请谅解!文章,请告诉我。