CSS总结

芝麻凛 2021年08月05日 133次浏览

CSS 知识总结

CSS是由Hakon Wium Lie发明的

CSS强大在于它是层叠样式表。

层叠是指什么?

样式层叠:可以多次对同一选择器进行样式声明

选择器层叠:可以用不同选择器对同一个元素进行样式声明

文件层叠:可以用多个文件进行层叠

这些特效使得CSS极度灵活,但也有一些隐患。

CSS的版本有:

CSS1:1996年发布。

CSS2:1998年发布。添加了定位,z-index,media

CSS2.1:2004~2011年 使用最广泛的版本(IE支持)

CSS3:1999年起草 现代版本,分模块(IE8部分支持)

CSS4*:分模块升级

使用caniuse.com查看浏览器都支持那些特效。

CSS是艺术,需要使用感性思维来理解CSS。

CSS语法

语法一:样式语法

选择器 {

	属性名: 属性值;	/*注释*/

}
语法二:at语法
@charset "UTF-8";
@import url(2.css);
@media (min-width: 100px) and (max-width: 200px) {
    语法一
}

注意事项

  • 所有的符号都是英文符号
  • 区分大小写,a和A是不同的东西
  • 注释只有一种,那就是/注释/
  • 最后一个分号可以省略,但不建议
  • 任何地方写错了,都不会有提示浏览器会直接忽略
  • @charset必须放在第一行
  • 前两个at语法必须以分号;结尾
  • charset是字符集的意思,但UTF-8是字符编码encoding,这是历史遗留问题

CSS Border调试法

步骤

  • 怀疑某个元素有问题
  • 就给这个元素加border
  • border没有出现?说明选择器错了或者语法错了
  • border出现了?看看边界是否符合预期
  • bug解决了才可以把border删掉

CSS基本概念

要理解几个重要的概念

  • 文档流 Normal Flow(文档中元素流动方向)
  • 块、内联、内联块
  • margin 合并
  • 两种盒模型(border-box更符合人类思维)

文档流

流动方向

  • inline 元素从左到右,到达最右边才会换行
  • block元素从上到下,每一个都另起一行
  • inline-block也是从左到右,但是到达页面末尾的时候它还是会保持整块的样式。

宽度

  • inline宽度为内部inline元素之和,不能用width指定
  • block默认自动(auto)计算宽度不是百分之百,可以用width指定
  • inline-block结合前两个的特点,可以width

高度

  • inline高度由line-height间接决定,跟height无关,跟padding也无关(字体会影响到行盒)
  • block高度由内部文档流元素决定,可以设height
  • inline-block跟block类似,可以设置height

不要在inline元素中写block元素。

大部分时候样式不要写宽度100%,特别情况除外。

如果div里面什么都没有那么div的高度就是0,span的高度使用line-height决定的。

overflow溢出

当内容大于容器

  • 等内容的宽度或高度大于容器的,会溢出
  • 可用overflow来设置是否显示滚动条
  • auto是灵活设置
  • scroll是永远显示
  • hidden是直接隐藏溢出部分
  • visible是直接显示溢出部分
  • overflow可以分为overflow-x和overflow-y

脱离文档流

回忆一下

block高度由内部文档流元素决定,可以设置height

这句话的意思是不是说,有些元素可以不在文档流中

那些元素脱离文档流

float

position: absolute / fixed

脱离文档流后会影响高度的计算,所在元素就不把元素算在高度里面了。

怎么让元素不脱离文档流

不使用上面属性就不脱离了。

两种盒模型

分别是

content-box 内容盒 - 内容就是盒子的边界

border-box 边框盒 - 边框才是盒子的边界

公式

content-box width = 内容宽度

border-box width = 内容宽度 + padding + border

那个好用

border-box好用,给一个盒子同时指定padding、width、border 就知道为什么了。

宽度只包含内容就是content-box,如果宽度包含border,那就是border-box

