偷懒了1个多礼拜,在工作饱和的情况下,怎么坚持学习?今天的分享来自@Coco国服第一切图仔,我们聊聊CSS属性box-shadow

关于 CSS 阴影,之前已经有写过一篇,box-shadow 与 filter:drop-shadow 详解及奇技淫巧,介绍了一些关于 box-shadow 的用法。

最近一个新的项目,CSS-Inspiration,挖掘了其他很多有关 CSS 阴影的点子,是之前的文章没有覆盖到的新内容,而且有一些很有意思,遂打算再起一篇。

本文的题目是 CSS 阴影技巧与细节。CSS 阴影,却不一定是 box-shadowfilter:drop-shadow,为啥?因为使用其他属性也可以模拟阴影,而且是各种各样的阴影。下面且听我娓娓道来~


单侧投影

先说单侧投影,关于 box-shadow,大部分时候,我们使用它都是用来生成一个两侧的投影,或者一个四侧的投影。如下:


OK,那如果要生成一个单侧的投影呢?

我们来看看 box-shadow 的用法定义:

1{
2    box-shadow: none | [inset? && [ <offset-x> <offset-y> <blur-radius>? <spread-radius>? <color>? ] ]#
3}

box-shadow: 1px 2px 3px 4px #333 为例,4 个数值的含义分别是,x 方向偏移值、y 方向偏移值 、模糊半径、扩张半径。

这里有一个小技巧,扩张半径可以为负值。

继续,如果阴影的模糊半径,与负的扩张半径一致,那么我们将看不到任何阴影,因为生成的阴影将被包含在原来的元素之下,除非给它设定一个方向的偏移量。所以这个时候,我们给定一个方向的偏移值,即可实现单侧投影:


CodePen Demo -- css 单侧投影

投影背景 / 背景动画

接着上面的说。

很明显,0 = -0,所以当 box-shadow 的模糊半径和扩张半径都为 0 的时候,我们也可以得到一个和元素大小一样的阴影,只不过被元素本身遮挡住了,我们尝试将其偏移出来。

CSS 代码如下:

1div {
2    width: 80px;
3    height: 80px;
4    border: 1px solid #333;
5    box-sizing: border-box;
6    box-shadow: 80px 80px 0 0 #000;
7}

得到如下结果:


有什么用呢?好像没什么意义啊。

额,确实好像没什么用。不过我们注意到,box-shadow 是可以设置多层的,也就是多层阴影,而且可以进行过渡变换动画(补间动画)。但是 background-image: linear-gradient(),也就是渐变背景是不能进行补间动画的。

这又扯到哪里去了。好我们回来,利用上面的特性,我们可以利用 box-shadow 实现原本只能利用渐变才能实现的背景图:


box-shadow,实现它的 CSS 代码如下(可以更简化):

 1.shadow {
2    position: relative;
3    width: 250px;
4    height: 250px;
5}
6
7.shadow::before {
8    content: "";
9    position: absolute;
10    width: 50px;
11    height: 50px;
12    top: -50px;
13    left: -50px;
14    box-shadow:
15        50px 50px #000, 150px 50px #000, 250px 50px #000,
16        50px 100px #000, 150px 100px #000, 250px 100px #000,
17        50px 150px #000, 150px 150px #000, 250px 150px #000,
18        50px 200px #000, 150px 200px #000, 250px 200px #000,
19        50px 250px #000, 150px 250px #000, 250px 250px #000;
20}

用渐变来实现的话,只需要这样:

