重学前端-CSS篇2-dispaly、position、定位机制、布局、盒子模型、BFC

display常用值

参考链接英文
参考链接中文

// 常用值
none:元素不显示
inline:将元素变为内联元素,默认
block:将元素变为块级元素
inline-block:将元素变为内联块级元素
list-item:inline:将元素变为列表显示(一般不用)
table:将元素变为块级表格元素,前后带有换行符
inline-table:将元素变为内联表格元素,前后不带换行符
table-row:将元素变为表格行,类似tr
table-cell:将元素变为表格列,类似td
grid:将产生一个块级网格布局
inline-grid:将产生一个内联块级网格布局
flex:将产生一个块级弹性盒子进行布局
inline-flex:将产生一个内联弹性盒子进行布局

position定位

CSS中的定位相当于PS中的新建图层,即在原有文档流上新开一层用于元素显示。
(1)position属性值

static:元素默认值,即没有定位,遵循正常的文档流对象
relative:相对定位
absolute:绝对定位,相对于static以外的第一个父元素进行定位,搭配元素:left/right    top/bottom
fixed:固定布定位,相对于浏览器窗口定位:搭配元素:left/right    top/bottom
inherit:规定应该从父元素继承 position 属性的值
sticky:css3新增,相当于relative和fixed结合,即滑动到一定程度就固定布局
参考链接:https://jsbin.com/moxetad/edit?html,css,output

(2)定位相对性
相对于最近的有定位的父元素,绝对定位,如果向上级找,如果都没找到定位元素,则相对与html定位。

定位机制

控制元素布局的定位方案

1、普通流(normal flow)
HTML默认布局。
以HTML文档为基础,元素按照在HTML中出现的先后位置自上而下布局,内联元素水平排列,直到当行被沾满然后换行。
块级元素则会被渲染为完整的一个新行,除非另外制定,否则所有元素默认都是普通流定位。
也可以说,普通流中元素的位置由该元素在HTML文档中的位置决定。

2、浮动流(float flow)
在浮动布局中,元素首先按照普通流的位置出现,然后根据浮动的方向尽可能地向左边或右边偏移,
其效果与印刷排版中的文本环绕相似。

3、定位(positioning)
(1)绝对定位:absolute positioning
在绝对定位布局中,元素会整体脱离普通流,因此绝对定位元素不会对其兄弟元素造成影响,
而元素具体的位置由绝对定位的坐标决定。这种定位通过设置top、right、bottom、left这些偏移值,
相对于 static 定位以外的第一个父元素进行定位(这种定位通常设置父元素为relative定位来配合使用),
在没有父元素的条件下,它的参照为body,该方式脱离文档流;

(2)静态定位(static positioning)
当我们没有指定定位方式的时候,这时默认的定位方式就是static,也就是按照文档的书写布局自动分配在一个合适的地方,
这种定位方式用margin来改变位置,对left、top、z-index等设置值无效,这种定位不脱离文档流;

(3)相对定位(relative positioning)
该定位是一种相对的定位,可以通过设置left、top等值,使得指定元素相对其正常的位置进行偏移,这种定位不脱离文档流

(4)固定定位(fixed positioning)
生成绝对定位的元素,相对于浏览器窗口进行定位。这种定位方式是相对于整个文档的,只需设置它相对于各个方向的偏移值,
就可以将该元素固定在页面固定的位置,通常用来显示一些提示信息,脱离文档流;

(5)inherit定位
这种方式规定该元素继承父元素的position属性值。

注意:
float,absolute,fixed,脱离文档流,即将元素从普通的布局排版中拿走,
其他盒子在定位的时候,会当没看到它,两者位置重叠就会发生重叠

布局

(1)table布局

(2)绝对定位布局