margin合并

那些情况会合并

父子margin合并、兄弟margin合并

如何阻止合并

  • 父子合并用padding/border挡住
  • 父子合并用overflow: hidden挡住
  • 父子合并用display: flex,不知道为什么
  • 兄弟合并可以用inline-block消除
  • 总之要一条一条记,而且css属性逐年增多,每年都可能有新的

基本单位

长度单位

  • px像素
  • em相对于自身font-size的倍数
  • 百分数
  • 整数
  • rem
  • vw和vh

颜色

  • 十六进制#FF6600或者#F60
  • RGBA颜色 rgb(0,0,0) 或者 rgb(0,0,0,1)
  • hsl颜色 hsl(360,100%,100%)

CSS布局

布局是什么?

把页面分成一块一块,按左中右,上中下等排列。

布局分类

两种

  • 固定宽度布局,一般宽度为960/1000/1024px
  • 不固定宽度布局,主要靠文档流的原理来布局

文档流本来就是自适应的,不需要加额外的样式

第三种布局

  • 响应式布局
  • 意思就是PC上固定宽度,手机上不固定宽度
  • 也就是一种混合布局

布局的两种思路

从大到小

  • 先定下大局
  • 然后完善每个部分小布局

从小到大

  • 先完成小布局
  • 然后组成大布局

两种均可

  • 新人推荐第二种,因为小的简单
  • 老手一般第一种,因为熟练了有了布局观

CSS布局采用:main、header、footer、nav、aside标签

Float 布局

步骤

  • 子元素上加上 float: left 和 width
  • 在父元素上加 .clearfix (一定要加)

经验

  • 有经验的会留一些空间或者最后一个设width

  • 不需要做响应式,因为手机上没有IE,而这个布局是专门为IE准备的

  • IE 6/7 存在双倍margin bug,解决的办法有两个

  • 一是将错就错,针对IE 6/7 把margin减半(_margin-left: 10px;)

  • 二是再加上一个display: inline-block

  • 加上头尾,接口满足所有PC页面需求

  • 手机页面不用float

  • float要程序员自己计算宽度,不灵活

  • float用来应付IE足以

  • vertical-align: top;去除图片下面多出的部分。

    • vertical-align属性可被用于两种环境:

    • 使行内元素盒模型与其行内元素容器垂直对齐。例如,用于垂直对齐一行文本的内的图片

    • 垂直对齐表格单元内容

    注意 vertical-align 只对行内元素、表格单元格元素生效:不能用它垂直对齐块级元素

有时候在调试的时候border会干扰,可以替换成outline

一个块级元素,并且宽度是固定的那么 margin-left: auto; margin-right: auto;就可以直接居中这样写比margin: 0 auto;好。因为0可能覆盖前面的margin。

float布局实践

<!DOCTYPE html>
<html lang="en">

<head>
  <meta charset="UTF-8">
  <meta http-equiv="X-UA-Compatible" content="IE=edge">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>Document</title>
</head>

<body>
  <header class="clearfix"> 
    <div class="logo">
      <img src="https://xiedaimala.com/packs/_/assets/images/logos/red-logo-3f8db9041e6c15d4ae7ed7e4087c4b98.png" alt="">
    </div>
    <ul class="clearfix nav">
      <li>首页</li>
      <li>课程</li>
      <li>优惠</li>
      <li>关于</li>
    </ul>
   </header>
  
  <div class="content clearfix">
    <aside>一行有六个字</aside>
    <main></main>
    <div class="ad"></div>
  </div>
  <div class="imageList">
    <div class="x clearfix">
      <div class="image"></div>
      <div class="image"></div>
      <div class="image"></div>
      <div class="image"></div>
      <div class="image"></div>
      <div class="image"></div>
      <div class="image"></div>
      <div class="image"></div>
      </div>
  </div>
</body>

</html>
* {
  margin: 0;
  padding: 0;
  box-sizing: border-box;
}

