关于 CSS position, 来自 MDN 的描述:
CSS position 属性用于指定一个元素在文档中的定位方式. top,right,bottom,left 属性则决定了该元素的最终位置.
然后来看看什么是文档流(normal flow), 下面是 https://www.w3.org/TR/CSS21/visuren.html# 的描述:
Normal flow
Boxes in the normal flow belong to a formatting context, which may be block or inline, but not both simultaneously. Block-level https://www.w3.org/TR/CSS21/visuren.html#block-level boxes participate in a block formatting https://www.w3.org/TR/CSS21/visuren.html#block-formatting context. Inline-level boxes https://www.w3.org/TR/CSS21/visuren.html#inline-level participate in an inline formatting https://www.w3.org/TR/CSS21/visuren.html#inline-formatting context.
个人补充(此处参考 FungLeo https://blog.csdn.net/fungleo 的博客文章, 原文点此 https://blog.csdn.net/fungleo/article/details/50056111 ):
normal flow 直译为常规流, 正常流, 国内不知何原因大多译为文档流;
窗体自上而下分成一行一行, 并在每行中按从左至右的顺序排放元素;
每个非浮动块级元素都独占一行, 浮动元素则按规定浮在行的一端, 若当前行容不下, 则另起新行再浮动;
内联元素也不会独占一行, 几乎所有元素 (包括块级, 内联和列表元素) 均可生成子行, 用于摆放子元素;
有三种情况将使得元素脱离 normal flow 而存在, 分别是 float,absolute ,fixed, 但是在 IE6 中浮动元素也存在于 normal flow 中.
一, position: static
MDN 的描述:
该关键字指定元素使用正常的布局行为, 即元素在文档常规流中当前的布局位置. 此时 top,right,bottom,left 属性无效.
个人补充: static 是 position 的默认值.
- <!DOCTYPE html>
- <html lang="en">
- <head>
- <meta charset="UTF-8">
- <title>CSS-position-static</title>
- <link rel="stylesheet" href="https://cdn.bootcss.com/normalize/8.0.0/normalize.css">
- <style>
- .container{
- background-color: #868686;
- width: 100%;
- height: 300px;
- }
- .content{
- background-color: yellow;
- width: 100px;
- height: 100px;
- position: static;
- left: 10px;/* 这个 left 没有起作用 */
- }
- </style>
- </head>
- <body>
- <div class="container">
- <div class="content">
- </div>
- </div>
- </body>
- </html>
对 content 的 position 设定 static 后, left 就失效了, 而元素 (content) 就以正常的 normal flow 形式呈现.
二, position: relative
MDN 的描述:
该关键字下, 元素先放置在未添加定位时的位置, 再在不改变页面布局的前提下调整元素位置(因此会在此元素未添加定位时所在位置留下空白).position:relative 对 table-*-group, table-row, table-column, table-cell, table-caption 元素无效.
个人理解: 相对于 normal flow 中的原位置来定位.
- <!DOCTYPE html>
- <html lang="en">
- <head>
- <meta charset="UTF-8">
- <meta name="viewport" content="width=device-width, initial-scale=1.0">
- <meta http-equiv="X-UA-Compatible" content="ie=edge">
- <title>CSS-position-relative</title>
- <link rel="stylesheet" href="https://cdn.bootcss.com/normalize/8.0.0/normalize.css">
- <style>
- .container{
- background-color: #868686;
- width: 100%;
- height: 300px;
- }
- .content_0{
- background-color: yellow;
- width: 100px;
- height: 100px;
- }
- .content_1{
- background-color: red;
- width: 100px;
- height: 100px;
- position: relative;/* 这里使用了 relative */
- }
- .content_2{
- background-color: black;
- width: 100px;
- height: 100px;
- }
- </style>
- </head>
- <body>
- <div class="container">
- <div class="content_0">
- </div>
- <div class="content_1">
- </div>
- <div class="content_2">
- </div>
- </div>
- </body>
- </html>
- position: relative
这是没有设置 left,top 等属性时, 正常出现在 normal flow 中的位置.
接着添加 left,top:
- .content_1{
- background-color: red;
- width: 100px;
- height: 100px;
- position: relative;/* 这里使用了 relative */
- left: 20px;/* 这里设置了 left 和 top */
- top: 20px;
- }
可以看到, 元素 (content_1) 的位置相对于其原位置 (normal flow 中的正常位置) 进行了移动.
三, position: absolute
MDN 的描述
不为元素预留空间, 通过指定元素相对于最近的非 static 定位祖先元素的偏移, 来确定元素位置. 绝对定位的元素可以设置外边距(margin), 且不会与其他边距合并.
个人理解: 生成绝对定位的元素, 其相对于 static 定位以外的第一个父元素进行定位, 会脱离 normal flow. 注意: 是除了 static 外
- <!DOCTYPE html>
- <html lang="en">
- <head>
- <meta charset="UTF-8">
- <meta name="viewport" content="width=device-width, initial-scale=1.0">
- <meta http-equiv="X-UA-Compatible" content="ie=edge">
- <title>CSS-position-static</title>
- <link rel="stylesheet" href="https://cdn.bootcss.com/normalize/8.0.0/normalize.css">
- <style>
- .container{
- background-color: #868686;
- width: 100%;
- height: 300px;
- margin-top: 50px;
- }
- .content{
- background-color: red;
- width: 100px;
- height: 100px;
- position: absolute;
- top: 10px;
- }
- </style>
- </head>
- <body>
- <div class="container">
- <div class="content">
- </div>
- </div>
- </body>
- </html>
- position: absolute
因为 content 的父元素 container 没有设置 position, 默认为 static, 所以找到的第一个父元素是 body(<body></body>), 可以看成是元素 (content) 相对于 body 向下移动 10px.
四, position: fixed
MDN 的描述
不为元素预留空间, 而是通过指定元素相对于屏幕视口 (viewport) 的位置来指定元素位置. 元素的位置在屏幕滚动时不会改变. 打印时, 元素会出现在的每页的固定位置. fixed 属性会创建新的层叠上下文. 当元素祖先的 transform 属性非 none 时, 容器由视口改为该祖先.
个人理解: fixed 相对于 window 固定, 滚动浏览器窗口并不会使其移动, 会脱离 normal flow.
- <!DOCTYPE html>
- <html lang="en">
- <head>
- <meta charset="UTF-8">
- <meta name="viewport" content="width=device-width, initial-scale=1.0">
- <meta http-equiv="X-UA-Compatible" content="ie=edge">
- <title>CSS-position-static</title>
- <link rel="stylesheet" href="https://cdn.bootcss.com/normalize/8.0.0/normalize.css">
- <style>
- .container{
- background-color: #868686;
- width: 100%;
- height: 1000px;
- }
- .content{
- background-color: yellow;
- width: 100px;
- height: 100px;
- position: fixed;/* 这里使用了 fixed */
- }
- </style>
- </head>
- <body>
- <div class="container">
- <div class="content">
- </div>
- </div>
- </body>
- </html>
- position: fixed
这里就不上图了, 看一下代码或者自己动手码一下就能理解.
五, position: sticky
MDN 的描述
盒位置根据正常流计算 (这称为正常流动中的位置), 然后相对于该元素在流中的 flow root(BFC) 和 containing block(最近的块级祖先元素)定位. 在所有情况下(即便被定位元素为 table 时), 该元素定位均不对后续元素造成影响. 当元素 B 被粘性定位时, 后续元素的位置仍按照 B 未定位时的位置来确定. position: sticky 对 table 元素的效果与 position: relative 相同.
因为各大浏览器对于 sticky 的兼容问题, 而且 JS 也可以实现这个功能, 在这里就不进行深入了, 了解一下就好.
六, position: inherit
http://www.w3school.com.cn/cssref/pr_class_position.asp 的 描述
规定应该从父元素继承 position 属性的值.
inherit 继承父元素, 这个用得不多, 所以也不继续深入了.
来源: https://www.cnblogs.com/guolao/p/9048308.html