CSS核心概念和知识点
语法
css的核心功能是能够将css属性设定一个特定的值,一个属性与值的键值对被称为声明
color:red;
而如果是用{}
来声明多个的话,就形成了一个声明块
{
font-size:20px;
color:red;
}
声明块如果需要用到对应的HTML元素,必须加上选择器,选择器和声明块组成了CSS 规则集,简称为 CSS 规则
效果:
其实规则中的最后一条声明可以省略分号,但是并不建议这么做,因为这样很容易出粗
css注释
/* 单行注释 */
/*
多行注释
*/
使用注释后,所有被注释的东西都将不被浏览器识别
@规则
css规则是样式表主体,通常会包括大量规则,有时候也需要在样式表中包括其他一些信息(如字符集,导入其它的外部样式表,字体等)这些需要特定语句来完成
而@规则就是这样的语句
css中包含了如下@规则
-
@namespace告诉css引擎必须考虑XML命名空间
- https://developer.mozilla.org/zh-CN/docs/Web/CSS/@namespace
-
@media满足媒体查询的条件则条件规则里面的规则生效
- https://developer.mozilla.org/zh-CN/docs/Web/CSS/@media
-
@page描述了打印文档时布局的变化
- https://developer.mozilla.org/zh-CN/docs/Web/CSS/@page
-
@font-face描述将下载哪些外部字体
- https://developer.mozilla.org/zh-CN/docs/Web/CSS/@font-face
-
@keyframes描述css动画的关键帧
- https://developer.mozilla.org/zh-CN/docs/Web/CSS/@keyframes
-
@document如果文档样式表满足给定条件则条件规则组里的规则生效
- https://developer.mozilla.org/zh-CN/docs/Web/CSS/@document
-
@charset(https://developer.mozilla.org/zh-CN/docs/Web/CSS/@charset)
用于定义样式表使用的字符集。它必须是样式表中的第一个元素。如果有多个
@charset
被声明,只有第一个会被使用,而且不能在HTML元素或HTML页面的<style>
元素内使用
@charset "UTF-8";
现在我们是在html的head头里面来写
<meta charset="UTF-8">
- @import(https://developer.mozilla.org/zh-CN/docs/Web/CSS/@import)
用于告诉css引擎引入外部样式表
link 和 @import 都能导入一个样式文件
- link 是 HTML 标签,除了能导入 CSS 外,还能导入别的资源,比如图片、脚本和字体等;而 @import 是 CSS 的语法,只能用来导入 CSS
- link 导入的样式会在页面加载时同时加载,@import 导入的样式需等页面加载完成后再加载
- link 没有兼容性问题,@import 不兼容 ie5 以下
- link 可以通过 JS 操作 DOM 动态引入样式表改变样式,而@import不可以
层叠性
层叠样式表是 CSS 中的核心特性之一,用于合并来自多个源的属性值的算法
针对不同源的样式,将按照如下的顺序进行层叠,越往下优先级越高
-
用户代理样式表中的声明(如浏览器的默认样式,在没有设置其他样式时使用)
-
用户样式表中的常规声明(由用户设置的自定义样式)
-
作者样式表中的常规声明(这些是我们 Web 开发人员设置的样式)
-
作者样式表中的 !important 声明
-
用户样式表中的 !important 声明
理解层叠性的时候需要结合 CSS 选择器的优先级以及继承性来理解
针对同一个选择器,定义在后面的声明会覆盖前面的
作者定义的样式会比默认继承的样式优先级更高
选择器
基础选择器
- 标签选择器:
h1
- 类选择器:
.checked
- ID 选择器:
#picker
- 通配选择器:
*
属性选择器
[attr]
:指定属性的元素;[attr=val]
:属性等于指定值的元素;[attr*=val]
:属性包含指定值的元素;[attr^=val]
:属性以指定值开头的元素;[attr$=val]
:属性以指定值结尾的元素;[attr~=val]
:属性包含指定值(完整单词)的元素(不推荐使用);[attr|=val]
:属性以指定值(完整单词)开头的元素(不推荐使用);
组合选择器
- 相邻兄弟选择器:
A + B
- 普通兄弟选择器:
A ~ B
- 子选择器:
A > B
- 后代选择器:
A B
伪类
条件伪类
:lang()
:基于元素语言来匹配页面元素;:dir()
:匹配特定文字书写方向的元素;:has()
:匹配包含指定元素的元素;:is()
:匹配指定选择器列表里的元素;:not()
:用来匹配不符合一组选择器的元素;
行为伪类
:active
:鼠标激活的元素;:hover
: 鼠标悬浮的元素;::selection
:鼠标选中的元素;
状态伪类
:target
:当前锚点的元素;:link
:未访问的链接元素;:visited
:已访问的链接元素;:focus
:输入聚焦的表单元素;:required
:输入必填的表单元素;:valid
:输入合法的表单元素;:invalid
:输入非法的表单元素;:in-range
:输入范围以内的表单元素;:out-of-range
:输入范围以外的表单元素;:checked
:选项选中的表单元素;:optional
:选项可选的表单元素;:enabled
:事件启用的表单元素;:disabled
:事件禁用的表单元素;:read-only
:只读的表单元素;:read-write
:可读可写的表单元素;:blank
:输入为空的表单元素;:current()
:浏览中的元素;:past()
:已浏览的元素;:future()
:未浏览的元素;
结构伪类
:root
:文档的根元素;:empty
:无子元素的元素;:first-letter
:元素的首字母;:first-line
:元素的首行;:nth-child(n)
:元素中指定顺序索引的元素;:nth-last-child(n)
:元素中指定逆序索引的元素;;:first-child
:元素中为首的元素;:last-child
:元素中为尾的元素;:only-child
:父元素仅有该元素的元素;:nth-of-type(n)
:标签中指定顺序索引的标签;:nth-last-of-type(n)
:标签中指定逆序索引的标签;:first-of-type
:标签中为首的标签;:last-of-type
:标签中为尾标签;:only-of-type
:父元素仅有该标签的标签;
伪元素
::before
:在元素前插入内容;::after
:在元素后插入内容;
优先级
优先级就是分配给指定的 CSS 声明的一个权重,它由匹配的选择器中的各自数值决定为了记忆,数值越大的权重越高
- 10000:!important
- 01000:内联样式
- 00100:ID 选择器;
- 00010:类选择器、伪类选择器、属性选择器
- 00001:元素选择器、伪元素选择器
- 00000:通配选择器、后代选择器、兄弟选择器
!important
可以把优先级提至最高,所以需要谨慎使用它
- 一定要优先考虑使用样式规则的优先级来解决问题而不是 !important
- 只有在需要覆盖全站或外部 CSS 的特定页面中使用 !important
- 永远不要在你的插件中使用 !important
- 永远不要在全站范围的 CSS 代码中使用 !important
继承性
CSS 中有一个很重要的特性就是子元素会继承父元素对应属性计算后的值
如果css中不存在继承的话,那我们的工作量就变大了,我们需要为每个文本都设置相对应的颜色,不光工作量变大,效率也变小了
- 字体相关:
font-family
、font-style
、font-size
、font-weight
等; - 文本相关:
text-align
、text-indent
、text-decoration
、text-shadow
、letter-spacing
、word-spacing
、white-space
、line-height
、color
等; - 列表相关:
list-style
、list-style-image
、list-style-type
、list-style-position
等; - 其他属性:
visibility
、cursor
等
对于其他默认不继承的属性也可以通过以下几个属性值来控制继承行为:
inherit
:继承父元素对应属性的计算值initial
:应用该属性的默认值,比如 color 的默认值是#000
unset
:如果属性是默认可以继承的,则取inherit
的效果,否则同initial
revert
:效果等同于unset
,兼容性差
文档流
特性如下
- 块级元素默认会占满整行,所以多个块级盒子之间是从上到下排列的
- 内联元素默认会在一行里一列一列的排布,当一行放不下的时候,会自动切换到下一行继续按照列排布
如何去脱离文档流
使用浮动或者定位来脱离
- 使用浮动(float)会将元素脱离文档流,移动到容器左/右侧边界或者是另一个浮动元素旁边,该浮动元素之前占用的空间将被别的元素填补,另外浮动之后所占用的区域不会和别的元素之间发生重叠
- 使用绝对定位(
position: absolute;
)或者固定定位(position: fixed;
)也会使得元素脱离文档流,且空出来的位置将自动被后续节点填补
盒模型
在 CSS 中任何元素都可以看成是一个盒子,而一个盒子是由 4 部分组成的:内容(content)、内边距(padding)、边框(border)和外边距(margin)
盒模型有 2 种:标准盒模型和 IE 盒模型,分别是由 W3C 和 IExplore 制定的标准
高版本的浏览器基本上默认都是使用标准盒模型
- 标准盒模型认为:盒子的实际尺寸 = 内容(设置的宽/高) + 内边距 + 边框
- IE 盒模型认为:盒子的实际尺寸 = 设置的宽/高 = 内容 + 内边距 + 边框
所以在 CSS3 中新增了一个属性 box-sizing
,允许开发者来指定盒子使用什么标准
content-box
:标准盒模型border-box
:IE 盒模型
盒子类型由 display 决定,同时给一个元素设置 display 后,将会决定这个盒子的 2 个显示类型(display type)
outer display type
- outer display type(对外显示):决定了该元素本身是如何布局的,即参与何种格式化上下文;
对外显示方面,盒子类型可以分成 2 类:block-level box(块级盒子) 和 inline-level box(行内级盒子)。
依据上图可以列出都有哪些块级和行内级盒子:
- 块级盒子:display 为 block、list-item、table、flex、grid、flow-root 等;
- 行内级盒子:display 为 inline、inline-block、inline-table 等;
所有块级盒子都会参与 BFC,呈现垂直排列;而所有行内级盒子都参会 IFC,呈现水平排列
-
block
- 占满一行,默认继承父元素的宽度;多个块元素将从上到下进行排列
- 设置 width/height 将会生效
- 设置 padding 和 margin 将会生效
-
inline
- 不会占满一行,宽度随着内容而变化;多个 inline 元素将按照从左到右的顺序在一行里排列显示,如果一行显示不下,则自动换行
- 设置 width/height 将不会生效
- 设置竖直方向上的 padding 和 margin 将不会生效
-
inline-block
- 是行内块元素,不单独占满一行,可以看成是能够在一行里进行左右排列的块元素
- 设置 width/height 将会生效
- 设置 padding 和 margin 将会生效
inner display type
- inner display type(对内显示):其实就相当于把该元素当成了容器,规定了其内部子元素是如何布局的,参与何种格式化上下文
对内方面,其实就是把元素当成了容器,里面包裹着文本或者其他子元素
container box 的类型依据 display 的值不同,分为 4 种
- block container:建立 BFC 或者 IFC;
- flex container:建立 FFC;
- grid container:建立 GFC;
- ruby container
格式化上下文
不同类型的盒子有不同格式化上下文
- BFC (Block Formatting Context) 块级格式化上下文;
- IFC (Inline Formatting Context) 行内格式化上下文;
- FFC (Flex Formatting Context) 弹性格式化上下文;
- GFC (Grid Formatting Context) 格栅格式化上下文;
BFC和IFC是非常重要的,他们可以直接影响网页的布局
BFC
-
渲染规则
- 内部的盒子会在垂直方向,一个接一个地放置
- 盒子垂直方向的距离由 margin 决定,属于同一个 BFC 的两个相邻盒子的 margin 会发生重叠
- 每个元素的 margin 的左边,与包含块 border 的左边相接触(对于从左往右的格式化,否则相反),即使存在浮动也是如此
- BFC 的区域不会与 float 盒子重叠
- BFC 就是页面上的一个隔离的独立容器,容器里面的子元素不会影响到外面的元素。反之也如此
- 计算 BFC 的高度时,浮动元素也参与计算
-
创建 BFC
- 根元素:html
- 非溢出的可见元素:overflow 不为 visible
- 设置浮动:float 属性不为 none
- 设置定位:position 为 absolute 或 fixed
- 定义成块级的非块级元素
-
应用场景
- 自适应两栏布局
- 清除内部浮动
IFC
- 渲染规则
- 子元素在水平方向上一个接一个排列,在垂直方向上将以容器顶部开始向下排列
- 节点无法声明宽高,其中 margin 和 padding 在水平方向有效在垂直方向无效
- 节点在垂直方向上以不同形式对齐
- 能把在一行上的框都完全包含进去的一个矩形区域,被称为该行的线盒(line box)。线盒的宽度是由包含块(containing box)和与其中的浮动来决定
- IFC 中的 line box 一般左右边贴紧其包含块,但 float 元素会优先排列
- IFC 中的 line box 高度由 line-height 计算规则来确定,同个 IFC 下的多个 line box 高度可能会不同
- 当内联级盒子的总宽度少于包含它们的 line box 时,其水平渲染规则由 text-align 属性值来决定
- 当一个内联盒子超过父元素的宽度时,它会被分割成多盒子,这些盒子分布在多个 line box 中。如果子元素未设置强制换行的情况下,inline box 将不可被分割,将会溢出父元素
- 应用场景
- 水平居中:当一个块要在环境中水平居中时,设置其为 inline-block 则会在外层产生 IFC,通过 text-align 则可以使其水平居中
- 垂直居中:创建一个 IFC,用其中一个元素撑开父元素的高度,然后设置其 vertical-align: middle,其他行内元素则可以在此父元素下垂直居中