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

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

 

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

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

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

 

单侧投影

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

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

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

1
2
3
{
     box-shadow:  none  | [ inset ? && [ ? ? ? ] ]#
}

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

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

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

CodePen Demo -- css单侧投影

  

投影背景 / 背景动画

接着上面的说。

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

CSS代码如下:

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

得到如下结果:

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

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

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

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

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

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

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

为什么选择更为复杂的 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 代码示意如下:

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

所以总结一下:

  • 立体投影的关键点在于利于伪元素生成一个大小与父元素相近的元素,然后对其进行 rotate 以及定位到合适位置,再赋于阴影操作
  • 颜色的运用也很重要,阴影的颜色通常比本身颜色要更深,这里使用 hsl 表示颜色更容易操作,l 控制颜色的明暗度

还有其他很多场景:

CodePen Demo -- 立体投影

 

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

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

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

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

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

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

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

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

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

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

1
2
3
div {
       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 ;
}

看看效果:

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

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

  • fade-out 改变颜色的透明度,让颜色更加透明
  • desaturate 改变颜色的饱和度值,让颜色更少的饱和

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

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

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

好,看看最终效果:

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

CodePen Demo -- 立体文字阴影

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

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

  

长投影

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

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

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

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

 

彩色投影

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

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

额,当然不行。

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

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

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

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

看看效果:

其简单的原理就是,利用伪元素,生成一个与原图一样大小的新图叠加在原图之下,然后利用滤镜模糊 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
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
---
div {
     position relative ;
     width 37px ;
     height 218px ;
     background #fff ;
 
     &::before {
         content "" ;
         position absolute ;
         width 100px ;
         height 100px ;
         border 37px  solid  #fff ;
         border-top 37px  solid  transparent ;
         border-radius:  50% ;
         top 123px ;
         left -137px ;
         transform: rotate( 45 deg);
     }
     
         &::after {
         content "" ;
         position absolute ;
         width 140px ;
         height 140px ;
         border 30px  solid  #fff ;
         border-right 30px  solid  transparent ;
         border-top 30px  solid  transparent ;
         border-left 30px  solid  transparent ;
         top -100px ;
         right -172px ;
         border-radius:  100% ;
         transform: rotate( 45 deg);
     }
}

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

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

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

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

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

得到如下效果:

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

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

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

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

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

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

总结一下:

  • 主要借助了两个伪元素实现了整体结构,借助了 drop-shadow 生成一层整体阴影
  • drop-shadow 只能是单层阴影,所以另一层阴影需要多尝试
  • contrast(150%) brightness(110%) 则可以增强图像的对比度和亮度,更贴近抖音LOGO的效果

 

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

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

 

最后

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

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

如果还有什么疑问或者建议,可以多多交流,原创文章,文笔有限,才疏学浅,文中若有不正之处,万望告知。

 

 

滚动视差?CSS 不在话下

 

何为滚动视差

视差滚动(Parallax Scrolling)是指让多层背景以不同的速度移动,形成立体的运动效果,带来非常出色的视觉体验。 作为网页设计的热点趋势,越来越多的网站应用了这项技术。

通常而言,滚动视差在前端需要辅助 Javascript 才能实现。当然,其实 CSS 在实现滚动视差效果方面,也有着不俗的能力。下面就让我们来见识一二:

 

认识 background-attachment

background-attachment 算是一个比较生僻的属性,基本上平时写业务样式都用不到这个属性。但是它本身很有意思。

background-attachment:如果指定了 background-image ,那么 background-attachment 决定背景是在视口中固定的还是随着包含它的区块滚动的。

单单从定义上有点难以理解,随下面几个 Demo 了解下 background-attachment 到底是什么意思:

background-attachment: scroll

scroll 此关键字表示背景相对于元素本身固定, 而不是随着它的内容滚动。

background-attachment: local

local 此关键字表示背景相对于元素的内容固定。如果一个元素拥有滚动机制,背景将会随着元素的内容滚动, 并且背景的绘制区域和定位区域是相对于可滚动的区域而不是包含他们的边框。

