盒模型

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。

  1. 盒子模型。若在页面中声明了DOCTYPE类型,所有的浏览器都会把盒模型解释为W3C盒模型。

定位和浮动

css定位——position和float的用法详解

搞懂Z-index的所有细节

z-index的工作原理

简介

我们知道盒模型是CSS布局的基本单元,实现一个页面,其实就是实现一个个的盒子,通过控制盒子的尺寸、颜色、边框、位置,把盒子设置好预期的样式,并摆放在页面上。

尺寸、颜色、边框可以通过盒子的width,height、background、border来控制,那么如何控制盒子的位置呢(如何摆放盒子)?

CSS提供了3种机制来控制盒子的位置:普通文档流floatposition定位。

普通文档流

普通文档流就是根据块级元素的标签在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。高度会被子元素撑满,但是浮动的元素会造成父元素高度塌陷。因为浮动元素脱离了文档流,所以浮动元素并不会占据包含元素的空间,包含元素高度不会自动撑开,造成塌陷。我们需要清除浮动。

清除浮动的方法:

  1. 后面增加一个元素,设置clear: both。

  2. 父元素设置伪元素,给伪元素设置clear: both。

  3. 父元素设置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大小没有比较的意义。

  1. <!DOCTYPE html>
  2. <html lang="en">
  3. <head>
  4. <meta charset="UTF-8">
  5. <title>Document</title>
  6. <style>
  7. *{
  8. margin: 0;
  9. padding: 0;
  10. }
  11. #A {
  12. position: relative;
  13. width: 300px;
  14. height: 300px;
  15. background-color: red;
  16. z-index: 1;
  17. }
  18. #B {
  19. position: relative;
  20. top: -200px;
  21. left: 50px;
  22. width: 300px;
  23. height: 300px;
  24. background-color: blue;
  25. z-index: 0;
  26. }
  27. #a {
  28. position: relative;
  29. width: 150px;
  30. height: 150px;
  31. background-color: pink;
  32. z-index: 0;
  33. }
  34. #b {
  35. position: relative;
  36. width: 150px;
  37. height: 150px;
  38. background-color: yellow;
  39. z-index: 999;
  40. }
  41. </style>
  42. </head>
  43. <body>
  44. <div id="A">
  45. <div id="a"></div>
  46. </div>
  47. <div id="B">
  48. <div id="b"></div>
  49. </div>
  50. </body>
  51. </html>

上面代码中,#A的z-index为1,形成一个堆叠上下文,#B的z-index为0,形成一个堆叠上下文。#A的z-index更大,因此在上面。

虽然#b的z-index大于#a,但是由于所在的堆叠上下文#B不如#A,因此没有在上面展示。

如果设置#B的z-index为auto,就可以展示,这是因为auto不创建堆叠上下文。

层级关系如下:

  1. (bottom) 元素构成堆叠上下文z-index: 0;
  2. 负堆叠顺序的子元素 z-index: -1;
  3. position文档流中,非内联,非定位子元素display: block; position: static
  4. 非定位浮动子元素 float: left | right; position: static
  5. 内联流,非定位子元素 display: inline; position: static
  6. 堆叠顺序为0的子元素 z-index: auto | 0; position: relative | absolute | fixed
  7. (top) 堆叠顺序为正的子元素 z-index: 1; position: relative | absolute | fixed

BFC和IFC

深度剖析Margin塌陷,BFC,Containing Block之间的关系

BFC是什么?10 分钟讲透BFC 原理

margin塌陷和BFC

margin塌陷是css1.0版本引入的一个规则。

margin塌陷是为了兼容p标签样式问题,在css1.0中,p标签其实就是一个设置了样式的div。

  1. p {
  2. display: block;
  3. margin-block-start: 1em;
  4. margin-block-end: 1em;
  5. margin-inline-start: 0px;
  6. margin-inline-end: 0px;
  7. }

为了让多个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触发条件

  1. 根元素(整个页面就是一个大的BFC);
  2. float为 left | right;
  3. overflow为 hidden | auto | scroll;
  4. display为 inline-block | table-cell | table-caption | flex | inline-flex;
  5. position为 absolute | fixed;

BFC功能

BFC的初衷为了解决margin塌陷,但是BFC还有其他功能

  • 解决垂直、包含塌陷
  • 清除浮动
  • 防止普通文档流被浮动元素遮挡(可以实现两栏布局)
  1. <div class="container">
  2. <div class="aside">
  3. aside
  4. </div>
  5. <div class="main">
  6. main content
  7. </div>
  8. </div>
  1. .container {
  2. border: 1px solid red;
  3. width: 300px;
  4. margin: 0 auto;
  5. overflow: hidden;
  6. }
  7. .aside {
  8. text-align: center;
  9. height: 150px;
  10. background: #bcbcbc;
  11. width: 100px;
  12. margin: 10px;
  13. float: left;
  14. }
  15. .main {
  16. text-align: center;
  17. background: #abcded;
  18. overflow: hidden;
  19. height: 150px;
  20. margin: 10px;
  21. }

IFC

IFC也是一种布局规则,inline元素和inline-block符合IFC的布局规则。

  1. 框会从包含块的顶部开始,一个接一个地水平摆放。
  2. 摆放这些框时,它们在水平方向的 内外边距+边框 所占用的空间都会被考虑; 在垂直方向上,这些框可能会以不同形式来对齐: 水平的margin、padding、border有效,垂直无效。不能指定宽高;
  3. 行框的宽度是 由包含块和存在的浮动来决定; 行框的高度 由行高来决定