// 绝对定位中的两栏设计
<div class="left"></div>
<div class="right"></div>
<style type="text/css">
    html,
    body {
        height: 100%;
        margin: 0;
        overflow-y: hidden;
        background: #000;
    }

    div {
        width: 100%;
    }

    .left {
        position: absolute;
        left: 0;
        top: 0;
        width: 200px;
        background-color: green;
    }

    .right {
        margin-left: 200px;
        background-color: orange;
    }
</style>

(3)浮动布局

  • 内联、内联块、浮动、溢出隐藏、纯文本都可以识别浮动元素的位置
  • 块级元素无法识别浮动元素的位置
  • float以后,元素变成内联块级元素
    // 清除浮动
    .clearfix::after {
      content: "";
      /*display: block;*/
      display: table;
      clear: both;
    }
    

(4)flex布局
Flex布局语法
Flex布局示例

(5)网格布局
网格布局参考链接

盒子模型

1、英文:box model

2、组成要素:
    (1)、content:宽高所划分的区域
    (2)、border:边框
    (3)、padding:内边距
    (4)、margin:外边距

3、盒子分类:
    W3C标准盒子模型
    IE盒子模型

4、标准盒子与IE盒子区别:
盒子宽高的计算方式不一样

(1)标准盒子模型

// 元素宽高度计算
一个元素的宽度 =  content

盒子总宽度 = margin-left + border-left + padding-left + width +
padding-right + border-right + margin-right

盒子总高度 = margin-top + border-top + padding-top + height +
padding-bottom + border-bottom + margin-bottom

(2)IE盒子模型

// 元素宽高度计算
一个元素的宽度 =  content + padding + border

盒子总宽度 = margin-left + width +  margin-right

盒子总高度 = margin-top + height + margin-bottom

(3)box-sizing设置两种模型

box-sizing取值:
content-box:W3C标准模型,浏览器默认设置
border-box:IE模型

padding-box:针对firefox,在Firefox 50中已被删除

具体可以参考:
https://developer.mozilla.org/zh-CN/docs/Web/CSS/box-sizing

(4)JS获取盒模型的宽高

取出前提浏览器渲染完毕之后

// 1、只能获取行内样式的宽高
dom.style.width/height
// 2、内联样式和外联样式的宽高都能取到,但只有 IE 支持
dom.currentStyle.width/height
// 3、内联样式和外联样式的宽高都能取到,几乎所有主流浏览器都支持
window.getComputedStyle(dom).width/height
// 4、内联样式和外联样式的宽高都能取到,几乎所有主流浏览器都支持,
// 取到的是盒模型距离viewport左上角的距离(绝对位置)
dom.getBoundingClientRect().width/height/left/top

示例如下:
//  获取dom
let dom = ocument.getElementById('box');

console.log('style:' + box.style.width);
console.log('currentStyle:' + box.currentStyle.width) ;
console.log('getComputedStyle:' + getComputedStyle(box).width)
console.log('getBoundingClientRect:' + box.getBoundingClientRect().width);

BFC

定义:边距重叠解决方案
中文:块级格式化上下文
英文:Block Formatting Context

BFC原理(渲染规则)

(1)BFC 里面的元素,在垂直方向,边距会发生重叠
(2)BFC在页面中是独立的容器,外面的元素不会影响里面的元素,反之亦然
(3)计算BFC的高度时,浮动的子元素也参与计算
(4)BFC区域不与旁边的float box区域重叠。(可以用来清除浮动带来的影响)

元素创建BFC方式

1、body本身为BFC元素
2、float:值不为none,如:left right
3、position:值不为static或relative,如:absolute fixed
4、display:inline-block table-cell inline-table table flex grid
5、overflow:值不为visible,如:hidden auto scroll

BFC作用

1、解决margin重叠/合并问题(兄弟元素) - 一般不需要解决
2、解决margin塌陷(父子元素)
3、解决浮动流造成父级元素高度坍塌 - 一般用清除浮动解决
4、解决浮动元素覆盖问题

BFC应用举例

