# 定位

### 文档流

​	文档流就是HTML文档内所有元素按照一定规律排列并显示的形式。

　CSS文档流大致可以分为3种：标准流，浮动流，定位流。

- 标准流

  - 默认情况下，HTML元素都在标准流中呈现和展示。我们之前把元素分为块级元素，行内元素，行内块级元素，他们的特性是块级独占一行，行内和行内块级可以在一行内共存，这些特性都是针对标准流的。总结一下就是，标准流中元素只能在水平或垂直方向上排版。如果元素是块级元素, 那么就会垂直排版，如果元素是行内元素/行内块级元素, 那么就会水平排版。

- 浮动流

  - 　浮动流只有一种排版方式, 就是水平排版。 它只能设置某个元素在父元素内左对齐或者右对齐。设置了浮动的元素，**将脱离标准流**，之后它将无视元素的display属性，并且都被当做块级元素处理。

- 定位流

  ​	标准流和浮动流都只能在水平或垂直方向布局元素，但现实是，我们可能需要在上下左右几个方向上同时偏移元素，定位流正是为了解决这一问题而设计的。通过设置元素的position属性，可以让元素处于定为流中，并通过left、right、top、bottom属性设置元素具体的偏移量。

  　　定为流分为四种：

  　　　　a) static 静态定位，实际上所有元素默认都是静态定位的，即处于标准流中。

  　　　　b) relative 相对定位，元素保留在标准流中所占用的位置，但实际是**边框及以内的部分将显示在偏移之后的位置**。即虽然元素已经不再原来的位置了，`但之前所占用的空间并不会被释放给其他标准流中的元素`。

  　　　　c) absolute 绝对定位，元素脱离标准流，浏览器把它视作块级元素，不论定位之前它是何种元素，其他元素也将无视它。绝对定位的偏移量是相对于其**有定位属性的第一个祖先元素的**。

  　　　　d) fixed 固定定位，固定定位和绝对定位相似，但它的偏移量固定的相对于浏览器窗口。



### position 应用

> ​	position 属性用来指定一个元素在网页上的位置 ，一共有5种定位方式

- **static  (默认)**
- **relative**
- **fixed**
- **absolute**
- sticky



#### 属性详解

#### static

------

static 是position 属性的默认值，这个值使指定元素使用正常的布局行为，即元素在文档常规流中当前的布局位置，此时top, right, bottom, left和z-index 都无效

示例：

html

```
<!DOCTYPE html>
<html lang="en">
<head>     
    <meta charset="UTF-8">    
    <title>Title</title> 
<body>     
    <div class="content">         
        <div class="box" id="one">One</div>        
		 <div class="box" id="two">Two</div>         
        <div class="box" id="three">Three</div>         
        <div class="box" id="four">Four</div>     
   	</div> 
</body> 
</html>
```



css

```
    .box {
        display: inline-block;  // 容器内的元素水平排列
        width: 100px;
        height: 100px;
        background: red;
        color: white;
    }

    #two {
        position: static;
        top: 20px;
        left: 20px;
        bottom:1px;
        right:9px
        background: blue;
    }
```



![image-20201221095702906](定位.assets/image-20201221095702906.png)





##### **position:static** 

<font color="red" size=5>**top,left,right,bottom无效**</font>



#### relative

------

relative 表示，相对于默认位置（即 static 时的位置）进行偏移，即定位基点是元素的默认位置。 它必须搭配 top、bottom、left、right 这四个属性一起使用，用来指定偏移的方向和距离。

示例：

html不变

css改为：

```
 .box {
        display: inline-block;
        width: 100px;
        height: 100px;
        background: red;
        color: white;
    }

    #two {
        position: relative;
        top: 20px;
        left: 20px;
        background: blue;
    }


```



![image-20201221102916077](定位.assets/image-20201221102916077.png)

#### absolute

------

absolute 表示，相对于上级元素（一般是父元素）进行偏移，即定位基点是父元素。

**它有一个重要的限制条件：定位基点（一般是父元素）不能是 static 定位，否则定位基点就会变成整个网页的根元素 html。**

另外，absolute 定位也必须搭配 top、bottom、left、right 这四个属性一起使用。

示例：

html 不变 css 改为：

父元素static定位 子元素 absolute定位

```
.content {
        margin-left: 100px;
        border: 2px solid blue;
    }
    .box {
        display: inline-block;
        width: 100px;
        height: 100px;
        background: red;
        color: white;
    }

    #two {
        position: absolute;
        top: 20px;
        left: 20px;
        background: blue;
    }

```

![image-20201221103043181](定位.assets/image-20201221103043181.png)

<font color="red">**此时 子元素相对于body定位**</font>



父元素relative 定位 子元素absolute定位

css 改为：

```
   .content {
        margin-left: 100px;
        border: 2px solid blue;
    }
    .box {
        display: inline-block;
        width: 100px;
        height: 100px;
        background: red;
        color: white;
    }

    #two {
        position: absolute;
        top: 20px;
        left: 20px;
        background: blue;
    }

```

![image-20201221103321675](定位.assets/image-20201221103321675.png)

<font color="red">**此时子元素根据父元素定位**</font>



#### fixed

------

fixed 表示，相对于视口（viewport，浏览器窗口）进行偏移，即定位基点是浏览器窗口。这会导致元素的位置不随页面滚动而变化，好像固定在网页上一样。

元素的位置通过 left、top、right 以及 bottom 属性进行规定。

示例：

```
<!DOCTYPE html>
<html lang="en" xmlns="http://www.w3.org/1999/html">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
</head>
<body>
    <div class="content">
        <div class="header">Header</div>
        <div class="blank"></div>
        <p>
            我是内容~ <br/>
            我是内容~ <br/>
            我是内容~ <br/>
            我是内容~ <br/>
            我是内容~ <br/>
            我是内容~ <br/>
            我是内容~ <br/>
            我是内容~ <br/>
            我是内容~ <br/>
            我是内容~ <br/>
            我是内容~ <br/>
            我是内容~ <br/>
            我是内容~ <br/>
            我是内容~ <br/>
            我是内容~ <br/>
            我是内容~ <br/>
            我是内容~ <br/>
        </p>
    </div>
</body>
</html>
```

css:

```
   .content {
        width: 500px;
        height: 200px;
        overflow: scroll;
    }
    .header {
        width: 100%;
        height: 50px;
        background: red;
        color: white;
        position: fixed;
    }
    p {
        margin-top: 50px;
    }

```



![image-20201221104140216](定位.assets/image-20201221104140216.png)



#### sticky 

------

sticky 跟前面四个属性值都不一样，它会产生动态效果，很像 relative 和 fixed 的结合：一些时候是 relative 定位（定位基点是自身默认位置），另一些时候自动变成 fixed 定位（定位基点是视口）。比如型表格滚动的时候，表头始终固定。

sticky 生效的前提是，必须搭配 top、bottom、left、right 这四个属性一起使用，不能省略，否则等同于 relative 定位，不产生"动态固定"的效果。原因是这四个属性用来定义"偏移距离"，浏览器把它当作 sticky 的生效门槛



## 常用的display属性 

1. block 指定元素为块级元素   块级元素（如div）的display属性的默认值

2. inline 指定元素为行内元素   内联元素（如span,a...able）的display的默认值

   > 在块级元素中指定display:inline 能将此元素转换成内联元素
   >
   > 在内联元素中指定 display:block  能将此元素转换成块级元素

3. flex 详情至弹性盒子 指定元素为弹性盒子

4. grid 详情自行探索网格布局（grid）

5. table 指定元素为table 