HTML与CSS3入门:前端开发必学基础

发表时间: 2023-07-13 18:06

CSS盒模型详解

为什么要把这个知识点单独拿出来记录,是因为这个是css最基础、最重要,也是一个难点、面试如果只要问到了css相关的,这个知识点应该是必问的,所有有必要单独拿出来说。

1.概念

css盒模型:可以认为每个html标签都是一个方块,然后这个方块又包着几个小方块,如同盒子一层层的包裹着,这就是所谓的盒模型,

盒模型分为IE盒模型和W3C标准盒模型

2.IE盒模型和W3C标准盒模型的区别是什么

W3C标准盒模型:属性width,height只包含内容content,不包含border和padding。

IE盒模型:属性width,height包含border和padding,指的是content+padding+border

在ie8+浏览器中使用哪个盒模型可以由box-sizing(CSS新增的属性)控制,默认值为content-box,即标准盒模型;如果将box-sizing设为border-box则用的是IE盒模型。如果在ie6,7,8中DOCTYPE缺失会触发IE模式。在当前W3C标准中盒模型是可以通过box-sizing自由的进行切换的。

content-box(标准盒模型)

width = 内容的宽度

height = 内容的高度

border-box(IE盒模型)

width = border + padding + 内容的宽度

height = border + padding + 内容的高度

谷歌浏览器,按下F12,然后把右边栏的滚动条拉到最下面你就会看到一个东西:


通过代码就能更直观的理解

.box{        width:200px;        height:200px;}//  此时,盒子大小就是content的大小

还是这个盒子,如果加上padding

.box{        width:200px;        height:200px;        padding:20px;}//  此时,盒子的长宽变成了240x240



显然,padding是能够改变盒子的大小的,这时盒子大小就等于content+padding

那如果加上border呢

.box{        width:200px;        height:200px;        padding:20px;        border:10px solid black;}// 此时,盒子的长宽变成了260x260



所以这时盒子大小就等于content+padding+border

继续加上margin

.box{        width:200px;        height:200px;        background-color:pink;        padding:20px;        border:10px solid black;        margin-bottom:10px;}.box1{        width: 100px;        height: 100px;        background: green;}// 此时,盒子的长宽仍为260x260,即盒子的大小并未发生变化,盒子的底部产生了10px的空白




所以说,盒子的大小为content+padding+border即内容的(width)+内边距的再加上边框,而不加上margin。很多时候,我们会错误地把margin算入,若那样的话,上面这种情形盒子的大小应该是260x270,但实际情况并不是这样的。

css的盒模型由content(内容)、padding(内边距)、border(边框)、margin(外边距)组成。但盒子的大小由content+padding+border这几部分决定,把margin算进去的那是盒子占据的位置,而不是盒子的大小!

3.box-sizing对盒模型的影响

我们可以试着给上面的粉色方块设置box-sizing属性为border-box发现,会发现:无论我们怎么改border和padding盒子大小始终是定义的width和height

.box{        width:200px;        height:200px;        box-sizing:border-box;          padding:20px;}// 此时,盒子的大小始终是200*200


我们在编写页面代码时应尽量使用标准的W3C模型(需在页面中声明DOCTYPE类型),这样可以避免多个浏览器对同一页面的不兼容。因为若不声明DOCTYPE类型,IE浏览器会将盒子模型解释为IE盒子模型,FireFox等会将其解释为W3C盒子模型;若在页面中声明了DOCTYPE类型,所有的浏览器都会把盒模型解释为W3C盒模型。

BFC详解

1.什么是BFC

BFC:块级格式化上下文(Block Fromatting Context),指一个隔离的独立的块级渲染区域,是 Web 页面的可视化 CSS 渲染的一部分,是布局过程中生成块级盒子的区域,也是浮动元素与其他元素的交互限定区域。

注意:一个 BFC 的范围包含创建该上下文的所有子元素,但不包括 创建了新 BFC 的子元素的内部元素。这从另一个角度说明,一个元素不能同时存在于两个 BFC 中。因为如果一个元素能够同时处于两个 BFC 中,那么就意味着这个元素能与两个 BFC 中的元素发生作用,就违反了 BFC 的 隔离作用

2.文档流

我们常说的文档流其实分为 定位流浮动流普通流 三种。而普通流其实就是指 BFC 中的 FC。FC(Formatting Context),直译过来就是格式上下文,它是页面中的一块渲染区域,有一套渲染规则,决定了其子元素如何布局,以及和其他元素之间的关系和作用。常见的 FC 有 BFC、IFC(内联元素格式化上下文)、GFC 和 FFC。

3.常规流

在常规流中,盒子一个接着一个排列;

在块级格式化上下文里面,它们垂直方向排列;

在行内格式化上下文里面,它们水平方向排列;

当 position 为 static 或 relative,并且 float 为 none 时会触发常规流;

对于静态定位(static positioning),position: static,盒的位置是常规流布局里的位置;

对于相对定位(relative positioning),position: relative,盒偏移位置由 top、bottom、left、right 属性定义。即使有偏移,仍然保留原有的位置,其它常规流不能占用这个位置