ul,ol{
  list-style:none;
}

img {
  max-width: 100%;
}

.clearfix::after{
  content:'';
  display: block;
  clear: both;
}

.logo{
  float: left;
  background: grey;
  display: inline-block;
  margin-top: 8px;
  margin-left: 10px;
}
.logo>img{
  height: 26px;
  vertical-align: middle;
}

.nav {
  float: right;
  margin-left: 20px;
}

ul > li {
  float:left;
  padding: 4px 0.5em;
  line-height: 32px;
}
ul{
  display: inline-block;
}
header {
  background: grey;
  color: white;
}
.content{
  outline: 1px solid red;
  width: 800px;
  margin-left: auto;
  margin-right: auto;
}
.content>aside{
  width: 200px;
  height: 300px;
  float: left;
  background: #999;
}
.content>main{
  height: 300px;
  width: 500px;
  float: left;
  background: #aaa;
}
.content>.ad{
  width: 100px;
  height: 300px;
  float: left;
  background: #000;
}


.imageList{
  outline: 1px solid green;
  width: 800px;
  margin-left: auto;
  margin-right: auto;
  margin-top: 10px;
}
.imageList > .x > .image{
  width: 191px;
  height: 191px;
  background: #000;
  border: 1px solid blue;
  float: left;
  margin-bottom: 10px;
  margin-right: 12px;
  
}
.imageList > .x{
  margin-right: -12px;
}

Flex布局

容器 container(父元素)

items(子元素)

flex container 有哪些样式

让一个元素变成flex容器

.container {
	display: flex; /* or inline-flex */
    flex-direction: row | row-reverse | column | column-reverse; /*改变items流动方向(主轴)*/
    flex-wrap: nowrap | wrap | wrap-reverse	/*是否折行*/
    justify-content: flex-start | flex-end | center | space-between | space-around | space-evenly /*主轴对齐方式 默认是横轴,除非改变了flex-direction方向*/
    align-items: stretch | flex-start | flex-end | center | baseline 	/*次轴对齐方式 默认次轴是纵轴 */
    align-content: flex-start | flex-end | center | stretch | space-between | space-around  /*多行内容*/
}

flex item 有哪些属性

item上面加order改变它的显示顺序顺序,从小到大排列。

item上面加flex-grow (控制自己如何长胖)

flex-shrink控制如何缩小,一般写flex-shrink: 0防止变小,默认是1。

flex-basis 控制基准宽度:默认是auto

align-self定制align-items:flex-start flex-end,指定某一个item特点。

重点

记住这些代码

  • display: flex
  • flex-direction: row / column
  • flex-wrap: wrap
  • justify-content: center /space-between
  • align-items: center

使用flex布局

<!DOCTYPE html>
<html>
<head>
  <meta charset="utf-8">
  <title>JS Bin</title>
</head>
<body>
  <header class="header"> 
    <div class="logo">
      <img src="https://xiedaimala.com/packs/_/assets/images/logos/red-logo-3f8db9041e6c15d4ae7ed7e4087c4b98.png" alt="">
    </div>
    <ul class="clearfix nav">
      <li>首页</li>
      <li>课程</li>
      <li>优惠</li>
      <li>关于</li>
    </ul>
   </header>
  <div class="content">
    <aside>一行有六个字</aside>
    <main></main>
    <div class="ad"></div>
   </div>
    <div class="imageList">
      <div class="x">
        <div class="image"></div>
        <div class="image"></div>
        <div class="image"></div>
        <div class="image"></div>
        <div class="image"></div>
        <div class="image"></div>
        <div class="image"></div>
        <div class="image"></div>
      </div>
  </div>
</body>
</html>
* {
  margin: 0;
  padding: 0;
  box-sizing: border-box;
}
ul,ol{
  list-style:none;
}

img {
  max-width: 100%;
}