1.gradient {
2    width: 250px;
3    height: 250px;
4    background-image: linear-gradient(90deg, #000 0%, #000 50%, #fff 50%, #fff 100%);
5    background-size:  100px 100px;
6}

为什么选择更为复杂的 box-shadow 呢?因为它可以进行补间动画,像这样,这是使用渐变做不到的:


CodePen Demo -- box-shadow 实现背景动画

当然,这只是个示例 Demo,运用点想象力还有很多有意思的效果,再贴一个:


CodePen Demo -- CSS Checker Illusion(By David Khourshid)

嗯,很有意思,就是实际用途可能不大。


立体投影

好,我们继续。下一个主题是立体投影。

这个说法很奇怪,阴影的出现,本就是为了让原本的元素看起来更加的立体,那这里所谓的立体投影,是个怎么立体法?

这里所谓的立体投影,并不一定是使用了 box-shadowtext-shadow 或者 drop-shadow,而是我们使用其他元素或者属性模拟元素的阴影。而这样做的目的,是为了能够突破 box-shadow 这类元素的一些定位局限。让阴影的位置、大小、模糊度可以更加的灵活。

OK,让我们来看看,这样一个元素,我们希望通过自定义阴影的位置,让它更加立体:


上图 div 只是带了一个非常浅的 bos-shadow ,看上去和立体没什么关系,接下来,我们通过 div 的伪元素,给它生成一个和原图边角形状类似的图形,再通过 transform 位移一下,可能是这样:


OK,最后对这个用伪元素生成的元素进行一些虚化效果(filter 或者 box-shadow 都可以),就可以实现一个边角看起来像被撕开的立体效果:


代码非常简单,伪 CSS 代码示意如下:

1div {
2    position: relative;
3    width: 600px;
4    height: 100px;
5    background: hsl(48, 100%, 50%);
6    border-radius: 20px;
7}
8
9div::before {
10    content: "";
11    position: absolute;
12    top: 50%;
13    left: 5%;
14    right: 5%;
15    bottom: 0;
16    border-radius: 10px;
17    background: hsl(48, 100%, 20%);
18    transform: translate(0, -15%) rotate(-4deg);
19    transform-origin: center center;
20    box-shadow: 0 0 20px 15px hsl(48, 100%, 20%);
21}

所以总结一下:

  • 立体投影的关键点在于利于伪元素生成一个大小与父元素相近的元素,然后对其进行 rotate 以及定位到合适位置,再赋于阴影操作

  • 颜色的运用也很重要,阴影的颜色通常比本身颜色要更深,这里使用 hsl 表示颜色更容易操作,l 控制颜色的明暗度

还有其他很多场景:

CodePen Demo -- 立体投影

文字立体投影 / 文字长阴影

上面的立体效果在文字上就完全不适用了,所以对待文字的立体阴影效果,还需要另辟蹊径。

正常而言,我们使用 text-shadow 来生成文字阴影,像这样:

1<div> Txt Shadow</div>
2-----
3div {
4    text-shadow: 6px 6px 3px hsla(14, 100%, 30%, 1);
5}

嗯,挺好的,就是不够立体。那么要做到立体文字阴影,最常见的方法就是使用多层文字阴影叠加。

Tips:和 box-shadow 一样,text-shadow 是可以叠加多层的!但是对于单个元素而言, drop-shadow的话就只能是一层。

好,上面的文字,我们试着叠加个 50 层文字阴影试一下。额,50 层手写,其实很快的~


好吧,手写真的太慢了,还容易出错,所以这里我们需要借助一下 SASS/LESS 帮忙,写一个生成 50 层阴影的 function 就好,我们每向右和向下偏移 1px,生成一层 text-shadow:

1@function makeLongShadow($color) {
2    $val: 0px 0px $color;
3
4    @for $i from 1 through 50 {
5        $val: #{$val}, #{$i}px #{$i}px #{$color};
6    }
7
8    @return $val;
9}
10
11div {
12    text-shadow: makeLongShadow(hsl(14, 100%, 30%));
13}

上面的 SCSS 代码。经过编译后,就会生成如下 CSS:

1div {
2      text-shadow: 0px 0px #992400, 1px 1px #992400, 2px 2px #992400, 3px 3px #992400, 4px 4px #992400, 5px 5px #992400, 6px 6px #992400, 7px 7px #992400, 8px 8px #992400, 9px 9px #992400, 10px 10px #992400, 11px 11px #992400, 12px 12px #992400, 13px 13px #992400, 14px 14px #992400, 15px 15px #992400, 16px 16px #992400, 17px 17px #992400, 18px 18px #992400, 19px 19px #992400, 20px 20px #992400, 21px 21px #992400, 22px 22px #992400, 23px 23px #992400, 24px 24px #992400, 25px 25px #992400, 26px 26px #992400, 27px 27px #992400, 28px 28px #992400, 29px 29px #992400, 30px 30px #992400, 31px 31px #992400, 32px 32px #992400, 33px 33px #992400, 34px 34px #992400, 35px 35px #992400, 36px 36px #992400, 37px 37px #992400, 38px 38px #992400, 39px 39px #992400, 40px 40px #992400, 41px 41px #992400, 42px 42px #992400, 43px 43px #992400, 44px 44px #992400, 45px 45px #992400, 46px 46px #992400, 47px 47px #992400, 48px 48px #992400, 49px 49px #992400, 50px 50px #992400;
3}

看看效果:


额,很不错,很立体。但是,就是丑,而且说不上来的奇怪。

问题出在哪里呢,阴影其实是存在明暗度和透明度的变化的,所以,对于渐进的每一层文字阴影,明暗度和透明度应该都是不断变化的。这个需求,SASS 可以很好的实现,下面是两个 SASS 颜色函数:

  • fade-out 改变颜色的透明度,让颜色更加透明

  • desaturate 改变颜色的饱和度值,让颜色更少的饱和

关于 SASS 颜色函数,可以看看这里:Sass 基础—颜色函数

我们使用上面两个 SASS 颜色函数修改一下我们的 CSS 代码,主要是修改上面的 makeLongShadow function 函数:

 1@function makelongrightshadow($color) {
2    $val: 0px 0px $color;
3
4    @for $i from 1 through 50 {
5        $color: fade-out(desaturate($color, 1%), .02);
6        $val: #{$val}, #{$i}px #{$i}px #{$color};
7    }
8
9    @return $val;
10}

好,看看最终效果:


嗯,大功告成,这次顺眼了很多~

CodePen Demo -- 立体文字阴影

当然,使用 CSS 生成立体文字阴影的方法还有很多,下面再贴出一例,使用了透明色叠加底色的多重线性渐变实现的文字立体阴影,感兴趣的同学可以去看看具体实现:

线性渐变配合阴影实现条纹立体阴影条纹字

长投影

上面提到了通过多层阴影叠加实现文字的立体阴影。运用在 div 这些容器上也是可以的。当然这里还有一种挺有意思的方法。假设我们,有一个矩形元素,希望给他添加一个长投影,像下面这样:


要生成这种长投影,刚刚说的叠加多层阴影可以,再就是借助元素的两个伪元素,其实上面的图是这样的:


关键点在于,我们通过对两个伪元素的 transform: skew() 变换以及从实色到透明色的背景色变化,实现了长投影的效果:

CodePen Demo -- 线性渐变模拟长阴影

彩色投影

通常而言,我们生成阴影的方式大多是 box-shadowfilter: drop-shadow()text-shadow 。但是,使用它们生成的阴影通常只能是单色或者同色系的。

你这么说,难道还可以生成渐变色的阴影不成?


额,当然不行。


这个真不行,但是通过巧妙的利用 filter: blur 模糊滤镜,我们可以假装生成渐变色或者说是颜色丰富的阴影效果。

假设我们有下述这样一张头像图片:


下面就利用滤镜,给它添加一层与原图颜色相仿的阴影效果,核心 CSS 代码如下:

 1.avator {
2    position: relative;
3    background: url($img) no-repeat center center;
4    background-size: 100% 100%;
5
6    &::after {
7        content: "";
8        position: absolute;
9        top: 10%;
10        width: 100%;
11        height: 100%;
12        background: inherit;
13        background-size: 100% 100%;
14        filter: blur(10px) brightness(80%) opacity(.8);
15        z-index: -1;
16    }
17}

看看效果:


其简单的原理就是,利用伪元素,生成一个与原图一样大小的新图叠加在原图之下,然后利用滤镜模糊 filter: blur() 配合其他的亮度 / 对比度,透明度等滤镜,制作出一个虚幻的影子,伪装成原图的阴影效果。

嗯,最重要的就是这一句 filter: blur(10px) brightness(80%) opacity(.8);

CodePen Demo -- filter create shadow

使用 box-shadow 实现的灯光效果

好,上文主要是一些实现各种阴影的方法,接下来是效果篇。先来看看使用 box-shadow实现的一些灯光效果。

box-shadow 实现霓虹氖灯文字效果

这个效果也叫 Neon,Codepen 上有很多类似的效果,本质上都是大范围的 box-shadow 过渡效果与白色文字的叠加:


CodePen Demo -- box-shadow 实现霓虹氖灯文字效果

使用 box-shadow 实现阴影灯光 show

和上面的效果类似,本质上都是多重阴影的过渡效果,或许再来点 3D 效果?

合理搭配,效果更佳:


CodePen Demo -- 使用 box-shadow 实现阴影灯光 show

使用 drop-shadow | box-shadow 实现单标签抖音 LOGO

嗯哼,既然标题叫你所不知道的 CSS 阴影技巧与细节,那么本文也应该有一点奇技淫巧。

先来看这个,单个标签实现仿抖音 LOGO,当然由于限定在一个元素,所以细节方面还是有很多瑕疵。

想着仿的缘由是某天刷抖音的时候看见这个 LOGO 的一时兴起,CSS 写多了,看见什么东西都会条件反射的想这个能不能用 CSS 实现。

我们先来看看抖音的 LOGO:


其实很简单,主体其实是由 3 个颜色不同类似 J 的形状组成。而单独拎出一个,又可以把它分成四分之三圆、| 以及㇏组成。

正好,一个元素加上它的两个伪元素,刚好可以凑成这三个形状,我们试着实现以下,简单 CSS 代码如下:

 1<div></div>
2---
3div {
4    position: relative;
5    width: 37px;
6    height: 218px;
7    background: #fff;
8
9    &::before {
10        content: "";
11        position: absolute;
12        width: 100px;
13        height: 100px;
14        border: 37px solid #fff;
15        border-top: 37px solid transparent;
16        border-radius: 50%;
17        top: 123px;
18        left: -137px;
19        transform: rotate(45deg);
20    }
21
22        &::after {
23        content: "";
24        position: absolute;
25        width: 140px;
26        height: 140px;
27        border: 30px solid #fff;
28        border-right: 30px solid transparent;
29        border-top: 30px solid transparent;
30        border-left: 30px solid transparent;
31        top: -100px;
32        right: -172px;
33        border-radius: 100%;
34        transform: rotate(45deg);
35    }
36}

上面的代码就可以生成整个形状的主体:


接下来就是轮到 filter: drop-shadow() 登场,它可以在元素呈现之前,为元素的渲染提供一些效果,最常见的也就用它渲染整体阴影。我们通常会用它来实现对话框的小三角与整个对话框的阴影效果,像下面这样,左边是使用 drop-shadow 的效果,右边是使用普通 box-shadow的效果。


本文假定读者已经了解了 drop-shadow 的基本用法,上图效果来自这里:CodePen Demo -- Drop-shadow vs box-shadow (2) By Kseso

OK,回到我们正文,下面我们使用 filter: drop-shadow() 生成它的第一层左边的蓝色阴影,添加在主体 div:

 1div {
2    position: relative;
3    width: 37px;
4    height: 218px;
5    background: #fff;
6    filter:drop-shadow(-10px -10px 0 #24f6f0);
7
8   &::before,
9   &::after {
10    ...
11    }
12}

得到如下效果:


好,接下来我们只需要再添加一层红色 filter: drop-shadow() 在右侧就大功告成!

等等!哪里不对,上面我也有提到过, 和 box-shadow 一样,text-shadow 是可以叠加多层的!但是对于单个元素而言, drop-shadow 的话就只能是一层。

也就是说,无法在 div 上再使用 filter: drop-shadow() 生成另一侧的红色投影,不过还好,我们还有两个伪元素的filter: drop-shadow() 以及 box-shadow 还没有用上,经过一番尝试:

 1div {
2    position: relative;
3    width: 37px;
4    height: 218px;
5    background: #fff;
6    filter:drop-shadow(-10px -10px 0 #24f6f0) contrast(150%) brightness(110%);
7    box-shadow: 11.6px 10px 0 0 #fe2d52;
8
9    &::before {
10        ....
11        filter: drop-shadow(16px 0px 0 #fe2d52);
12    }
13
14    &::after {
15        ....
16        filter:drop-shadow(14px 0 0 #fe2d52);
17    }
18}

我们分别再利用 div 的 box-shadow 以及两个伪元素的 filter: drop-shadow() ,在单个标签的限制下,最终结果如下:


CodePen Demo -- 单标签实现抖音 LOGO

总结一下:

  • 主要借助了两个伪元素实现了整体结构,借助了 drop-shadow 生成一层整体阴影

  • drop-shadow 只能是单层阴影,所以另一层阴影需要多尝试

  • contrast(150%) brightness(110%) 则可以增强图像的对比度和亮度,更贴近抖音 LOGO 的效果

另外

关于上述抖音 LOGO,经友人提醒,其实应该只是两个类 J 形的形状重叠在一起,重叠部分为白色,非重叠部分为各自原色。

当初想复杂了,这个效果我尝试了一下,使用 CSS 的混合模式 mix-blend-mode 也是可以实现的,下面给出实现方法如下,感兴趣的同学可以看看:

CodePen Demo -- 使用 mix-blend-mode 实现抖音 LOGO


当然,关于 CSS 阴影还有很多有意思的技巧和细节,本文限于篇幅不再一一罗列。

我在 Git 上开了个仓库,CSS-Inspiration,以分类的形式,展示不同 CSS 属性或者不同的课题使用 CSS 来解决的各种方法。更多有意思的 CSS 技巧可以在这里找到,而且是每日更新。

最后

感谢耐心读完。更多精彩 CSS 技术文章汇总在我的 Github -- iCSS ,持续更新,欢迎点个 star 订阅收藏。

好了,本文到此结束,希望对你有帮助 :)

原文地址:

https://www.cnblogs.com/coco1s/p/9913885.html

点这,与大家一起分享本文吧~

【CSS】346- 你所不知道的 CSS 阴影技巧与细节的更多相关文章

  1. 你所不知道的 CSS 阴影技巧与细节

    关于 CSS 阴影,之前已经有写过一篇,box-shadow 与 filter:drop-shadow 详解及奇技淫巧,介绍了一些关于 box-shadow 的用法. 最近一个新的项目,CSS-Ins ...

  2. 你所不知道的 CSS 阴影技巧与细节 滚动视差?CSS 不在话下 神奇的选择器 :focus-within 当角色转换为面试官之后 NPOI 教程 - 3.2 打印相关设置 前端XSS相关整理 委托入门案例

    你所不知道的 CSS 阴影技巧与细节   关于 CSS 阴影,之前已经有写过一篇,box-shadow 与 filter:drop-shadow 详解及奇技淫巧,介绍了一些关于 box-shadow  ...

  3. 你所不知道的 CSS 滤镜技巧与细节

    承接上一篇你所不知道的 CSS 动画技巧与细节,本文主要介绍 CSS 滤镜的不常用用法,希望能给读者带来一些干货! OK,下面直接进入正文.本文所描述的滤镜,指的是 CSS3 出来后的滤镜,不是 IE ...

  4. 你所不知道的 CSS 负值技巧与细节

    写本文的起因是,一天在群里有同学说误打误撞下,使用负的 outline-offset 实现了加号.嗯?好奇的我马上也动手尝试了下,到底是如何使用负的 outline-offset 实现加号呢? 使用负 ...

  5. 你所不知道的 CSS 动画技巧与细节

    怕标题起的有点大,下述技巧如果你已经掌握了看看就好,欢迎斧正,本文希望通过介绍一些 CSS 不太常用的技巧,辅以一些实践,让读者可以更加深入的理解掌握 CSS 动画. 废话少说,直接进入正题,本文提到 ...

  6. 你所不知道的CSS

    1.用FONT-SIZE:0来清除间距 inline-block的元素之间会受空白区域的影响,也就是元素之间差不多会有一个字符的间隙.如果在同一行内有4个25%相同宽度的元素,会导致最后一个元素掉下来 ...

  7. 前端开发 CSS中你所不知道的伪类与伪元素的区别--摘抄

    做过前端开发的人都熟悉伪类与伪元素,而真正能够彻底了解这二者的区别的人并不多.伪类与伪元素确实很容易混淆. 伪元素主要是用来创建一些不存在原有dom结构树种的元素,例如:用::before和::aft ...

  8. 你可能不知道的Animation动画技巧与细节

    引言 在web应用中,前端同学在实现动画效果时往往常用的几种方案: css3 transition / animation - 实现过渡动画 setInterval / setTimeout - 通过 ...

  9. 你所不知道的Spring的@Autowired实现细节

    前言 相信很多Java开发都遇到过一个面试题:Resource和Autowired的区别是什么?这个问题的答案相信基本都清楚,但是这两者在Spring中是如何实现的呢?这就要分析Spring源码才能知 ...

随机推荐

  1. 利用GitHub Pages + jekyll快速搭建个人博客

    前言 想搭建自己博客很久了(虽然搭了也不见得能产出多频繁). 最初萌生想写自己博客的想法,想象中,是自己一行一行码出来的成品,对众多快速构建+模板式搭建不屑一顾,也是那段时间给闲的,从前后端选型.数据 ...

  2. deepin 、 windows10,双系统安装

    deepin . windows10,双系统安装: 首先,最好专门分一个盘用来存放deepin操作系统的安装位置(我这里分给它60个G). 1.在 http://rsync.deepin.com/de ...

  3. 【编程题与分析题】Javascript 之继承的多种实现方式和优缺点总结

    [!NOTE] 能熟练掌握每种继承方式的手写实现,并知道该继承实现方式的优缺点. 原型链继承 function Parent() { this.name = 'zhangsan'; this.chil ...

  4. Spring Boot2 系列教程(二十五)Spring Boot 整合 Jpa 多数据源

    本文是 Spring Boot 整合数据持久化方案的最后一篇,主要和大伙来聊聊 Spring Boot 整合 Jpa 多数据源问题.在 Spring Boot 整合JbdcTemplate 多数据源. ...

  5. vuejs学习之新的components组件挂载

    暂时写个目录,内容待完善,主要是记录我的学习过程,方便以后复习

  6. windows版的mysql主从复制环境搭建

    背景 最近在学习用Spring Aop来实现数据库读写分离的功能. 在编写代码之前,首先是要部署好mysql的环境,因为要实现读写分离,所以至少需要部署两个mysql实例,一主一从,并且主从实例之间能 ...

  7. firefox浏览器中使用vux的x-input报错TypeError: _this3.$refs.input.scrollIntoViewIfNeeded is not a function

    最近做公众号项目,想着统一风格,所以决定使用vux. 在调试时发现,只要鼠标点击x-input输入框,就会报错 TypeError: _this3.$refs.input.scrollIntoView ...

  8. 在SQL Server数据库中执行存储过程很快,在c#中调用很慢的问题

    记录工作中遇到的问题,分享出来: 原博客地址:https://blog.csdn.net/weixin_40782680/article/details/85038281 今天遇到一个比较郁闷的问题, ...

  9. C# 未在本地计算机上注册“Microsoft.Jet.OLEDB.4.0”

    “Microsoft.Jet.OLEDB.4.0” 是数据库接口驱动,用来连接数据库的,一般多用于连Access和Excel.我在在winform开发时,在本地运行没有问题,可是部署到另一台服务器上就 ...

  10. Vue 指令总结大全

    1.v-text v-text主要用来更新textContent. <p>{{msg}}</p>与<p v-text="msg2"></p ...