本文收集了些常用的 css,用到的时候可以到这里查看。都是直接可以用的。
三角形
用 border 实现
宽高为 0 border 为 100px 的div 看起来这样
div{
width:0;
height: 0;
border: 100px solid ;
border-top-color:red ;
border-right-color: green;
border-bottom-color:yellowgreen;
border-left-color: blueviolet;
}
以这个为起点,想用哪个三角形就非常容易了。
比如想得到左面紫色三角形,只需要把上右下的三个三角形的 border-border 设成 transparent即可,但这样有一个问题,就是右边还会占有 100px 空间。可以设 border-right-width:0 去掉。
border-right-width: 0;
border-top-color: transparent;
border-bottom-color: transparent;
想得到其它的三角形也是一样,把相对的border-width 设为0 ,相邻两个设为透明。如果想改变高度也很容易,直接修改 border-width 即可。
给用 border 制作的三角形加阴影
<div class="shadow"></div>
.shadow{
width:0;
height: 0;
border: 30px solid transparent;
border-left-width: 0;
border-right-color: green;
filter: drop-shadow(5px 5px 4px black);
}
也许你会有疑问,不是有 box-shadow吗?如果用 box-shadow 就会这样
用 linear-gradient 实现
div{
width:100px;
height:100px;
background: linear-gradient(45deg ,green 50%,transparent 50%) no-repeat ;
}
改变宽高和角度,这种方式可以很容易做出各种直角三角形。直接在 chrome 中动态修改即可,非常方便。
div {
width: 200px;
height: 100px;
background: linear-gradient(27deg, green 50%, transparent 50%) no-repeat;
}
clip-path 实现 三角形
<div class="triangle"></div>
.triangle{
width: 100px;
height: 30px;
background: linear-gradient(red,green);
clip-path: polygon(0 0,100% 0,30% 100%);
}
这才是制作三角形的利器!可以制作任意三角形,背景随意。就是兼容性没有 border 好,而且也无法添加阴影效果。
终极武器 svg
<svg class="triangle" xmlns="http://www.w3.org/2000/svg"
xmlns:xlink="http://www.w3.org/1999/xlink" viewBox="0 0 100 100">
<defs>
<linearGradient id="myGradient" gradientTransform="rotate(90)">
<stop offset="5%" stop-color="gold" />
<stop offset="95%" stop-color="red" />
</linearGradient>
</defs>
<polygon points="0 0,100 50,20 100" fill="url('#myGradient')">
</svg>
.triangle{
width:100px;
stroke: green;
stroke-width: 2px;
filter: drop-shadow(6px 6px 5px black);
}
前面的说的几种方案都有局限性,唯有 svg 可以做到随心所欲。svg 不仅可以写三角形,其它形状也可以。
网格
网格用 repeating-linear-gradient 实现。
width: 100px;
height: 100px;
background: repeating-linear-gradient(0deg, rgba(0, 155, 100, .6) 0 10px, transparent 0 20px),
repeating-linear-gradient(90deg, rgba(0, 155, 100, .3) 0 10px, transparent 0 20px);
用 linear-gradient 也可以实现同样的效果的,而且会更加灵活。repeating-linear-gradient 可以看作是 linear-gradient 的简便写法,让代码看起来更简洁。
虚线
系统自带的虚线效果没什么可操作空间。如果想随意的实现虚线效果,用渐变实现可以随心所欲。
width: 200px;
height: 2px;
background:linear-gradient(90deg,green 0 70%,transparent 0 100%) repeat-x 0 0 /20px 100%;
可以随便调整实线的百分比(当前是 70%),和一段的宽度(当前是 20px) 生成各种各样的虚线。
也可以这样写,把 起止位置连在一起。
background:linear-gradient(90deg,green 0 70%,transparent 0 100%) repeat-x 0 0 /20px 100%;
渐变虚线
width: 200px;
height: 2px;
background:linear-gradient(90deg,#fff 0 30%,transparent 0 100%) repeat-x 0 0 /20px 100%,
linear-gradient(90deg,green,red);
两层背景叠加。
渐变 border
实现直角渐变 border 毫无压力,也非常完美。
width: 100px;
height: 100px;
border: 10px solid;
border-image: linear-gradient(red,green) 1;
添加圆角
width: 100px;
height: 100px;
border: 10px solid;
border-image: linear-gradient(red,green) 1;
//裁剪成圆角
clip-path: inset(0 round 10px);
这种裁剪成圆角的方式只能应用于border 较粗的情况,太细了,border-radius又较大的情况下边缘就看不见border了。比如我们看下 2px 的效果:
也许你会想到两层渐变叠加进行模拟。效果上免强可以,就是四角处有点厚(下图是 border 2px 的效果,而且代码也比较多。并不是很推荐。如果是 1px 宽的话,四角的厚度并不明显,免强可以一用。
.border {
width: 100px;
height: 100px;
position: relative;
}
.border::after{
content:'';
position: absolute;
z-index: 1;
top: 0;
left: 0;
width:100%;
height:100%;
background:linear-gradient(red,green);
border-radius: 10px;
}
.border::before{
border-radius: 10px;
content:'';
top: 2px;
left: 2px;
width:calc(100% - 4px);
height: calc(100% - 4px);
position: absolute;
z-index: 2;
background:#fff;
}
同心圆
用径向渐变写同心圆太轻而易举了
.border {
width:100px;
height:100px;
background: radial-gradient(red 0,red 10px,green 0,green 20px,transparent 0) no-repeat;
}
这样写可以,但是会有很多锯齿,所以我们增加 1px 渐变过渡,让边缘不这么生硬
.border {
width:100px;
height:100px;
background: radial-gradient(red 0,red 10px,green 11px,green 20px,transparent 21px) no-repeat;
}
现在看起来很平滑了。
如果你用第一种写法看起来也很平滑,是因为你的显示器很好,可以显示细微的部分。
渐变文字
<div class="text-clip">一二三四五六七八九十</div>
.text-clip{
font-weight: bold;
font-size: 30px;
height: 40px;
width:320px;
/*最主要的就这三句*/
background: linear-gradient(90deg,red,green);
-webkit-background-clip: text;
color: transparent;
}
很简单,就是用文字来 clip 背景,再把文字透明就可以了。
目前 -webkit- 前缀是必须要加的
mask
mask 出场的机会不多,但是却很重要。比如可以实现文字的纯色渐变
<div class="text-mask">一二三四五六七八九十</div>
.text-mask{
color: green;
font-weight: bold;
font-size: 30px;
width:320px;
-webkit-mask: linear-gradient(-90deg, black, 70%, transparent);
}
70% 写在两个色值中间的含义是中间色的位置,本例中间色的值为 rgba(0,0,0,.5)。
这看起来好像没什么特别,用前面讲过的 background-clip:text 就能实现。
mask 更常用的是用图片做 mask 实现各种效果,用渐变 mask 还可以把 不透明的图片变成透明图片,这样在素材上就可以用 jpg 也能实现半透明的效果。
用mask 做出折线的效果
<div class="line"></div>
.line {
width:80px;
height: 80px;
border:1px solid green;
background: linear-gradient(45deg ,green 0 19px,transparent 21px) no-repeat left bottom;
background-clip: border-box;
-webkit-mask:linear-gradient(45deg ,transparent 0 20px,black 21px 100%) no-repeat left bottom;
}
-webkit- 是必须的,什么颜色没关系,只与透明度有关。
前面的绿色框就是原图形,后面的就是蒙板。折线部分是用渐变背景加上的。蒙板的的效果与颜色无关,也与透明度有关。用蒙板覆盖原图后,只有蒙板透明度不为 0 的部分才能显示。如果透明度在 [0,1] 之间,就是出现半透明效果。
outline
outline 的好处是不占用位置。下图可以帮助理解。
<div class="outline"></div>
<div class="box"></div>
.outline {
width:80px;
height: 80px;
background-color: green;
outline: 3px solid red;
outline-offset: 10px;
margin-left: 20px;
}
.box{
width:120px;
height: 40px;
background-color: steelblue;
}
如果设置 outline-offset: -10px;,还可以有下面的效果
还可以实现加号效果
多行文本省略号
overflow:hidden;
text-overflow:ellipsis;
display:-webkit-box;
-webkit-line-clamp:2; /*(两行文字)*/
-webkit-box-orient:vertical;
line-height:1.5;
不需要加 height,加上 height 反而会导致问题。
页面滚动动画效果
html,body{
scroll-behavior: smooth;
}
如果没有写上面的css,js 也可以办到
window.scrollTo({
top: 100,
left: 100,
behavior: 'smooth'
});
制作饼图
<div class="pie"></div>
.pie {
width: 150px;
height: 150px;
border-radius: 50%;
background: conic-gradient(yellowgreen 60%, deepskyblue 0);
}
纯 css 复选框
默认:<label class="checkbox"></label>
选中:<label class="checkbox checked"></label>
.checkbox {
display: inline-block;
width: 18px; height: 18px;
border: 3px solid transparent;
box-shadow: inset 0 1px, inset -1px 0, inset 0 -1px, inset 1px 0;
color: gray;
user-select: none;
vertical-align: middle;
}
.checkbox.checked {
color: deepskyblue;
background: currentColor;
background-clip: padding-box;
}
.checkbox.checked::before {
content: "";
display: block;
width: 10px; height: 3px;
margin: 5px auto 0;
border: solid #fff;
border-width: 0 0 2px 2px;
transform: rotate(-45deg);
}
这段代码还是有很多讲究的。
- 用透明 border 来扩大点周区域。
- 因为 border 已经占用,用内阴影来模拟 border。
- 因为 border 只是用来扩大点击区域,所以画背景的时候应该把 border 部分去掉
background-clip: padding-box;。 - 对号是用最开始讲过的 border 模拟的。
- 内阴影没有指定颜色,颜色用的就是
color:gray
用内阴影来模拟 border 还是很有用的,因为border 点位置 ,内阴影不占位置。比如一个按钮,hover的时候有 border ,正常情况下没有border,这个就可以用内阴影来模拟 border。
新手引导遮罩
.guide {
box-shadow: 0 0 0 9999px rgba(0, 0, 0, .75);
border-radius: 50%;
}
用的是阴影的扩散半径。box-shaow 的内阴影在背景之上,又在 img 之下,所以 img 没办法用 box-shaow 的内阴影,可以用 outline 替代。
阴影的扩散半径除了正值还可以是负值,负值可以起到收缩的效果。看上面的图阴影扩散出来了。下面的收缩进来,只有下面有阴影效果。
翻牌效果
<ul class="turn">
<li>1</li>
<li>2</li>
</ul>
.turn{
transform-style: preserve-3d;
perspective: 500px;
width:100px;
height: 100px;
font-size: 80px;
font-weight: bold;
text-align: center;
line-height: 100px;
position: relative;
}
.turn li{
list-style: none;
transition: all .5s;
position: absolute;
width: 100%;
top: 0;
left: 0;
backface-visibility: hidden;
}
.turn li:first-child{
background-color: green;
color:rgb(240, 45, 10);
transform: rotateY(0);
}
.turn li:last-child{
background-color: orange;
color: orchid;
transform: rotateY(180deg);
}
.turn:hover li:first-child{
transform: rotateY(180deg);
}
.turn:hover li:last-child{
transform: rotateY(360deg);
}
翻牌用到了 3D 变换。当鼠标 hover 的时候,进行翻牌。
perspective 的中文意思是透视,perspective的大小会影响到变换的幅度。试想一下,你离一个物体越近,感觉物体的移动距离就会越大,离的越远,感觉物体的移动距离就越小。3d 变换的 z 轴代表离透视点的远近。可以用这个示例 translateZ()函数与perspective视角关系 体验一下。
backface-visibility: hidden 的意思是只显示正面,背面不可见。也就是说绕 Y 轴旋转 +90deg 或 -90deg 的时候是临界点,这时目标已经垂直,再转就应该显示背面了。这个属性的作用就是不让背面显示。本例中用两个 li 叠加起来,开始的时候一个没有旋转,另一个旋转180deg,所以只能看到 上面没有旋转的。hover 的时候正反面互换,就有了翻牌的效果。为了更好的理解可以看这个示例 backface-visibility属性基本效果示意。
旋转木马
张老师说弄明白 3d 旋转木马这个例子,对于 CSS 3D 变换 的学习就算是合格了,深以为然。
如果想从头学习 3d 变换,看这篇 CSS3 3D transform变换,不过如此!
其实关键就两步
- 为每个图片平均旋转一个角度
rotateY - 让每个图片向外走几步
translateZ
向外走多少步有公式可以算,也直接在 chrome 里调数值看效果。
边框旋转的按钮
<div class="clip">hello</div>
.clip{
position: relative;
margin: auto;
width: 120px;
line-height: 64px;
text-align: center;
color: #fff;
font-size: 20px;
border: 2px solid gold;
border-radius: 10px;
background: gold;
transition: all .3s;
cursor: pointer;
}
.clip::before,
.clip::after {
content: "";
position: absolute;
top: -10px;
left: -10px;
right: -10px;
bottom: -10px;
border: 2px solid gold;
border-radius: 10px;
}
.clip::before{
animation: clippath 3s infinite linear;
}
.clip::after {
animation: clippath 3s infinite -1.5s linear;
}
逐帧动画
用 steps 阶跃函数,可以实现纯 css 的逐帧动画,原理就是把 n 张图片一张接着一张的展示,和放电影的原理是一样的。
我们用其它的函数比如 linear,会根据关键帧计算出许许多多的中间状态的帧。steps 和其它函数不同的是,可以指定帧的数量。如果只指定了开始和结束这两帧,相当于是执行了超慢动作的 linear 的效果。
我们用这张图片来演示,直接下载就可以用。图片一共宽 300px ,每个色块 100px。通过每次左移 100px,来显示不同的色块。
<div class="step"></div>
.step{
background:url(color.png) no-repeat ;
height: 50px;
width:100px;
animation: step 3s steps(3) infinite;
}
@keyframes step{
from{
background-position: 0 0;
}
to {
background-position: -300px 0;
}
}
steps(3) 的意思是动画分 3 步完成,因为动画 一共 3秒,所以正好一秒走一步。具体过程是这样的。
- 动画在起始位置停 1秒,效果上是显示红色块 1 秒。
- 背景向左移 100px,停 1,秒 ,效果上是显示绿色块 1 秒。
- 背景向左移 100px,停 1,秒 ,效果上是显示蓝色块 1 秒。
经过 3 步后,动画结束,再从第一步开始。因为我们只指定了 from ,to,所以 3 步平均每步移 100px,每步走多少其实是可以指定的。比如可以第二步走 150 px,效果上到第二步的时候就显示一半红,一半绿。
@keyframes step{
from{
background-position: 0 0;
}
50%{
background-position: -150px 0;
}
to {
background-position: -300px 0;
}
}
step 一共有两个参数,本例中是 step(3,end) ,end是默认值。效果上是显示红色块 1秒。
第二个参数可以指定为 start ,效果上是直接显示绿色块,最后显示空白 1 秒。
如果一个图片由 10张 连续的画面橫向拼在一起的,一共 300 px。如果想用 step 连续显示每张图片,就需要分 10 份,一共走 300px,step 用默认的 end 方式。
标签嵌套实现复合动画
两个标签分别实现匀速向右移动和加速向下移动,合起来就是抛物线的效果。
最关键的是这种复合动画的思想,有了这个思想,还可以合成很多效果
env
viewport-fit=cover 必须有这句 env 才能生效。
<meta name="viewport" content="viewport-fit=cover">
env(safe-area-inset-top);
/*20px 是兜底的*/
env(safe-area-inset-top,20px);
/*兼容 ios <11.2,基本上可以不用写,占比太小*/
constant(safe-area-inset-top);
除了top 还有 right,bottom,left 三个值。
取消 300 ms 点击延时
touch-action:manipulation;
还可以禁用手势
touch-action:none;
穿透点击
pointer-events:none;
pointer-events具有继承性,想恢复child的点击
pointer-events:auto;
选中
user-select:all;
改变被选中文字的颜色
::selection{
color:blue;
}
光标
caret-color: red;