.header{
  display:flex; 
  justify-content: space-between;
  align-items: center;
  background: grey;
  padding: 4px 0;
}

.logo{
  display: flex;
  align-items: center;
}
.logo>img{
  height: 26px;
  vertical-align: middle;
}

ul{
  /* margin-left: auto; */
  display: flex;
}

ul>li{
  padding: 4px;
}

.content{
  display: flex;
  width: 800px;
  margin-left: auto;
  margin-right: auto;
}
.content>aside{
  background: #000;
  width: 200px;
}
.content>main{
  background: #666;
  height: 400px;
  flex-grow: 1;
}
.content>.ad{
  background: #999;
  width: 100px
}

.imageList{
  width: 800px;
  margin-left: auto;
  margin-right: auto;
  margin-top: 10px;
  
}
.imageList>.x{
  display: flex;
  flex-wrap: wrap;
  margin-right: -12px;
}
.image{
  width: 191px;
  height: 191px;
  background: grey;
  border: 1px solid red;
  margin-right: 12px;
  margin-bottom: 10px;
}

经验

  • 永远不要把width和height写死,除非特殊说明
  • 用min-width、max-width、min-height、max-height
  • flex可以基本满足所有需求
  • flex和margin-xxx: auto 配合有意外的效果

写死

  • width: 100px;

不写死

  • width: 50%
  • max-width: 100px
  • width: 30vw
  • min-width: 80%
  • 特点:不使用px,或者加min max 前缀

Grid布局

二维布局用Grid,一维布局使用Flex

grid也分container和items

如何让一个元素成为Grid的container

.container{
	display: grid | inline-grid;
    /*设置行和列*/
    grid-template-columns: 40px 50px auto 50px 40px; 
    grid-template-rows: 25% 100px auto;
}
/*还可以给每一条线取名字*/
.container {
    grid-template-columns: [first] 40px [line2] 50px [line3] auto
    [col4-start] 50px [five] 40px [end];
    grid-template-rows: [row1-start] 25% [row1-end] 100px [third-line]
    auto [last-line];
}

取名有什么用

item可以设置范围

item-a {
	grid-column-start: 2;
	grid-column-end: five;
	grid-row-start: row1-start;
	grid-row-end: 3;
}
/*fr -- free space*/
.container{
    grid-template-columns: 1fr 1fr 1fr;
    grid-template-columns: 1fr 50px 1fr 1fr;
}

分区 grid-template-areas

.item-a {
    grid-area: header;
}
.item-b{
    grid-area: main;
}
.item-c {
    grid-area: sidebar;
}
.item-d{
    grid-area: footer;
}
.container {
    display: gird;
    grid-template-columns: 50px 50px 50px 50px;
    grid-template-rows: auto;
    grid-template-areas: 
        "header header header header"
        "main main . sidebar"
        "footer footer footer footer"
}

空隙 gap

.container {
	grid-template-columns:100px 50px 100px;
	grid-template-rows: 80px auto 80px;
	grid-columns-gap: 10px;
	grid-row-gap: 15px;
}

Grid尤其适合不规则布局

CSS定位

布局和定位有什么区别?

布局是屏幕平面上的,定位是垂直于屏幕的。

两个问题

  • 背景的范围是从哪到哪?
    • A. border 内边沿围成的区域
    • B. border 外边沿围成的区域
    • 如何验证自己的猜想 将border调整为半透明试试
  • 从左边看一个div ,是什么样子
    • background 在文字后面

一个div 的分层

background、border、块级子元素、浮动元素、内联子元素,从下往上。

浮动元素脱离文档流,其实就是浮起来了一点,产生了分层。

属性:position

position

  • static默认值,待在文档流里
  • relative相对定位,升起来,但不脱离文档流
  • absolute绝对定位,定位基准是祖先里的非static
  • fixed 固定定位。定位基准是viewport
  • sticky 粘性定位,不好描述。