4.浮动流

左浮动元素尽量靠左、靠上,右浮动同理,这导致常规流环绕在它的周边,除非设置 clear 属性;

浮动元素不会影响块级元素的布局,但浮动元素会影响行内元素的布局,让其围绕在自己周围,撑大父级元素,从而间接影响块级元素布局;

最高点不会超过当前行的最高点、它前面的浮动元素的最高点;

不超过它的包含块,除非元素本身已经比包含块更宽;

行内元素出现在左浮动元素的右边和右浮动元素的左边,左浮动元素的左边和右浮动元素的右边是不会摆放浮动元素的;

5.定位流

绝对定位方案,盒从常规流中被移除,不影响常规流的布局;

它的定位相对于它的包含块,相关 CSS 属性:top、bottom、left、right;

如果元素的属性 position 为 absolute 或 fixed,它是绝对定位元素;

对于 position: absolute,元素定位将相对于上级元素中最近的一个 relative、fixed、absolute,如果没有则相对于 body

7.BFC 触发条件

  1. 根元素默认创建 BFC
  2. 浮动元素(元素 float 不为 none)
  3. 绝对定位元素(元素 position 为 absolute 或 fixed)
  4. 行内块元素(元素 display 为 inline-block)
  5. 表格单元格(元素 display 为 table-cell,HTML 表格单元格默认为该值)
  6. 表格标题(元素 display 为 table-caption,HTML 表格标题默认该值)
  7. 匿名表格单元格元素(display 值是 table、table-row、table-row-group、table-header-group、table-footer-group)
  8. overflow 值不为 visible
  9. 弹性元素(display 为 flex 或 inline-flex 元素的直接子元素)
  10. 网格元素(display 为 grid 或 inline-grid 元素的直接子元素)

7.BFC 约束规则

浏览器对 BFC 区域的约束规则

生成 BFC 元素的子元素会一个接一个的放置;

垂直方向上他们的起点是一个包含块的顶部,两个相邻子元素之间的垂直距离取决于元素的 margin 特性。在 BFC 中相邻的块级元素的外边距会折叠(Mastering margin collapsing)。

生成 BFC 元素的子元素中,每一个子元素左外边距与包含块的左边界相接触(对于从右到左的格式化,右外边距接触右边界),即使浮动元素也是如此(尽管子元素的内容区域会由于浮动而压缩),除非这个子元素也创建了一个新的 BFC(如它自身也是一个浮动元素)。

规则解读:

在 BFC 的垂直方向上,边距会发生重叠(margin collapse)

每个元素的左外边距与包含块的左边界相接触(从左向右),即使浮动元素也是如此。(这说明 BFC 中子元素不会超出他的包含块,而 position 为 absolute 的元素可以超出他的包含块边界)

BFC 的区域不会与 float 的元素浮动区域重叠

计算 BFC 的高度时,浮动子元素也参与计算

8.使用场景

(1)防止margin重叠(塌陷)

<style>    p {        color: #f55;        background: #fcc;        width: 200px;        line-height: 100px;        text-align:center;        margin: 100px;    }</style><body>    <p>Haha</p >    <p>Hehe</p ></body>

两个p元素之间的距离为100px,发生了margin重叠(塌陷),以最大的为准,如果第一个P的margin为80的话,两个P之间的距离还是100,以最大的为准。

同一个BFC的俩个相邻的盒子的margin会发生重叠,可以在p外面包裹一层容器,并触发这个容器生成一个BFC,那么两个p就不属于同一个BFC,则不会出现margin重叠

<style>    .wrap {        overflow: hidden; // 新的BFC    }    p {        color: #f55;        background: #fcc;        width: 200px;        line-height: 100px;        text-align:center;        margin: 100px;    }</style><body>    <p>Haha</p >    <div class="wrap">        <p>Hehe</p >    </div></body> //  这时候,边距则不会重叠

(2)清除内部浮动

<style>    .par {        border: 5px solid #fcc;        width: 300px;    }     .child {        border: 5px solid #f66;        width:100px;        height: 100px;        float: left;    }</style><body>    <div class="par">        <div class="child"></div>        <div class="child"></div>    </div></body>

BFC在计算高度时,浮动元素也会参与,所以我们可以触发.par元素生成BFC,则内部浮动元素计算高度时候也会计算

.par {    overflow: hidden;}

(3)自适应多栏布局

<style>    body {        width: 300px;        position: relative;    }     .aside {        width: 100px;        height: 150px;        float: left;        background: #f66;    }     .main {        height: 200px;        background: #fcc;    }</style><body>    <div class="aside"></div>    <div class="main"></div></body>

每个元素的左外边距与包含块的左边界相接触,因此,虽然.aslide为浮动元素,但是main的左边依然会与包含块的左边相接触,BFC的区域不会与浮动盒子重叠所以我们可以通过触发main生成BFC,以此适应两栏布局

.main {    overflow: hidden;}

这时候,新的BFC不会与浮动的.aside元素重叠。因此会根据包含块的宽度,和.aside的宽度,自动变窄

BFC实际就是页面一个独立的容器,里面的子元素不影响外面的元素