CSS入门
先来看一组快问快答:
CSS是什么?
Cascading Style Sheets,即层叠样式表。功能如其名,既能给HTML文档添加样式,又带有可层叠的特性。
层叠指什么?
样式层叠、选择器层叠、文件层叠等,这些特性使得CSS书写非常灵活
CSS是谁发明的?
万维网的Lee爵士的挪威同事Lie先生首先提出的CSS
哪个CSS版本最主流或流行?
CSS 1和CSS 2是比较老的版本不提,CSS 2.1是目前使用最广泛兼容性最好的版本,CSS 3开始分模块进行升级,还在逐步扩展浏览器的兼容性。
CSS的版本详情
| CSS版本 | 时间 | 重要性 |
|---|---|---|
| CSS 1 | 1996年 | 过时 |
| CSS 2 | 1998年 | 过时 |
| CSS 2.1 | 2004~2011年 | 使用最广泛的版本(IE支持) |
| CSS 3 | 1999年开始起草 | 现代版本,分模块升级(IE 8部分支持) |
| CSS 4 ? | 未来版本 | 分模块升级 |
查看浏览器的CSS特性支持性
各个浏览器兼容性非常繁琐复杂,建议使用caniuse.com网站,全网数据一网打尽
CSS的语法
掌握两大类即可
样式语法
选择器 {
属性名: 属性值;
}
注意区分大小写!!
@语法
@charset "UTF-8";
@import url(.css);
@media (min-width: 100px) and (max-width: 150px)
注意事项
- charset字符编码设置必须在第一行
- 没有{}就必须以;结尾
- media媒体查询是非常关键的功能,做自适应或自响应页面
CSS的调试方法
跟JS中的经典log调试法类似,CSS也有其灵魂调试法,border调试法
遇事不决,给元素添加border
注意border有时候会影响尺寸,导致父元素容纳子元素的空间出现问题。
Tips: 这时候可用outline法代替border,outline不占用文档空间
CSS重要概念
Normal Flow
国内翻译文档流,其实直译应该是正常流或常规流,就是HTML文档的一个正常排布流动的方向。
页面的左上角作为起点,横向排布流是从左到右,纵向排布流是自上而下。
block, inline, inline-block元素
- block元素自上而下,每一个另起一行
- inline元素从左到右,到达一行末端会换行
- inline-box元素也从左到右
盒模型
CSS 盒模型有两种,一种是默认的content-box模型,一种是border-box模型。两者的主要区别就在,context-box你规定的元素宽度只有content宽度,不包括padding,border。而border-box模型下,你定义的元素宽度会包括content,padding,border的总和。如果定义了padding,border宽度,content宽度会自动减法计算得到。
border-box模型非常符合人类思维,普适于平时工作场景,推荐优先使用。
脱离Normal Flow
对元素使用以下CSS样式:
- float
- position: absolute / fixed 等
CSS大坑
说了CSS那么多特性和优点,实际工作中会发现CSS也有缺点,有很多奇葩的大坑。
最经典的,margin合并问题
在较新的主流内核的浏览器上,如chrome和firefox,CSS会出现block元素的垂直方向margin合并,也称为margin塌缩现象。父与首尾两个子元素或者相邻同级子元素在垂直方向的margin如果同时存在,他们两个的margi会取其中最大的值。
而在比较老的浏览器比如ie8上,这个margin合并功能就不会实现。这就会出现,所谓的双倍margin问题。因为我们通常CSS编程,是根据目前最通用的chrome内核浏览器编写的;而在ie内核下,将相邻子元素赋予垂直方向margin会导致不自动合并而是呈现双倍效果。虽然有办法解决,但这是CSS一个令人头疼的典型问题。
CSS3的重要新功能——动画
CSS3提供了很强的动画功能,主要分为两种方法,transition以及animation。通过这两种动画功能,进行包装和配合,就能实现一些很酷眩的动画效果,摆脱以往需要复杂Js脚本实现的繁琐操作。在继续探讨这两种动画功能之前,需要先稍微了解一些前置的知识点,如浏览器是如何渲染html页面的。
浏览器渲染原理
关于浏览器的渲染原理,其实各家浏览器会有各自的做法和微妙的区别。由于最主流的浏览器都是在用chrome内核,所以我们优先探讨一下chrome浏览器的渲染机制。关于chrome渲染,最权威的说明还是谷歌官方提供的文档。文档很长,很专业,涉及专业术语很多难啃,就在这里简单总结一下。
浏览器渲染大概步骤
- 根据HTML构建HTML树,也就是DOM树
- 根据CSS构建CSS树(CSSOM)
- 将两颗树合并成一颗渲染树(render tree)
- Layout布局(包括文档流,盒模型,计算大小和位置)
- Paint绘制(把边框颜色、文字颜色、阴影等绘出)
- Compose合成(根据层叠关系展示画面)
如何更新样式
通常使用JS脚本来更新样式
- 比如改背景
div.style.background = 'color' - 比如改元素显示/隐藏
div.style.display = 'none' - 更改元素的样式更常用改类名的方法
div.classList.add('blue') - 移除节点
div.remove()
这些不同的脚本和方法,会产生不同的页面样式更新方式,这跟浏览器的种类版本也有关系。涉及浏览器的渲染过程。
三种更新方式
- JS -> style -> layout -> paint -> composite
- JS -> style -> paint -> composite
- JS -> style -> composite
第一种方式是全走一遍,比如div.remote会让元素消失,其他元素发生重新布局relayout。
第二种方式会跳过layout步骤,因为不涉及元素的重排,比如改元素背景色。
第三种方式会跳过layout和paint步骤,直接进行composite步骤。比如,非常重要的改变元素外观效果的一个功能,transform。
优化CSS的动画效果,就需要研究浏览器渲染过程,就需要优化不同属性下触发的流程,触发的CSS更新流程越简单,响应越快,用户体验越好。
注意不同的属性会触发不同的渲染过程,这就需要使用不同浏览器调试功能来试验。
好在有CSS Triggers这个网站,已经总结了绝大多数常用的CSS属性触发,在不同浏览器上的表现。
transform方法简介
四个常用功能:
- 位移 translate
- 缩放 scale
- 旋转 rotate
- 倾斜 skew
使用transform变换页面元素的外观,一般都需要配合transition来过渡。
特别需要注意一点,inline元素不支持transform,需要先display: block;
这些方法的具体语句写法,在MDN里都有详细的描述,最快掌握语句的方法就是去查看MDN的语法示例。
例子:translate(-50%, -50%)经常用于绝对定位元素的居中
注意scale 语句用的很少,因为很可能会导致元素模糊的现象发生,视觉效果灾难性的,用户体验极差。
transition方法简介
他的作用,本质上来说就是自动补全动画中间帧。
语法其实很简单:
transition:属性名 时长 过渡方式 延迟;
以及一些小技巧:
- 可以用逗号分隔两个不同属性名
- 可以用all来代表所有属性
- 过渡方式是用函数表示,具体有很多数学知识不方便展开。常用的ease,linear,steps掌握后自行摸索吧
以及还要注意几点:
- 不是所有属性都有动画效果过渡,比如display: none到block无过渡
- transition过渡必须有始有终,可以执行一次动画或正反向各执行一次
最经典的用法是hover和非hover状态的过渡
animation方法简介
除了两个节点有始有终以外,如果你还想实现更复杂的动画效果,就不能只用简单的transition过渡了。如果硬要用transition方法去实现多个中间转折点,那就需要借助JS语句来配合实现。这一过程会非常繁琐。
想做复杂动画效果,添加更多的中间帧,关键帧,最好用到animation方法。
animation方法的使用也非常简单,两个步骤:
- 声明关键帧
- 添加动画
animation缩写语法:
animation:时长 | 过渡方式 | 延迟 | 次数 | 方向 | 填充模式 | 是否暂停 | 动画名称;
- 次数可以是具体数值,或者infinite
- 方向有 reverse / alternate / alternate-reverse
- 填充模式 none / forwards / backwards / both
- 是否暂停属性来控制播放状态 paused / running
申请关键帧 @keyframes
@keyframes name {
from {
}
to {
}
}
或者
@keyframes name {
0, 100% {
}
50% {
}
}
个人体会,animation的使用相对于transition会复杂一些,代码维护工作会更繁琐一些,如果能使用transition实现的基础动画效果,那就尽量用transition实现。