(1)解决margin重叠/合并问题

  1. 标准文档流中,竖直方向的margin不叠加,会重叠合并,只取较大的值作为margin(水平方向的margin是可以叠加的,即水平方向没有塌陷现象)。
  2. 如果不在标准流,比如盒子都浮动了,那么两个盒子之间是没有margin重叠的现象的。
// 通常发生在兄弟元素之间
// 现象解释:对应原理第一条:BFC 里面的元素,在垂直方向,边距会发生重叠
<div class="box box1"></div>
<div class="box box2"></div>
<style type="text/css">
    .box {
        width: 100px;
        height: 100px;
    }
    .box1 {
        background-color: lightblue;
        margin-bottom: 100px;
    }
    .box2 {
        background-color: orange;
        margin-top: 50px;
    }
</style>

解决方案:分别将两个元素放置到BFC容器中

<div class="container">
    <div class="box box1"></div>
</div>
<div class="container">
    <div class="box box2"></div>
</div>
<style type="text/css">
    .container {
        overflow: hidden;
    }

    .box {
        width: 100px;
        height: 100px;
    }

    .box1 {
        background-color: lightblue;
        margin-bottom: 100px;
    }

    .box2 {
        background-color: orange;
        margin-top: 50px;
    }
</style>

(2)解决margin塌陷

<div class="box1">
    <div class="box2"></div>
</div>
<style type="text/css">
    .box1 {
        width: 300px;
        height: 300px;
        background-color: #000;
    }
    .box2 {
        width: 50px;
        height: 50px;
        margin: 0 auto;
        margin-top: 100px;
        background-color: orange;
    }
</style>

解决方案:

  1. 给box1加一个透明边框:border-top: 1px solid transparent;
  2. 将父级变为BFC
// box1变为BFC
.box1 {
        width: 300px;
        height: 300px;
        background-color: #000;
        overflow: hidden;
    }

解决原理对应第二条:
BFC在页面中是独立的容器,外面的元素不会影响里面的元素,反之亦然

(3)解决浮动流造成父级元素高度坍塌

<div class="box">
    <div class="box1"></div>
    <div class="box2"></div>
</div>
<style type="text/css">
    .box {
        width: 200px;
        border: 10px solid #000;
    }

    .box1 {
        float: left;
        width: 100px;
        height: 100px;
        background-color: green;
    }

    .box2 {
        float: left;
        width: 100px;
        height: 100px;
        background-color: orange;
    }
</style>

解决方案:

  1. 给父元素设置高度
  2. 使用清除浮动的方法(开发常用)
  3. 父元素变为BFC,以下为BFC解决方案
// 父级加一行代码变为BFC即可
.box {
    width: 200px;
    border: 10px solid #000;
    overflow: hidden;
}

为什么父元素变为BFC之后就有高度了呢?
对应原理第三条:计算BFC的高度时,浮动的子元素也参与计算

(4)解决浮动元素覆盖问题

<div class="box1">浮动元素box</div>
<div class="box2">测试测试测试测试测试测试测试测试测试测试测试测试测试测试测试测试测试测试测试测试测试测试测试测试测试测试</div>
<style type="text/css">
    .box1 {
        float: left;
        width: 100px;
        height: 100px;
        background-color: lightblue;
    }
    .box2 {
        width: 200px;
        height: 200px;
        background-color: orange;
    }
</style>

解决方案:右侧浮动元素变为BFC

// box2加一行代码变为BFC即可
.box2 {
    width: 200px;
    height: 200px;
    background-color: orange;
    overflow: hidden;
}

对应原理第四条:BFC区域不与旁边的float box区域重叠

BFC、IFC、GFC、FFC定义

BFC:Block Formatting Contexts - 块级格式化上下文
IFC:Inline Formatting Contexts - 内联格式化上下文
GFC:GridLayout Formatting Contexts - 网格布局格式化上下文
FFC:Flex Formatting Contexts - 自适应格式化上下文
标签: