# CSS 基础
# 布局单位
常用的布局单位包括像素( px
),百分比( %
), em
, rem
, vw/vh
。
(1)像素( px
)是页面布局的基础,一个像素表示终端(电脑、手机、平板等)屏幕所能显示的最小的区域,像素分为两种类型:CSS 像素和物理像素:
- CSS 像素:为 web 开发者提供,在 CSS 中使用的一个抽象单位;
- 物理像素:只与设备的硬件密度有关,任何设备的物理像素都是固定的。
(2)百分比( %
),当浏览器的宽度或者高度发生变化时,通过百分比单位可以使得浏览器中的组件的宽和高随着浏览器的变化而变化,从而实现响应式的效果。一般认为子元素的百分比相对于直接父元素。
(3)em 和 rem 相对于 px 更具灵活性,它们都是相对长度单位,它们之间的区别:em 相对于父元素,rem 相对于根元素。
- em: 文本相对长度单位。相对于当前对象内文本的字体尺寸。如果当前行内文本的字体尺寸未被人为设置,则相对于浏览器的默认字体尺寸 (默认 16px)。(相对父元素的字体大小倍数)。
- rem: rem 是 CSS3 新增的一个相对单位,相对于根元素(html 元素)的 font-size 的倍数。作用:利用 rem 可以实现简单的响应式布局,可以利用 html 元素中字体的大小与屏幕间的比值来设置 font-size 的值,以此实现当屏幕分辨率变化时让元素也随之变化。
(4)vw/vh 是与视图窗口有关的单位,vw 表示相对于视图窗口的宽度,vh 表示相对于视图窗口高度,除了 vw 和 vh 外,还有 vmin 和 vmax 两个相关的单位。
- vw:相对于视窗的宽度,视窗宽度是 100vw;
- vh:相对于视窗的高度,视窗高度是 100vh;
- vmin:vw 和 vh 中的较小值;
- vmax:vw 和 vh 中的较大值;
vw/vh 和百分比很类似,两者的区别:
- 百分比(
%
):大部分相对于祖先元素,也有相对于自身的情况比如(border-radius、translate 等) - vw/vm:相对于视窗的尺寸
# 盒模型
判断一个元素的大小时有两种盒模型,一种是 IE 盒模型,另一种是标准盒模型。盒子的大小由 margin
、 border
、 padding
、 content
四部分组成。
在 IE 盒模型中如果我们给一个元素设置了 height
和 width
时,这些值会包括 content
、 padding
、 border
。如:
.box{ | |
height:100px; | |
width:100px; | |
backgroundcolor:blue; | |
} |
在标准盒模型中,如果我们给一个元素设置了宽高属性,这些值的只会包括 content
。
- 标准盒模型的 width 和 height 属性的范围只包含了 content,
- IE 盒模型的 width 和 height 属性的范围包含了 border、padding 和 content。
可以通过修改元素的 box-sizing 属性来改变元素的盒模型:
box-sizing: content-box
表示标准盒模型(默认值)box-sizing: border-box
表示 IE 盒模型(怪异盒模型)
在书写 html 进行页面布局的过程中,我们经常使用 float
、 postion
属性进行布局。float 只能在块级元素中使用,若在内联元素里使用时会失效。使用 float 时,对应的标签会脱离标准文档流,一个盒子
# 选择器
选择器 | 格式 | 优先级权重 |
---|---|---|
id 选择器 | #id | 100 |
类选择器 | .classname | 10 |
属性选择器 | a[ref=“eee”] | 10 |
伪类选择器 | li:last-child | 10 |
标签选择器 | div | 1 |
伪元素选择器 | li::after | 1 |
相邻兄弟选择器 | h1+p | 0 |
子选择器 | ul>li | 0 |
后代选择器 | li a | 0 |
通配符选择器 | * | 0 |
对于选择器的优先级:
- 标签选择器、伪元素选择器:1
- 类选择器、伪类选择器、属性选择器:10
- id 选择器:100
- 内联样式:1000
注意事项:
!important
声明的样式的优先级最高;- 如果优先级相同,则最后出现的样式生效;
- 继承得到的样式的优先级最低;
- 通用选择器(*)、子选择器(>)和相邻同胞选择器(+)并不在这四个等级中,所以它们的权值都为 0 ;
- 样式表的来源不同时,优先级顺序为:内联样式 > 内部样式 > 外部样式 > 浏览器用户自定义样式 > 浏览器默认样式。
# 文本溢出处理
- 单行文本溢出
overflow: hidden; // 溢出隐藏 | |
text-overflow: ellipsis; // 溢出用省略号显示 | |
white-space: nowrap; // 规定段落中的文本不进行换行 |
- 多行文本溢出
overflow: hidden; // 溢出隐藏 | |
text-overflow: ellipsis; // 溢出用省略号显示 | |
display:-webkit-box; // 作为弹性伸缩盒子模型显示。 | |
-webkit-box-orient:vertical; // 设置伸缩盒子的子元素排列方式:从上到下垂直排列 | |
-webkit-line-clamp:3; // 显示的行数 |
注意:由于上面的三个属性都是 CSS3 的属性,不是所有浏览器都可以兼容,所以要在前面加一个 -webkit-
来兼容一部分浏览器。
# 定位 & 布局
# 浮动
浮动的定义: 非 IE 浏览器下,容器不设高度且子元素浮动时,容器高度不能被内容撑开。 此时,内容会溢出到容器外面而影响布局。这种现象被称为浮动(溢出)。
浮动的特点:
脱离标准文档流
脱离文档流的特点:
- 块元素:
- 块元素不再独占一行
- 盒模型的宽高都默认由内容撑开
- 行内元素:
- 行内元素浮动后特点变成块元素,可以设置宽高
- 块元素:
当水平空间不够时,浮动元素会自动挤向下一行
浮动元素的高度不会超过其兄弟浮动浮动元素的高度
浮动不会遮盖文字,文字会环绕在浮动元素旁边
浮动元素不会脱离父元素
若浮动元素上一个元素未设置浮动,则浮动元素无法上移
浮动的工作原理:
- 浮动元素脱离文档流,不占据空间(引起 “高度塌陷” 现象)
- 浮动元素碰到包含它的边框或者其他浮动元素的边框停留
浮动元素可以左右移动,直到遇到另一个浮动元素或者遇到它外边缘的包含框。浮动框不属于文档流中的普通流,当元素浮动之后,不会影响块级元素的布局,只会影响内联元素布局。此时文档流中的普通流就会表现得该浮动框不存在一样的布局模式。当包含框的高度小于浮动框的时候,此时就会出现 “高度塌陷”。
浮动元素引起的问题?
- 父元素的高度无法被撑开,影响与父元素同级的元素
- 与浮动元素同级的非浮动元素会跟随其后
- 若浮动的元素不是第一个元素,则该元素之前的元素也要浮动,否则会影响页面的显示结构
清除浮动的方式如下:
- 给父级 div 定义
height
属性 - 最后一个浮动元素之后添加一个空的 div 标签,并添加
clear:both
样式 - 包含浮动元素的父级标签添加
overflow:hidden
或者overflow:auto
- 使用 :after 伪元素。由于 IE6-7 不支持 :after,使用 zoom:1 触发 hasLayout**
.clearfix::after{ | |
content: ""; | |
display: block; | |
height: 0; | |
clear: both; | |
} | |
.clearfix{ | |
*zoom: 1; | |
} |
# BFC
先来看两个相关的概念:
- Box: Box 是 CSS 布局的对象和基本单位,⼀个⻚⾯是由很多个 Box 组成的,这个 Box 就是我们所说的盒模型。
- Formatting context:块级上下⽂格式化,它是⻚⾯中的⼀块渲染区域,并且有⼀套渲染规则,它决定了其⼦元素将如何定位,以及和其他元素的关系和相互作⽤。
块格式化上下文(Block Formatting Context,BFC)是 Web 页面的可视化 CSS 渲染的一部分,是布局过程中生成块级盒子的区域,也是浮动元素与其他元素的交互限定区域。
通俗来讲:BFC 是一个独立的布局环境,可以理解为一个容器,在这个容器中按照一定规则进行物品摆放,并且不会影响其它环境中的物品。如果一个元素符合触发 BFC 的条件,则 BFC 中的元素布局不受外部影响。
创建 BFC 的条件:
- 根元素:body;
- 元素设置浮动:float 除 none 以外的值;
- 元素设置绝对定位:position (absolute、fixed);
- display 值为:inline-block、table-cell、table-caption、flex 等;
- overflow 值为非 visible;
BFC 的特点:
- 垂直方向上,自上而下排列,和文档流的排列方式一致。
- 在 BFC 中上下相邻的两个容器的 margin 会重叠
- 计算 BFC 的高度时,需要计算浮动元素的高度
- BFC 区域不会与浮动的容器发生重叠
- BFC 是独立的容器,容器内部元素不会影响外部元素
- 每个元素的左 margin 值和容器的左 border 相接触
BFC 的作用:
- 解决 margin 的重叠问题:由于 BFC 是一个独立的区域,内部的元素和外部的元素互不影响,将两个元素变为两个 BFC,就解决了 margin 重叠的问题。
- 解决高度塌陷的问题:在对子元素设置浮动后,父元素会发生高度塌陷,也就是父元素的高度变为 0。解决这个问题,只需要把父元素变成一个 BFC。常用的办法是给父元素设置
overflow:hidden
。 - 创建自适应两栏布局:可以用来创建自适应两栏布局:左边的宽度固定,右边的宽度自适应。
.left{ | |
width: 100px; | |
height: 200px; | |
background: red; | |
float: left; | |
} | |
.right{ | |
height: 300px; | |
background: blue; | |
overflow: hidden; | |
} | |
<div class="left"></div> | |
<div class="right"></div> |
# margin 重叠问题
问题描述:
两个块级元素的上外边距和下外边距可能会合并(折叠)为一个外边距,其大小会取其中外边距值大的那个,这种行为就是外边距折叠。需要注意的是,浮动的元素和绝对定位这种脱离文档流的元素的外边距不会折叠。重叠只会出现在垂直方向。
计算原则:
折叠合并后外边距的计算原则如下:
兄弟元素
- 如果两者都是正数,那么就去最大者
- 如果是一正一负,就会取两者之和
- 两个都是负值时,取绝对值大的那个
父子元素
- 父子元素相邻外边距,子元素的会传递给父元素(上外边距)
解决办法:
对于折叠的情况,主要有两种:兄弟之间重叠和父子之间重叠
(1)兄弟之间重叠
- 底部元素变为行内盒子:
display: inline-block
- 底部元素设置浮动:
float
- 底部元素的 position 的值为
absolute/fixed
(2)父子之间重叠
- 父元素加入:
overflow: hidden
- 父元素添加透明边框:
border:1px solid transparent
- 子元素变为行内盒子:
display: inline-block
- 子元素加入浮动属性或定位
# position 属性
position 有以下属性值:
属性值 | 概述 |
---|---|
absolute | 生成绝对定位的元素,相对于 static 定位以外的一个父元素进行定位。元素的位置通过 left、top、right、bottom 属性进行规定。 |
relative | 生成相对定位的元素,相对于其原来的位置进行定位。元素的位置通过 left、top、right、bottom 属性进行规定。 |
fixed | 生成绝对定位的元素,指定元素相对于屏幕视⼝(viewport)的位置来指定元素位置。元素的位置在屏幕滚动时不会改变,⽐如回到顶部的按钮⼀般都是⽤此定位⽅式。 |
static | 默认值,没有定位,元素出现在正常的文档流中,会忽略 top, bottom, left, right 或者 z-index 声明,块级元素从上往下纵向排布,⾏级元素从左向右排列。 |
inherit | 规定从父元素继承 position 属性的值 |
前面三者的定位方式如下:
- **relative:** 元素的定位永远是相对于元素自身位置的,和其他元素没关系,也不会影响其他元素。
**fixed:** 元素的定位是相对于 window (或者 iframe)边界的,和其他元素没有关系。但是它具有破坏性,会导致其他元素位置的变化。
**absolute:** 元素的定位相对于前两者要复杂许多。如果为 absolute 设置了 top、left,浏览器会根据什么去确定它的纵向和横向的偏移量呢?答案是浏览器会递归查找该元素的所有父元素,如果找到一个设置了 position:relative/absolute/fixed
的元素,就以该元素为基准定位,如果没找到,就以浏览器边界定位。如下两个图所示:
# position & float & display 的关系
(1)首先判断 display 属性是否为 none,如果为 none,则 position 和 float 属性的值不影响元素最后的表现。
(2)然后判断 position 的值是否为 absolute 或者 fixed,如果是,则 float 属性失效,并且 display 的值应该被设置为 table 或者 block,具体转换需要看初始转换值。
(3)如果 position 的值不为 absolute 或者 fixed,则判断 float 属性的值是否为 none,如果不是,则 display 的值则按上面的规则转换。注意,如果 position 的值为 relative 并且 float 属性的值存在,则 relative 相对于浮动后的最终位置定位。
(4)如果 float 的值为 none,则判断元素是否为根元素,如果是根元素则 display 属性按照上面的规则转换,如果不是,则保持指定的 display 属性值不变。
总的来说,可以把它看作是一个类似优先级的机制,"position:absolute" 和 "position:fixed" 优先级最高,有它存在的时候,浮动不起作用,'display' 的值也需要调整;其次,元素的 'float' 特性的值不是 "none" 的时候或者它是根元素的时候,调整 'display' 的值;最后,非根元素,并且非浮动元素,并且非绝对定位的元素,'display' 特性值同设置值。
# flex 布局
Flex 是 FlexibleBox 的缩写,意为 "弹性布局",用来为盒状模型提供最大的灵活性。任何一个容器都可以指定为 Flex 布局。行内元素也可以使用 Flex 布局。注意,设为 Flex 布局以后,子元素的 float、clear 和 vertical-align 属性将失效。采用 Flex 布局的元素,称为 Flex 容器(flex container),简称 "容器"。它的所有子元素自动成为容器成员,称为 Flex 项目(flex item),简称 "项目"。容器默认存在两根轴:水平的主轴(main axis)和垂直的交叉轴(cross axis),项目默认沿水平主轴排列。
以下 6 个属性设置在容器上:
- flex-direction 属性决定主轴的方向(即项目的排列方向)。
- flex-wrap 属性定义,如果一条轴线排不下,如何换行。
- flex-flow 属性是 flex-direction 属性和 flex-wrap 属性的简写形式,默认值为 row nowrap。
- justify-content 属性定义了项目在主轴上的对齐方式。
- align-items 属性定义项目在交叉轴上如何对齐。
- align-content 属性定义了多根轴线的对齐方式。如果项目只有一根轴线,该属性不起作用。
以下 6 个属性设置在项目上:
- order 属性定义项目的排列顺序。数值越小,排列越靠前,默认为 0。
- flex-grow 属性定义项目的放大比例,默认为 0,即如果存在剩余空间,也不放大。
- flex-shrink 属性定义了项目的缩小比例,默认为 1,即如果空间不足,该项目将缩小。
- flex-basis 属性定义了在分配多余空间之前,项目占据的主轴空间。浏览器根据这个属性,计算主轴是否有多余空间。它的默认值为 auto,即项目的本来大小。
- flex 属性是 flex-grow,flex-shrink 和 flex-basis 的简写,默认值为 0 1 auto。
- align-self 属性允许单个项目有与其他项目不一样的对齐方式,可覆盖 align-items 属性。默认值为 auto,表示继承父元素的 align-items 属性,如果没有父元素,则等同于 stretch。