盒模型
CSS把每个元素视为一个盒子,每个盒子包括分为内容(content)、填充(padding)、边界(margin)、边框(border)四个部分。这种对界面元素的抽象,称为盒模型。
盒模型是CSS布局的基本单元。
有两种盒模型:IE盒模型(也称怪异盒模型)(border-box)、W3C标准盒模型(content-box)
IE盒模型和W3C标准盒模型的区别:
- W3C标准盒模型:属性width,height只包含内容content,不包含border和padding。
- IE盒模型:属性width,height包含content、border和padding,指的是content +padding+border。
在 IE8+ 浏览器中使用哪个盒模型可以由box-sizing(CSS新增的属性)控制,默认值为content-box,即标准盒模型。
如果将box-sizing设为border-box则用的是IE盒模型。如果在 IE6/7/8中DOCTYPE缺失会将盒子模型解释为IE。
盒子模型。若在页面中声明了DOCTYPE类型,所有的浏览器都会把盒模型解释为W3C盒模型。
定位和浮动
简介
我们知道盒模型是CSS布局的基本单元,实现一个页面,其实就是实现一个个的盒子,通过控制盒子的尺寸、颜色、边框、位置,把盒子设置好预期的样式,并摆放在页面上。
尺寸、颜色、边框可以通过盒子的width,height、background、border来控制,那么如何控制盒子的位置呢(如何摆放盒子)?
CSS提供了3种机制来控制盒子的位置:普通文档流、float和position定位。
普通文档流
普通文档流就是根据块级元素的标签在HTML里的顺序,从上至下,依次排开。行内元素在一行中水平排列的。
我们使用普通文档流控制盒子的位置,就是通过控制元素的出现顺序来实现的。例如让header出现在footer上面,那就在html中把header标签放在footer前面。
块元素和行内元素
块元素:独占一行;元素的宽高、以及内外边距都可设置;元素宽度在不设置的情况下,是它本身父容器的100%。
行元素(行内元素):在水平方向上修改水平尺寸(padding,margin,border),能产生相应的效果,垂直方向上对行元素的高度是毫无影响的。
因此,行内元素直接定义width和height是没有意义的,行元素的宽高是靠内容撑起来的。
但是,可以通过设置line-height,来规定行元素的高度。
可以通过对行元素设置display属性,转化为块元素,display:block
。
display的属性值:
block
块类型。默认宽度为父元素宽度,可设置宽高,换行显示。none
元素不显示,并从文档流中移除。inline
行内元素类型。默认宽度为内容宽度,不可设置宽高,同行显示。inline-block
默认宽度为内容宽度,可以设置宽高,同行显示。
浮动
浮动的概念
浮动是另一种布局方法,浮动元素脱离普通文档流,浮在普通文档流之上。
最初,引入 float 属性是为了能让 web 开发人员实现简单的布局,包括在一列文本中浮动的图像,文字环绕在它的左边或右边。但大家很快意识到,它可以浮动任何东西,而不仅仅是图像,所以浮动的使用范围扩大了。
float 属性可以使一个元素脱离正常的文档流(normal flow),然后被安放到它所在容器的的左端或者右端,并且其他的文本和行内元素环绕它。
浮动有左浮动和右浮动。左浮动的元素浮起来,尽量靠左摆放,有浮动元素浮起来,尽量靠右摆放。
浮动元素如果前面一个元素是普通元素,新起一行。
浮动元素前面是浮动元素,则尽量挨着,一行放不开就新起一行。
普通元素前面是浮动元素,不影响,当做没有。
普通元素如果有clear: left属性,则如果前面是左浮动元素新起一行,如果前面是普通元素,新起一行,如果前面是右浮动元素,则当做没看见。
清除浮动
注意:div默认宽度是父元素的100%,高度默认是0。高度会被子元素撑满,但是浮动的元素会造成父元素高度塌陷。因为浮动元素脱离了文档流,所以浮动元素并不会占据包含元素的空间,包含元素高度不会自动撑开,造成塌陷。我们需要清除浮动。
清除浮动的方法:
后面增加一个元素,设置clear: both。
父元素设置伪元素,给伪元素设置clear: both。
父元素设置overflow: hidden。
定位
position取值为static、relative、absolute、fixed。
relative
:相对于自己在普通文档流中的位置,这时候元素不会脱离普通文档流。
absolute
:脱离普通文档流,相对于第一个设置了position(relative、absolute、fixed)的元素定位。
fixed
:脱离普通文档流,相对于窗口定位。
只有取值为relative、absolute、fixed,设置left、top、right、bottom才有效。
注意:浮动的元素不应该设置定位。
z-index
HTML文档中的元素存在于三个维度之中。除了大家熟知的平面画布中的x轴和y轴,还有控制第三维度的z轴。
浏览器渲染时候,z轴上靠上的元素覆盖下面的元素。
z-index就是控制元素层级的属性。只有定位了的元素才生效。
后出现的元素在先出现的元素之上。
z-index大的在上面,如果z-index相同,则比较元素出现顺序。
但并不是z-index大就一定在上面,这个和堆叠上下文的概念有关
堆叠上下文
如果给一个元素设置了z-index的值(整型),就会创建一个堆叠上下文。z-index: auto不创建堆叠上下文。
根元素默认是堆叠上下文。
堆叠上下文是一个树状结构,但这个树状结构和DOM结构不是一一对应,因为元素不设置z-index就不会创建堆叠上下文。
堆叠上下文形成一个“层”,浏览器渲染时候,会按“层”渲染,较高的“层”会覆盖较低的“层”。
由于浏览器按“层”渲染,所以不同“层”里面的子元素之间的z-index大小没有比较的意义。
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Document</title>
<style>
*{
margin: 0;
padding: 0;
}
#A {
position: relative;
width: 300px;
height: 300px;
background-color: red;
z-index: 1;
}
#B {
position: relative;
top: -200px;
left: 50px;
width: 300px;
height: 300px;
background-color: blue;
z-index: 0;
}
#a {
position: relative;
width: 150px;
height: 150px;
background-color: pink;
z-index: 0;
}
#b {
position: relative;
width: 150px;
height: 150px;
background-color: yellow;
z-index: 999;
}
</style>
</head>
<body>
<div id="A">
<div id="a"></div>
</div>
<div id="B">
<div id="b"></div>
</div>
</body>
</html>
上面代码中,#A的z-index为1,形成一个堆叠上下文,#B的z-index为0,形成一个堆叠上下文。#A的z-index更大,因此在上面。
虽然#b的z-index大于#a,但是由于所在的堆叠上下文#B不如#A,因此没有在上面展示。
如果设置#B的z-index为auto,就可以展示,这是因为auto不创建堆叠上下文。
层级关系如下:
- (bottom) 元素构成堆叠上下文
z-index: 0;
- 负堆叠顺序的子元素
z-index: -1;
- position文档流中,非内联,非定位子元素
display: block; position: static
- 非定位浮动子元素
float: left | right; position: static
- 内联流,非定位子元素
display: inline; position: static
- 堆叠顺序为0的子元素
z-index: auto | 0; position: relative | absolute | fixed
- (top) 堆叠顺序为正的子元素
z-index: 1; position: relative | absolute | fixed
BFC和IFC
深度剖析Margin塌陷,BFC,Containing Block之间的关系
margin塌陷和BFC
margin塌陷是css1.0版本引入的一个规则。
margin塌陷是为了兼容p标签样式问题,在css1.0中,p标签其实就是一个设置了样式的div。
p {
display: block;
margin-block-start: 1em;
margin-block-end: 1em;
margin-inline-start: 0px;
margin-inline-end: 0px;
}
为了让多个p标签排列时候,上下边距和p标签之间的间隔相同,因此设计了margin合并的规则。
符合下面规则的,就会出现margin塌陷的现象。
- 元素之间没有被非空内容、padding、border 或 clear 分隔开。
- 然后有符合下面几种毗邻情况:
- 一个元素的 margin-top 和它的第一个子元素的 margin-top
- 普通流中一个元素的 margtin-bottom 和它的紧邻的兄弟元素的的 margin-top
- 一个元素( height 为 auto )的 margin-bottom 和它的最后一个子元素的margin-bottom
- 一个没有创建 BFC、没有子元素、height 为0的元素自身的 margin-top 和 margin-bottom
css2.0的bfc是为了解决margin塌陷,因为有时候我们就是不希望有margin塌陷的现象。
BFC本质
BFC(块级格式化上下文,block formatting context)就是一系列的规则:由一系列条件触发的布局方式,布局方式的核心就是“隔离”,让满足条件的元素内部的子元素不会影响到元素外部。
context,上下文,可以理解为“环境”、“系统”。
BFC触发条件
- 根元素(整个页面就是一个大的BFC);
- float为 left | right;
- overflow为 hidden | auto | scroll;
- display为 inline-block | table-cell | table-caption | flex | inline-flex;
- position为 absolute | fixed;
BFC功能
BFC的初衷为了解决margin塌陷,但是BFC还有其他功能
- 解决垂直、包含塌陷
- 清除浮动
- 防止普通文档流被浮动元素遮挡(可以实现两栏布局)
<div class="container">
<div class="aside">
aside
</div>
<div class="main">
main content
</div>
</div>
.container {
border: 1px solid red;
width: 300px;
margin: 0 auto;
overflow: hidden;
}
.aside {
text-align: center;
height: 150px;
background: #bcbcbc;
width: 100px;
margin: 10px;
float: left;
}
.main {
text-align: center;
background: #abcded;
overflow: hidden;
height: 150px;
margin: 10px;
}
IFC
IFC也是一种布局规则,inline元素和inline-block符合IFC的布局规则。
- 框会从包含块的顶部开始,一个接一个地水平摆放。
- 摆放这些框时,它们在水平方向的 内外边距+边框 所占用的空间都会被考虑; 在垂直方向上,这些框可能会以不同形式来对齐: 水平的margin、padding、border有效,垂直无效。不能指定宽高;
- 行框的宽度是 由包含块和存在的浮动来决定; 行框的高度 由行高来决定