一、CSS基础
层叠样式表(英文全称:Cascading Style Sheets)是一种用来表现HTML(标准通用标记语言的一个应用)或XML(标准通用标记语言的一个子集)等文件样式的计算机语言。CSS不仅可以静态地修饰网页,还可以配合各种脚本语言动态地对网页各元素进行格式化。
CSS 能够对网页中元素位置的排版进行像素级精确控制,支持几乎所有的字体字号样式,拥有对网页对象和模型样式编辑的能力
二、核心概念以及知识点
2.1 css语法
CSS 的核心功能是将 CSS 属性设定为特定的值。一个属性与值的键值对被称为声明(declaration)
background-color: #eee;
而如果将一个或者多个声明用 {}
包裹起来后,那就组成了一个声明块(declaration block)
{
height:200px;
background-color: #eee;
border: 1px solid black;
}
声明块如果需要作用到对应的 HTML 元素,那还需要加上选择器。选择器和声明块组成了CSS 规则集(CSS ruleset),常简称为 CSS 规则。
.box {
//属性:值
height:200px;
background-color: #eee;
border: 1px solid black;
}
2.2 CSS注释
// 单行注释
/*
多行
注释
*/
在 CSS 文件中,除了注释、CSS 规则集以及 @规则 外,定义的一些别的东西都会被浏览器忽略
2.3 @规则
CSS 规则是样式表的主体,通常样式表会包括大量的规则列表。但有时候也需要在样式表中包括其他的一些信息,比如字符集,导入其它的外部样式表,字体等,这些需要专门的语句表示。
CSS 里包含了以下 @规则:
- @namespace 告诉 CSS 引擎必须考虑XML命名空间。
- @media, 如果满足媒体查询的条件则条件规则组里的规则生效。
- @page, 描述打印文档时布局的变化.
- @font-face, 描述将下载的外部的字体。
- @keyframes, 描述 CSS 动画的关键帧。
- @document, 如果文档样式表满足给定条件则条件规则组里的规则生效。
2.3.1 不常用的@规则
2.3.1.1 @charset
- @charset 用于定义样式表使用的字符集。
- 它必须是样式表中的第一个元素。
- 如果有多个
@charset
被声明,只有第一个会被使用 - 不能在HTML元素或HTML页面的
<style>
元素内使用
例如
@charset "UTF-8"; //必须是双引号包裹
2.3.1.2 @import
@import 用于告诉 CSS 引擎引入一个外部样式表。
link和@import的区别:
- link 是 HTML 标签,除了能导入 CSS 外,还能导入别的资源,比如图片、脚本和字体等;而 @import 是 CSS 的语法,只能用来导入 CSS;
- link 导入的样式会在页面加载时同时加载,@import 导入的样式需等页面加载完成后再加载;
- link 没有兼容性问题,@import 不兼容 ie5 以下;
- link 可以通过 JS 操作 DOM 动态引入样式表改变样式,而@import不可以。
2.4 CSS 选择器
2.4.1 基础选择器
标签选择器 类选择器 ID选择器 通配符选择器
2.4.2 属性选择器
[attr]
:指定属性的元素;
[attr=val]
:属性等于指定值的元素;
[attr*=val]
:属性包含指定值的元素; // *匹配0或多
[attr^=val]
:属性以指定值开头的元素; // ^匹配开头
[attr$=val]
:属性以指定值结尾的元素; // $匹配结尾
2.4.3 组合选择器
- 相邻兄弟选择器:
A + B
- 普通兄弟选择器:
A ~ B
- 子选择器:
A > B
- 后代选择器:
A B
2.5 伪类
2.5.1 条件伪类
:lang()
:基于元素语言来匹配页面元素;:dir()
:匹配特定文字书写方向的元素;:has()
:匹配包含指定元素的元素;:is()
:匹配指定选择器列表里的元素;:not()
:用来匹配不符合一组选择器的元素;
2.5.2 行为伪类
:active
:鼠标激活的元素;:hover
: 鼠标悬浮的元素;::selection
:鼠标选中的元素;
2.5.3 状态伪类
:target
:当前锚点的元素;:link
:未访问的链接元素;:visited
:已访问的链接元素;:focus
:输入聚焦的表单元素;:required
:输入必填的表单元素;:valid
:输入合法的表单元素;:invalid
:输入非法的表单元素;:in-range
:输入范围以内的表单元素;:out-of-range
:输入范围以外的表单元素;:checked
:选项选中的表单元素;:optional
:选项可选的表单元素;:enabled
:事件启用的表单元素;:disabled
:事件禁用的表单元素;:read-only
:只读的表单元素;:read-write
:可读可写的表单元素;:blank
:输入为空的表单元素;:current()
:浏览中的元素;:past()
:已浏览的元素;:future()
:未浏览的元素;
2.5.4 结构伪类
: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
:父元素仅有该标签的标签;
2.5.5 伪元素
::before
:在元素前插入内容;::after
:在元素后插入内容;
.box {
height: 200px;
position: relative;
background-color: #eee;
}
.box::after {
content: "";
top: 200px;
position: absolute;
width: 100%;
height: 1px;
background-color: blue;
}
2.6 优先级
!important ∞无穷大
内联样式 1000
id选择器优先级 100
类选择器 伪类选择器 属性选择器优先级 10
标签选择器 伪元素选择器优先级 1
通配符 后代选择器 兄弟选择器优先级 0
2.7 继承性
在 CSS 中有一个很重要的特性就是子元素会继承父元素对应属性计算后的值。
比如页面根元素 html 的文本颜色默认是黑色的,页面中的所有其他元素都将继承这个颜色
.box {
color: red;
height: 200px;
background-color: #eee;
}
<div class="box">
<p>我会继承父元素的颜色</p>
</div>
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
,兼容性差。
2.8 标准文档流
在 CSS 的世界中,会把内容按照从左到右、从上到下的顺序进行排列显示。正常情况下会把页面分割成一行一行的显示,而每行又可能由多列组成,所以从视觉上看起来就是从上到下从左到右,而这就是 CSS 中的流式布局,又叫文档流。
文档流特性:
- 块级元素默认会占满整行,所以多个块级盒子之间是从上到下排列的;
- 内联元素默认会在一行里一列一列的排布,当一行放不下的时候,会自动切换到下一行继续按照列排布;
如何脱离文档流:
脱流文档流指节点脱流正常文档流后,在正常文档流中的其他节点将忽略该节点并填补其原先空间。文档一旦脱流,计算其父节点高度时不会将其高度纳入,脱流节点不占据空间。
有两种方式可以让元素脱离文档流:浮动和定位。
- 使用浮动(float)会将元素脱离文档流,移动到容器左/右侧边界或者是另一个浮动元素旁边,该浮动元素之前占用的空间将被别的元素填补,另外浮动之后所占用的区域不会和别的元素之间发生重叠;
- 使用绝对定位(
position: absolute;
)或者固定定位(position: fixed;
)也会使得元素脱离文档流,且空出来的位置将自动被后续节点填补。
2.8.1 何如清除浮动
(1)额外标签法
是w3C推荐的做法是通过在浮动元素末尾添加一个空的标签
例如
优点:通俗易懂,书写方便
缺点:添加许多无意义的标签,结构化较差。
(2)overflow:hidden
可以给父级添加:overflow为hidden/ auto/ scro11
优点:代码简洁
缺点:内容增多时候容易造成不会自动换行导致内容被隐藏掉,无法显示需要溢出的元素。
(3))使用after伪元素清除浮动
使用方法:
.clearfix:after {
content: "";
display: block;
height: 0;
clear: both;
visibility: hidden;
}
.clearfix {
*zoom: 1;
}/*IE6、7专有*/
2.9 CSS 盒模型
一个盒子是由 4 部分组成的:内容(content)、内边距(padding)、边框(border)和外边距(margin)。
盒模型有 2 种:标准盒模型和 IE 盒模型,本别是由 W3C 和 IExplore 制定的标准。
我们给盒子设置如下样式:
.box {
width: 800px;
height: 200px;
border: 1px solid blue;
padding: 20px;
margin: 20px;
background-color: #eee;
}
2.9.1 标准盒模型
盒子的实际尺寸 = 内容(设置的宽/高) + 内边距 + 边框
.box元素的宽度为800px 而实际宽度为 内容+左右padding+左右border = 842px
2.9.2 IE盒模型
盒子的实际尺寸 = 设置的宽/高 = 内容 + 内边距 + 边框
.box元素宽度为800px 实际宽度= 内容-左右padding-左右border = 758px
高版本的浏览器基本上默认都是使用标准盒模型,而像 IE6 这种老古董才是默认使用 IE 盒模型的。
在 CSS3 中新增了一个属性 box-sizing
,允许开发者来指定盒子使用什么标准,它有 2 个值:
content-box
:标准盒模型;border-box
:IE 盒模型;
2.10 视觉格式化模型
视觉格式化模型(Visual formatting model)是用来处理和在视觉媒体上显示文档时使用的计算规则。CSS 中一切皆盒子,而视觉格式化模型简单来理解就是规定这些盒子应该怎么样放置到页面中去,这个模型在计算的时候会依赖到很多的因素,比如:盒子尺寸、盒子类型、定位方案(是浮动还是定位)、兄弟元素或者子元素以及一些别的因素。
盒子类型由 display 决定,同时给一个元素设置 display 后,将会决定这个盒子的 2 个显示类型(display type):
- outer display type(对外显示):决定了该元素本身是如何布局的,即参与何种格式化上下文;
- inner display type(对内显示):其实就相当于把该元素当成了容器,规定了其内部子元素是如何布局的,参与何种格式化上下文;
2.10.1 outer display type
对外显示方面,盒子类型可以分成 2 类:block-level box(块级盒子) 和 inline-level box(行内级盒子)。
块级盒子:display为block div、p、h1-h6、ul、ol、li
行内级盒子:display为inline a、span、i、em
行内块盒子:display为inline-block img、input
所有块级盒子都会参与 BFC,呈现垂直排列;而所有行内级盒子都参会 IFC,呈现水平排列。
2.10.1 block
- 占满一行,默认继承父元素的宽度;多个块元素将从上到下进行排列;
- 设置 width/height 将会生效;
- 设置 padding 和 margin 将会生效;
2.10.2 inline
- 不会占满一行,宽度随着内容而变化;多个 inline 元素将按照从左到右的顺序在一行里排列显示,如果一行显示不下,则自动换行;
- 设置 width/height 将不会生效;
- 设置竖直方向上的 padding 和 margin 将不会生效;
1.10.3 inline-block
- 是行内块元素,不单独占满一行,可以看成是能够在一行里进行左右排列的块元素;
- 设置 width/height 将会生效;
- 设置 padding 和 margin 将会生效;
2.10.2 inner display type
对内方面,其实就是把元素当成了容器,里面包裹着文本或者其他子元素。container box 的类型依据 display 的值不同,分为 4 种:
- block container:建立 BFC 或者 IFC;
- flex container:建立 FFC;
- grid container:建立 GFC;
- ruby container:接触不多
三、值和单位
CSS 的声明是由属性和值组成的,而值的类型有许多种:
- 数值:长度值 ,用于指定例如元素 width、border-width、font-size 等属性的值;
- 百分比:可以用于指定尺寸或长度,例如取决于父容器的 width、height 或默认的 font-size;
- 颜色:用于指定 background-color、color 等;
- 坐标位置:以屏幕的左上角为坐标原点定位元素的位置,比如常见的 background-position、top、right、bottom 和 left 等属性;
- 函数:用于指定资源路径或背景图片的渐变,比如 url()、linear-gradient() 等;
3.1 px
屏幕分辨率是指在屏幕的横纵方向上的像素点数量,比如分辨率 1920×1080 意味着水平方向含有 1920 个像素数,垂直方向含有 1080 个像素数。
而 px 表示的是 CSS 中的像素,在 CSS 中它是绝对的长度单位,也是最基础的单位,其他长度单位会自动被浏览器换算成 px。但是对于设备而言,它其实又是相对的长度单位,比如宽高都为 2px,在正常的屏幕下,其实就是 4 个像素点,而在设备像素比(devicePixelRatio) 为 2 的 Retina 屏幕下,它就有 16 个像素点。所以屏幕尺寸一致的情况下,屏幕分辨率越高,显示效果就越细腻。
讲到这里,还有一些相关的概念需要理清下:
3.1.1 设备像素
(Device pixels)设备屏幕的物理像素,表示的是屏幕的横纵有多少像素点;和屏幕分辨率是差不多的意思。
设备像素比(DPR)
设备像素比表示 1 个 CSS 像素等于几个物理像素。
计算公式:DPR = 物理像素数 / 逻辑像素数;
在浏览器中可以通过 window.devicePixelRatio 来获取当前屏幕的 DPR。
像素密度(DPI/PPI)
像素密度也叫显示密度或者屏幕密度,缩写为 DPI(Dots Per Inch) 或者 PPI(Pixel Per Inch)。从技术角度说,PPI 只存在于计算机显示领域,而 DPI 只出现于打印或印刷领域。
计算公式:像素密度 = 屏幕对角线的像素尺寸 / 物理尺寸
比如,对于分辨率为 750 * 1334 的 iPhone 6 来说,它的像素密度为:
Math.sqrt(750 * 750 + 1334 * 1334) / 4.7 = 326ppi
设备独立像素(DIP)
DIP 是特别针对 Android设备而衍生出来的,原因是安卓屏幕的尺寸繁多,因此为了显示能尽量和设备无关,而提出的这个概念。它是基于屏幕密度而计算的,认为当屏幕密度是 160 的时候,px = DIP。
计算公式:dip = px * 160 / dpi
3.2 em
em 是 CSS 中的相对长度单位中的一个。居然是相对的,那它到底是相对的谁呢?它有 2 层意思:
- 在 font-size 中使用是相对于父元素的 font-size 大小,比如父元素 font-size: 16px,当给子元素指定 font-size: 2em 的时候,经过计算后它的字体大小会是 32px;
- 在其他属性中使用是相对于自身的字体大小,如 width/height/padding/margin 等;
我们都知道每个浏览器都会给 HTML 根元素 html 设置一个默认的 font-size,而这个值通常是 16px。这也就是为什么 1em = 16px 的原因所在了。
em 在计算的时候是会层层计算的,比如:
<div>
<p></p>
</div>
div { font-size: 2em; }
p { font-size: 2em; }
对于如上一个结构的 HTML,由于根元素 html 的字体大小是 16px,所以 p 标签最终计算出来后的字体大小会是 16 * 2 * 2 = 64px
3.3 rem
rem(root em) 和 em 一样,也是一个相对长度单位,不过 rem 相对的是 HTML 的根元素 html。
rem 由于是基于 html 的 font-size 来计算,所以通常用于自适应网站或者 H5 中。
3.4 vw/vh
vw 和 vh 分别是相对于屏幕视口宽度和高度而言的长度单位:
- 1vw = 视口宽度均分成 100 份中 1 份的长度;
- 1vh = 视口高度均分成 100 份中 1 份的长度;
在 JS 中 100vw = window.innerWidth,100vh = window.innerHeight。
vw/vh 的出现使得多了一种写自适应布局的方案,开发者不再局限于 rem 了。
相对视口的单位,除了 vw/vh 外,还有 vmin 和 vmax:
- vmin:取 vw 和 vh 中值较小的;
- vmax:取 vw 和 vh 中值较大的;
四、颜色
根据 CSS 颜色草案 中提到的颜色值类型,大概可以把它们分为这几类:
- 颜色关键字
- transparent 关键字
- currentColor 关键字
- RGB 颜色
- HSL 颜色
4.1 颜色关键字
颜色关键字(color keywords)是不区分大小写的标识符,它表示一个具体的颜色,比如 white(白),黑(black)等;
可接受的关键字列表在CSS的演变过程中发生了改变:
- CSS 标准 1 只接受 16 个基本颜色,称为 VGA 颜色,因为它们来源于 VGA 显卡所显示的颜色集合而被称为 VGA colors (视频图形阵列色彩)。
- CSS 标准 2 增加了 orange 关键字。
- 从一开始,浏览器接受其它的颜色,由于一些早期浏览器是 X11 应用程序,这些颜色大多数是 X11 命名的颜色列表,虽然有一点不同。SVG 1.0 是首个正式定义这些关键字的标准;CSS 色彩标准 3 也正式定义了这些关键字。它们经常被称作扩展的颜色关键字, X11 颜色或 SVG 颜色 。
- CSS 颜色标准 4 添加可 rebeccapurple 关键字来纪念 web 先锋 Eric Meyer。
4.1.1 transparent 关键字
transparent 关键字表示一个完全透明的颜色,即该颜色看上去将是背景色。从技术上说,它是带有 alpha 通道为最小值的黑色,是 rgba(0,0,0,0) 的简写。
4.1.2 currentColor 关键字
currentColor 会取当前元素继承父级元素的文本颜色值或声明的文本颜色值,即 computed 后的 color 值。
4.1.3 RGB[A] 颜色
RGB[A] 颜色是由 R(red)-G(green)-B(blue)-A(alpha) 组成的色彩空间。
4.1.4 HSL[A] 颜色
HSL[A] 颜色是由色相(hue)-饱和度(saturation)-亮度(lightness)-不透明度组成的颜色体系。
写法上可以参考 RGB 的写法,只是参数的值不一样。
五、媒体查询
媒体查询是指针对不同的设备、特定的设备特征或者参数进行定制化的修改网站的样式。
你可以通过给 <link>
加上 media 属性来指定该样式文件只能对什么设备生效,不指定的话默认是 all,即对所有设备都生效:
<link rel="stylesheet" src="styles.css" media="screen" />
<link rel="stylesheet" src="styles.css" media="print" />
- all:适用于所有设备;
- print:适用于在打印预览模式下在屏幕上查看的分页材料和文档;
- screen:主要用于屏幕;
- speech:主要用于语音合成器。
需要注意的是:通过 media 指定的 资源尽管不匹配它的设备类型,但是浏览器依然会加载它。
除了通过 <link>
让指定设备生效外,还可以通过 @media
让 CSS 规则在特定的条件下才能生效。响应式页面就是使用了 @media 才让一个页面能够同时适配 PC、Pad 和手机端。
@media (min-width: 1000px) {}
媒体查询支持逻辑操作符:
- and:查询条件都满足的时候才生效;
- not:查询条件取反;
- only:整个查询匹配的时候才生效,常用语兼容旧浏览器,使用时候必须指定媒体类型;
- 逗号或者 or:查询条件满足一项即可匹配;
媒体查询还支持众多的媒体特性,使得它可以写出很复杂的查询条件:
/* 用户设备的最小高度为680px或为纵向模式的屏幕设备 */
@media (min-height: 680px), screen and (orientation: portrait) {}