常用 CSS

186 阅读12分钟

本文收集了些常用的 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 制作的三角形加阴影

image.png

<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 就会这样

image.png

用 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 实现 三角形

image.png

<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 实现。

image.png

  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 的简便写法,让代码看起来更简洁。

虚线

系统自带的虚线效果没什么可操作空间。如果想随意的实现虚线效果,用渐变实现可以随心所欲。

image.png

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%;

渐变虚线

image.png

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 毫无压力,也非常完美。

image.png

  width: 100px;
  height: 100px;
  border: 10px solid;
  border-image: linear-gradient(red,green) 1;

添加圆角

image.png

  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 的效果:

image.png

也许你会想到两层渐变叠加进行模拟。效果上免强可以,就是四角处有点厚(下图是 border 2px 的效果,而且代码也比较多。并不是很推荐。如果是 1px 宽的话,四角的厚度并不明显,免强可以一用。

image.png

.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;
}

同心圆

用径向渐变写同心圆太轻而易举了

image.png

.border {
  width:100px;
  height:100px;
  background: radial-gradient(red 0,red 10px,green 0,green 20px,transparent 0) no-repeat;
}

这样写可以,但是会有很多锯齿,所以我们增加 1px 渐变过渡,让边缘不这么生硬

image.png

.border {
  width:100px;
  height:100px;
  background: radial-gradient(red 0,red 10px,green 11px,green 20px,transparent 21px) no-repeat;
}

现在看起来很平滑了。

如果你用第一种写法看起来也很平滑,是因为你的显示器很好,可以显示细微的部分。

渐变文字

image.png

<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 出场的机会不多,但是却很重要。比如可以实现文字的纯色渐变

image.png

<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;
}

image.png

-webkit- 是必须的,什么颜色没关系,只与透明度有关。

前面的绿色框就是原图形,后面的就是蒙板。折线部分是用渐变背景加上的。蒙板的的效果与颜色无关,也与透明度有关。用蒙板覆盖原图后,只有蒙板透明度不为 0 的部分才能显示。如果透明度在 [0,1] 之间,就是出现半透明效果。

outline

outline 的好处是不占用位置。下图可以帮助理解。

image.png

<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;,还可以有下面的效果

image.png

还可以实现加号效果

多行文本省略号

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);
}

查看网页效果

来源: demo.cssworld.cn/new/3/10-6.…

这段代码还是有很多讲究的。

  • 用透明 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%;
}

查看网页效果

来源:demo.cssworld.cn/new/4/3-2.p…

用的是阴影的扩散半径。box-shaow 的内阴影在背景之上,又在 img 之下,所以 img 没办法用 box-shaow 的内阴影,可以用 outline 替代。

阴影的扩散半径除了正值还可以是负值,负值可以起到收缩的效果。看上面的图阴影扩散出来了。下面的收缩进来,只有下面有阴影效果。

image.png

image.png

翻牌效果

<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变换,不过如此!

其实关键就两步

  1. 为每个图片平均旋转一个角度 rotateY
  2. 让每个图片向外走几步 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;
}

来源 csscoco.com/inspiration…

逐帧动画

用 steps 阶跃函数,可以实现纯 css 的逐帧动画,原理就是把 n 张图片一张接着一张的展示,和放电影的原理是一样的。

我们用其它的函数比如 linear,会根据关键帧计算出许许多多的中间状态的帧。steps 和其它函数不同的是,可以指定帧的数量。如果只指定了开始和结束这两帧,相当于是执行了超慢动作的 linear 的效果。

color.png

我们用这张图片来演示,直接下载就可以用。图片一共宽 300px ,每个色块 100px。通过每次左移 100px,来显示不同的色块。

2.gif

<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秒,效果上是显示红色块 1 秒。
  2. 背景向左移 100px,停 1,秒 ,效果上是显示绿色块 1 秒。
  3. 背景向左移 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 方式。

标签嵌套实现复合动画

两个标签分别实现匀速向右移动和加速向下移动,合起来就是抛物线的效果。

查看网页效果

来源:www.zhangxinxu.com/study/20180…

最关键的是这种复合动画的思想,有了这个思想,还可以合成很多效果

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;