background-attachment: fixed

fixed 此关键字表示背景相对于视口固定。即使一个元素拥有滚动机制,背景也不会随着元素的内容滚动。

注意一下 scroll 与 fixed,一个是相对元素本身固定,一个是相对视口固定,有点类似 position 定位的 absolute 和 fixed

可以感受下 3 种不同取值的不同效果:

CodePen Demo -- bg-attachment Demo

 

使用 background-attachment: fixed 实现滚动视差

首先,我们使用 background-attachment: fixed 来实现滚动视差。fixed 此关键字表示背景相对于视口固定。即使一个元素拥有滚动机制,背景也不会随着元素的内容滚动。

这里的关键在于,即使一个元素拥有滚动机制,背景也不会随着元素的内容滚动。也就是说,背景图从一开始就已经被固定死在初始所在的位置。

我们使用,图文混合排布的方式,实现滚动视差,HTML 结构如下,.g-word 表示内容结构,.g-img 表示背景图片结构:

1
2
3
4
5
6
7
< section  class="g-word">Header section >
< section  class="g-img">IMG1 section >
< section  class="g-word">Content1 section >
< section  class="g-img">IMG2 section >
< section  class="g-word">Content2 section >
< section  class="g-img">IMG3 section >
< section  class="g-word">Footer section >

关键 CSS:

1
2
3
4
5
6
7
8
9
10
section {
     height 100 vh;
}
 
.g-img {
     background-image url (...);
     background-attachment fixed ;
     background- size : cover;
     background-position center  center ;
}

效果如下:

CodePen Demo -- https://codepen.io/Chokcoco/pen/JBaQoY

嗯?有点神奇,为什么会是这样呢?可能很多人会和我一样,第一次接触这个属性对这样的效果感到懵逼。

我们把上面 background-attachment: fixed 注释掉,或者改为 background-attachment: local,再看看效果:

CodePen Demo -- bg-attachment:local

这次,图片正常跟随滚动条滚动了,按常理,这种效果才符合我们大脑的思维。

而滚动视差效果,正是不按常理出牌的一个效果,重点来了:

当页面滚动到图片应该出现的位置,被设置了 background-attachment: fixed 的图片并不会继续跟随页面的滚动而跟随上下移动,而是相对于视口固定死了。

好,我们再来试一下,如果把所有 .g-word 内容区块都去掉,只剩下全部设置了 background-attachment: fixed 的背景图区块,会是怎么样呢?

HTML 代码如下:

1
2
3
< section  class="g-img">IMG1 section >
< section  class="g-img">IMG2 section >
< section  class="g-img">IMG3 section >
1
2
3
4
5
6
7
8
9
10
section {
     height 100 vh;
}
 
.g-img {
     background-image url (...);
     background-attachment fixed ;
     background- size : cover;
     background-position center  center ;
}

效果如下:

CodePen Demo

结合这张 GIF,相信能对 background-attachment: fixed 有个更深刻的认识,移动的只有视口,而背景图是一直固定死的。

综上,就是 CSS 使用 background-attachment: fixed 实现滚动视差的一种方式,也是相对而言比较容易的一种。当然,background-attachment: fixed 本身的效果并不仅只是能有用来实现滚动视差效果,合理运用,还可以实现其他很多有趣的效果,这里简单再列一个:

 

background-attachment: fixed 实现图片点击水纹效果

利用图片相对视口固定,可以有很多有趣的效果,譬如下面这个,来源于这篇文章CSS Water Wave (水波效果):

CodePen Demo -- bg-attachment:fixed Wave

利用图片相对视口固定的特性实现点击的水纹效果。

上面这个效果有点瑕疵,图片在放大容器变大的过程中发生了明显的抖动。当然,效果还是可以的,background-attachment 还有很多有意思的效果可以挖掘。

 

使用 transform: translate3d 实现滚动视差

言归正传,下面介绍另外一种使用 CSS 实现的滚动视差效果,利用的是 CSS 3D。