经验

  • 如果写了absolute,一般都得补一个relative(子绝父相)
  • 如果写了absolute或fixed,一定要补top和left
  • sticky兼容性很差,主要用于面试。

position: relative

使用场景

  • 用于位偏移(很少用)
  • 用于给absolute元素做父类

配合z-index

  • z-index: auto 默认值,不创建新层叠上下文
  • z-index: 0/1/2 (创建层叠上下文)
  • z-index: -1 / -2 (创建层叠上下文)

总结

  • 写z-index: 9999的都是彩笔
  • 学会管理z-index

position: absolute

使用场景

  • 脱离原来的位置,另起一层,比如对话框的关闭按钮
  • 鼠标提示

配合z-index

总结

  • absolute是相对于祖先元素中最近的一个定位元素定位的,不是相对于relative
  • 某浏览器上如果不写top/left 会位置错乱
  • 善用 left: 100%
  • 善用 left: 50%; 加负margin

white-space: nowrap;文字内容不准换行

浏览器--开发者工具--Styles--:hov--Force element state中选择:hover等元素就可以将其显示出来

position:fixed(现对于viewpost定位的)

使用场景

  • 广告
  • 回到顶部按钮

配合z-index

总结

  • 手机上尽量不要使用这个属性
  • CSS新增的一些属性会影响到这个

层叠上下文

background > border > 块级子元素 > 浮动元素 > 内联元素 > 定位元素(z-index=0/=1/=2)(-1/-2/-3)

z-index: 10 和 z-index:5

  • 每个层叠上下文就是一个新的小世界(作用域)
  • 这小世界里面的z-index跟外界无关
  • 处在同一个小世界的z-index才能比较

那些不正交的属性可以创建它

  • MDN文档有些
  • 需要记忆的有z-index、flex、opacity、transform
  • 忘了就搜【层叠上下文MDN】

动画

定义

  • 许多静止的画面(帧)
  • 以一定速度(如每秒30张)连续播放时
  • 肉眼因视觉残像产生错觉
  • 而误以为时活动的画面

概念

  • 帧:每个静止的画面都叫做帧
  • 播放速度:每秒24帧(影视)或者最低每秒30帧--120帧(游戏)

一个简单的例子

将div从左往右移动

原理

  • 每过一段时间(用setInterval做到)
  • 将div移动一小段距离
  • 直到移动到目标地点

注意性能

  • 绿色表示重新绘制(repaint)了
  • CSS渲染过程依次包含布局、绘制、合成
  • 其中布局和绘制有可能被省略
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
    <style>
        #demo {
            width: 100px;
            height: 100px;
            border: 1px solid red;
            position: relative;
            left: 0;
        }
    </style>
</head>
<body>
    <div id="demo"></div>
    <script>
        var n = 1
        var id = setInterval(()=>{
            if(n<=200){
                demo.style.left = n + 'px'
                n = n + 1
            }else{
                console.log('1')
                clearInterval(id)
            }
        },1000/60)
    </script>
</body>
</html>

用transform(变形)

原理

  • transform: translateX(0 => 300px)
  • 直接修改会被合成,需要等一会修改
  • transition 过度属性可以自动脑补中间帧

注意性能

  • 并没有repaint(重新绘制)
  • 比改left性能好

浏览器渲染过程

步骤

  1. 根据HTML构建的HTML树(DOM)
  2. 根据CSS构建CSS树(CSSDOM)
  3. 将两棵树合并成一颗渲染树(render tree)
  4. Layout 布局(文档流、盒模型、计算大小和位置)
  5. Paint 绘制(把边框颜色、文字颜色、阴影等画出来)
  6. Compose合成(根据层叠关系展示画面)

如何更新样式

一般我们用JS来更新样式

  • 比如 div.style.background = 'red'
  • 比如 div.style.display = 'none'
  • 比如 div.style.classList.add('red')
  • 比如 div.remove() 直接删除节点

那么这些方式有什么不同?

有三种不同的渲染方式

  1. JS/CSS > 样式 > 布局 > 绘制 > 合成
  2. JS/CSS > 样式 > 绘制 > 合成
  3. JS/CSS > 样式 > 合成

三种更新方式

  1. 第一种,全走
    • div.remove() 会触发当前消失,其他元素relayout
  2. 第二种,跳过layout
    • 改变背景颜色,直接跳过repaint + composite
  3. 第三种,跳过layout和paint
    • 改变 transform,只需composite
    • 注意必须全屏查看效果,在iframe里面有问题

(每个属性触发什么流程)[https://csstriggers.com/]

CSS动画优化

(答案都在google写的文章里面)[https://developers.google.com/web/fundamentals/performance/rendering/stick-to-compositor-only-properties-and-manage-layer-count]

JS优化

  • 使用requestAnimationFrame 代替 setTimeout 或 setInterval

CSS优化

  • 使用will-change 或 translate

transform 完整介绍

transform 四个常用功能

  1. 位移 translate
  2. 缩放 scale
  3. 旋转 rotate
  4. 倾斜 skew

总结

  • 一般都需要配合transition 过渡
  • inline 元素 不支持 transform, 需要先变成block

transform 之 translate

常用写法

  • translateX()
  • translateY()
  • translate(,?)
  • translateZ() 且父容器 perspective
  • translate3d(x,y,z)

总结

  • 要学会看懂MDN的语法示例
  • translate(-50%,-50%) 可做绝对定位元素的居中
#demo {
  width: 100px;
  height: 100px;
  border: 1px solid red;
  position: absolute;
  left: 50%;
  top: 50%;
  transform: translate(-50%,-50%); /*居中*/
}

.wrapper{
  border: 1px solid black;
  position: relative;
  height: 500px;
}

transform 之 scale

常用写法

  1. scaleX()
  2. scaleY()
  3. scale((),()?)

总结:用的较少,因为容易出现模糊

transform 之 rotate

常用写法

  1. rotate([angle]|)
  2. rotateZ([angle]|)
  3. rotateX([angle]|)
  4. rotateY([angle]|)
  5. rotate3d

总结

  • 一般用于360度旋转制作loading
  • 用到时在搜索rotate MDN文档

transform 之 skew

常用写法

  1. skewX([angle]|)
  2. skewY([angle]|)
  3. skew([angle]|,[angle]|)

总结:用的很少。用到时再搜 skew MDN文档

transform多重效果

组合使用

  • transform: scale(0.5) translate(-100%,-100%);
  • transform: none; 取消所有

CSS需要有想象力,而不是逻辑

CSS给出的属性都很简单,但是可以组合的很复杂

跳动的心

<!DOCTYPE html>
<html>
<head>
  <meta charset="utf-8">
  <title>JS Bin</title>
</head>
<body>
  <div id="heart">
    <div class="left"></div>
    <div class="right"></div>
    <div class="bottom"></div>
  </div>
</body>
</html>
*{margin:0;padding:0;box-sizing: border-box;}

#heart{
  margin: 100px;
  position: relative;
  display: inline-block;
  transition: all 2;
}

#heart:hover{
  transform: scale(1.5);
}

#heart > .left{
  width: 50px;
  height: 50px;
  /* border-radius: 50%; */
  border-radius: 50% 0 0 50%;
  position: absolute;
  bottom: 100%;
  right: 100%;
  transform: rotate(45deg) translateX(35px);
  background: red;
}

#heart > .right{
  width: 50px;
  height: 50px;
  /* border-radius: 50%; */
  border-radius: 50% 50% 0 0;
  position: absolute;
  bottom: 100%;
  left: 100%;
  transform: rotate(45deg) translateY(35px);
  background: red;
}

#heart > .bottom{
  width: 50px;
  height: 50px;
  transform: rotate(45deg);
  background: red;
}