原理就是:

  1. 我们给容器设置上 transform-style: preserve-3d 和 perspective: xpx,那么处于这个容器的子元素就将位于3D空间中,

  2. 再给子元素设置不同的 transform: translateZ(),这个时候,不同元素在 3D Z轴方向距离屏幕(我们的眼睛)的距离也就不一样

  3. 滚动滚动条,由于子元素设置了不同的 transform: translateZ(),那么他们滚动的上下距离 translateY 相对屏幕(我们的眼睛),也是不一样的,这就达到了滚动视差的效果。

关于 transform-style: preserve-3d 以及 perspective 本文不做过多篇幅展开,默认读者都有所了解,还不是特别清楚的,可以先了解下 CSS 3D。

核心代码表示就是:

1
2
3
4
5
< div  class="g-container">
     < div  class="section-one">translateZ(-1) div >
     < div  class="section-two">translateZ(-2) div >
     < div  class="section-three">translateZ(-3) div >
div >
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
html {
     height 100% ;
     overflow hidden ;
}
 
body {
     perspective:  1px ;
     transform-style: preserve -3 d;
     height 100% ;
     overflow-y:  scroll ;
     overflow-x:  hidden ;
}
 
.g-container {
     height 150% ;
 
     .section-one {
         transform: translateZ( -1px );
     }
     .section-two {
         transform: translateZ( -2px );
     }
     .section-three {
         transform: translateZ( -3px );
     }
}

总结就是父元素设置 transform-style: preserve-3d 和 perspective: 1px,子元素设置不同的 transform: translateZ,滚动滚动条,效果如下:

css3dparallax

CodePen Demo -- CSS 3D parallax

很明显,当滚动滚动条时,不同子元素的位移程度从视觉上看是不一样的,也就达到了所谓的滚动视差效果。

滚动视差文字阴影/虚影效果

那么,运用 translate3d 的视差效果,又能有一些什么好玩的效果呢?下面这个滚动视差文字阴影/虚影效果很有意思:

CodePen Demo -- CSS translate3d Parallax

当然,通过调整参数(perspective: ?px 以及 transform: translateZ(-?px);),还能有其他很有意思的效果出现:

CodePen Demo -- CSS translate3d Parallax 2

是不是很有电影开片的厂商 LOGO 的特效的感觉  。

师父领进门,修行在个人,怎么制作更好更有意思的效果还是需要花时间钻研和琢磨,这里我仅仅是抛砖引玉,希望能见到更多 Nice 的效果。

 

最后

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

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

如果还有什么疑问或者建议,可以多多交流,原创文章,文笔有限,才疏学浅,文中若有不正之处,万望告知。

 

 

神奇的选择器 :focus-within

 

CSS 的伪类选择器和伪元素选择器,让 CSS 有了更为强大的功能。

伪类大家听的多了,伪元素可能听到的不是那么频繁,其实 CSS 对这两个是有区分的。

有个错误有必要每次讲到伪类都提一下,有时你会发现伪类元素使用了两个冒号 (::) 而不是一个冒号 (:),这是 CSS3 规范中的一部分要求,目的是为了区分伪类和伪元素,大多数浏览器都支持下面这两种表示方式。

通常而言,

1
2
3
4
5
6
7
#id:after{
  ...
}
 
#id::after{
...
}

符合标准而言,单冒号(:)用于 CSS3 伪类,双冒号(::)用于 CSS3 伪元素。

当然,也有例外,对于 CSS2 中已经有的伪元素,例如 :before,单冒号和双冒号的写法 ::before 作用是一样的。

所以,如果你的网站只需要兼容 webkit、firefox、opera 等浏览器或者是移动端页面,建议对于伪元素采用双冒号的写法,如果不得不兼容低版本 IE 浏览器,还是用 CSS2 的单冒号写法比较安全。

 

伪类选择器 :focus-within

言归正传,今天要说的就是:focus-within 伪类选择器。

它表示一个元素获得焦点,或,该元素的后代元素获得焦点。划重点,它或它的后代获得焦点。

这也就意味着,它或它的后代获得焦点,都可以触发 :focus-within

:focus-within 的冒泡性

这个属性有点类似 Javascript 的事件冒泡,从可获焦元素开始一直冒泡到根元素 html,都可以接收触发 :focus-within 事件,类似下面这个简单的例子这样:

1
2
3
4
5
< div  class="g-father">
     < div  class="g-children">
         < input  type="button" value="Button">
     div >
div >
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
html,
body,
.g-father,
.g-children {
     padding 30px ;
     border : 1px  solid  #999 ;
}
 
input {
     ...
     &:focus {
         background #00bcd4 ;
     }
}
 
html:focus-within {
     background #e91e63 ;
}
body:focus-within {
     background #ff5722 ;
}
.g-father:focus-within {
     background #ffeb3b ;
}
.g-children:focus-within {
     background #4caf50 ;
}

就是这样:

CodePen Demo -- :focus-within 冒泡触发

这个选择器的存在,让 CSS 有了进一步的让元素持久停留在一种新状态的的能力。

下面几个例子,看看 :focus-within 可以提供什么能力,做些什么事情。

 

感应用户聚焦区域

它或它的后代获得焦点,这一点使得让感知获焦区域变得更大,所以,最常规的用法就是使用 :focus-within 感应用户操作聚焦区域,高亮提醒。

下面的效果没有任何 JS 代码:

这里是什么意思呢?:focus-within 做了什么呢?

  • 我们无须去给获焦的元素设置 :focus 伪类,而是可以给需要的父元素设置,这样当元素获焦时,我可以一并控制它的父元素的样式

核心思想用 CSS 代码表达出来大概是这样:

1
2
3
4
5
6
7
8
< div  class="g-container">
     < div  class="g-username">
         < input  type="text" placeholder="user name" class="g_input" >
     div >
     < div  class="g-username">
         < input  type="text" placeholder="code" class="g_input" >
     div >
div >
1
2
3
4
5
6
7
.g-container:focus-within {
     ...
 
     input {
         ....
     }
}

DEMO -- CSS focus-within INPUT

运用上面思想,我们可以把效果做的更炫一点点,在某些场景制作一些增强用户体验的效果:

DEMO -- PURE CSS FOCUS By :focus-within

 

TAB导航切换

在之前的一篇文章里,介绍了两种纯 CSS 实现的 TAB 导航栏切换方法:

纯CSS的导航栏Tab切换方案

现在又多了一种方式,利用了 :focus-within 可以在父节点获取元素获得焦点的特性,实现的TAB导航切换:

DEMO -- focus-within switch tab

主要的思路就是通过获焦态来控制其他选择器,以及最重要的是利用了父级的 :not(:focus-within) 来设置默认样式:

1
2
3
4
5
6
7
8
9
10
11
.nav-box:not(:focus-within) {
     // 默认样式
}
 
.nav-A:focus-within ~ .content-box .content-A {
     display block ;
}
 
.nav-B:focus-within ~ .content-box .content-B {
     display block ;
}

 

配合 :placeholder-shown 伪类实现表单效果

:focus-within 一个人能力有限,通常也会配合其他伪类实现一些不错的效果。这里要再简单介绍的是另外一个有意思的伪类 :placeholder-shown

:placeholder-shown:The :placeholder-shown CSS pseudo-class represents any or

复制代码

对于设置属性的值,是安全的

复制代码


 
复制代码

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

1.4.3 前端Handlebars模板中的安全问题

后端有Smarty模板,前端也可以有Handlebars模板,使用模板有利于开发维护代码。不过和后端一样,使用模板也要考虑到XSS的问题

Handlebars模板中可选择是否开启转义

复制代码


{{name}}
 

{{{name}}}
复制代码

所以要注意的第一点是:

如果使用了转义占位符,就需要先进行还原;如果不使用转义,就不要还原,否则将造成XSS

另外,Handlebars模板可以自定义helper,helper有两种使用方式,直接返回数据或返回子层

复制代码


 


 
 


 

 
复制代码

进入页面后,将会执行 alert(1) ,然后鼠标滑过span或input元素,将会执行 alert(2)

这是因为Handlebars在处理helper时,如果是返回数据,将不进行转义过滤

解决方案为:

如果使用了自定义的helper直接返回数据,先转义一遍,即取消注释[1] 处 代码

或者不直接返回数据,即注释模板[A],[1] 和[2]处,取消注释模板[B],[3]处 代码

 

另外,前端模板会频繁和JS进行交互,在前端直接使用JS获取URL参数并放到模板中时,要格外注意防止产生DOM-base型XSS,如下面这段代码

复制代码
Payload: http://local.abc.com/main/?r=abc/index¶m=%22%20οnmοuseοver=%22alert(2)%22
 
function getUrlParam(name) {
    let value = window.location.search.match(new RegExp('[?&]' + name + '=([^&]*)(&?)', 'i'));
    return value ? decodeURIComponent(value[1]) : '';
}
var attrData = getUrlParam('param');
复制代码

1.4.4  React JSX模板中的 dangerouslySetInnerHTML

alert(1);'}}>

这段代码会执行么

事实上,并不会。与模板不同,它使用的是 innerHTML来更新DOM元素的内容,所以不会执行恶意代码

不过,这个内容不会显示在页面中,如果这时正常的一段内容,就应该转义之后再放入 __html的值中

 

1.4.5 在React的服务端渲染中,也要注意安全问题

服务端渲染需要一个初始的state,并与客户端做对应

可能会长这样子

复制代码

<|- appHtml |>
// 服务端 res.render('xxx.html', { appHtml: appHtml, preloadState: JSON.stringify(preloadState).replace(/
复制代码

类似模板,服务端将数据传给客户端时,在模板组装数据的时候要防止构造出闭合 ?r=abc/index&a=\&b==alert(1);function b(){}//

复制代码

假设只对 ' " > < & 进行了转义,可以试试从URL拿数据,这里需要利用到JS代码中关键的 & 符号与 \ 转义符

\ 将第一个分号转义为字符串

& 与运算将前后分离

b的参数加上 = 号构造处bool运算

为了防止b未定义,在后面用函数提升特性来定义

最后注释符防止报错

为了攻击也是蛮拼的....所以最好还是要对JS操作的字符用反斜杠进行转义一下,比如 \  -> \\

 

1.4.9 图片 exif 信息含有恶意代码

另一种XSS攻击的方式是在图片的exif信息中注入脚本,在读取图片信息时要注意过滤

在早期的很多插件中都没有进行处理,如之前爆出的 Chrome Exif Viewer 插件问题,可能还有相关插件没有这些意识,平时也要注意

另外,站点自身在读取文件信息时也要注意,攻击者在上传文件前,可能会对文件的信息进行修改,过滤不当很可能就造成严重的存储型漏洞

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

 

 

 

委托入门案例

 

我本人对于委托最多的使用就是子线程调用主线程的控件的使用。可能使用winform或者wpf的人接触的多一点。

这里最主要还是给大家看看委托的案例吧

delegate void showMsg(string Msg);
showMsg s;

第一种委托的方法
s+=func;
s("aaa");


第二种委托方法(这种方式用的多)
s=new showMsg(func);
s("aaa")'

public void func(string s)
{
console.WriteLine("aaa"+s);
}

 

当然也有 这种方式的委托,在应用程序的主线程上执行指定的委托

this.Invoke(new Action(()=>{Console.WriterLine("aaa")}); 

  异步委托
this.Dispatcher.BeginInvoke((Action)delegate ()
                {Console.WriterLine("aaa")});
 

转载于:https://www.cnblogs.com/cjm123/p/9930841.html

你可能感兴趣的:(你所不知道的 CSS 阴影技巧与细节 滚动视差?CSS 不在话下 神奇的选择器 :focus-within 当角色转换为面试官之后 NPOI 教程 - 3.2 打印相关设置 前端XSS相关整...)