tansition 过渡

作用

  • 补充中间帧

语法

  • transition: 属性名 时长 过渡方式 延迟
  • transition: left 200ms linear
  • 可以用逗号分隔两个不同属性
  • transition: left 200ms,top 400ms
  • 可以用 all 代表所有属性
  • transition: all 200ms
  • 过渡方式有:linear | ease | ease-in | ease-out | ease-in-out | cubic-bezier | step-start | step-end | steps,具体含义要靠数学知识

注意

并不是所有属性都能过渡

  • display: none => block 没法过渡

  • 一般改成visibility:hidden => visible

  • display 和 visibility 的区别

    • display:none,该元素不占据任何空间,在文档渲染时,该元素如同不存在(但依然存在文档对象模型树中)。
      visibility:hidden,该元素空间依旧存在。
      即一个(display:none)不会在渲染树中出现,一个(visibility :hidden)会。

      1. 是否渲染

      display:none,会触发reflow(回流),进行渲染。
      visibility:hidden,只会触发repaint(重绘),因为没有发现位置变化,不进行渲染。

      1. 是否是继承属性

      display:none,display不是继承属性,元素及其子元素都会消失。
      visibility:hidden,visibility是继承属性,若子元素使用了visibility:visible,则不继承,这个子孙元素又会显现出来。

      1. 读屏器是否读取

      读屏器不会读取display:none的元素内容,而会读取visibility:hidden的元素内容。

  • background压缩可以过渡

  • opacity透明度可以过渡

过渡必须要有起始,一般只有一次动画或者两次,比如hover和非hover 的状态过渡

如果过渡还有中间点可以使用以下两种方法:

使用两次transform

  • .a === transform ===> .b
  • .b === transform ===> .c
  • 如何知道到了中间点呢,使用setTimeout或者监听 transitionend 事件

使用animation

让动画停在最后一帧:加个 forwards

@keyframes完整语法

@keyframes xxx{
  0%{
    transform: none;
  }
  66%{
    transform: translateX(200px);
  }
  100%{
     transform: translateX(200px) 
       translateY(100px);
  }
}
  • 一种是from to
  • 一种是百分数

animation

缩写语法

  • animation: 时长 | 过渡方式 | 延迟 | 次数 | 方向 | 填充模式 | 是否暂停 | 动画名;
  • 时长:1s 或者 1000ms
  • 过渡方式:跟transition取值一样,如linear
  • 次数:3或者2.4或者infinite
  • 方向:reverse | alternate | alternate-reverse
  • 填充模式:none | forwards | backwards | both
  • 是否暂停: paused | running
  • 以上属性都有对应单独属性

animation语法重写跳动的心

<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <title>Document</title>
</head>
<body>
  <div id="heart">
    <div class="left"></div>
    <div class="right"></div>
    <div class="bottom"></div>
  </div>
</body>
</html>
*{margin:0;padding:0;box-sizing: border-box;}

#heart{
  margin: 100px;
  position: relative;
  display: inline-block;
  animation: heart 600ms infinite alternate;  
}

@keyframes heart{
  0% {
    transform: scale(1.0);
  }
  100% {
    transform: scale(1.5);
  }
}

#heart > .left{
  width: 50px;
  height: 50px;
  /* border-radius: 50%; */
  border-radius: 50% 0 0 50%;
  position: absolute;
  bottom: 100%;
  right: 100%;
  transform: rotate(45deg) translateX(35px);
  background: red;
}

#heart > .right{
  width: 50px;
  height: 50px;
  /* border-radius: 50%; */
  border-radius: 50% 50% 0 0;
  position: absolute;
  bottom: 100%;
  left: 100%;
  transform: rotate(45deg) translateY(35px);
  background: red;
}

#heart > .bottom{
  width: 50px;
  height: 50px;
  transform: rotate(45deg);
  background: red;
}