侯体宗的博客
  • 首页
  • Hyperf版
  • beego仿版
  • 人生(杂谈)
  • 技术
  • 关于我
  • 更多分类
    • 文件下载
    • 文字修仙
    • 中国象棋ai
    • 群聊
    • 九宫格抽奖
    • 拼图
    • 消消乐
    • 相册

CSS的position属性完全解析

前端  /  管理员 发布于 7年前   141

一、定位基本原理

对于前端开发工程师来说,编写CSS是前端开发工作中必不可少的一个内容,在CSS中的position属性又是非常重要的一个方面。顾名思义,所谓position,即是对HTML元素定位方式的一种设置。它是CSS定位技术的基石,看似很容易学习,很多的前端工程师也会说自己掌握得很好,但事实上是这样吗?作为一个在前端开发的道路上慢慢前行的新人,我不敢这么说,那么就通过这篇文章与大家一起,了解position的奥秘。

首先,既然是CSS中的属性之一,那么我们就有必要研究一下W3C的CSS文档,毕竟这才是对此属性说明最为详细的地方。在这里要插一句,目前市面上充斥着大量的教学书籍,网络上也有很多相关的学习资源,其中固然不乏精品,但是会花点时间,认真阅读官方文档的又有多少人呢,有的时候,最乏味的往往是最准确的。

好了,话不多说,官方文档中关于position属性的内容大致是这样的:

In CSS 2.1, a box may be laid out according to three positioning schemes:

1、Normal flow

2、Floats

3、Absolute positioning

1. 常规文档流。包括块级元素排版,行内元素排版以及对块级元素和行内元素相对位置的排版。

2. 浮动。在浮动模型中,元素先按照正常文档流定位,然后从文档流中移出,根据设置向左或者向右尽可能地移动。

3. 绝对定位。元素会完全从文档流中移出,再根据父元素进行定位。

一个元素如果是根元素,或者有浮动或绝对定位的话,那它就是在常规文档流之外的,其他情况都是在文档流之内。文档中有这么一句:The flow of an element A is the set consisting of A and all in-flow elements whose nearest out-of-flow ancestor is A. 有些绕,以我并不深厚的英语能力来翻译的话,应该是:元素A的flow是由元素A本身以及所有最近的文档流之外的父元素是A的流内元素所组成的。(翻译得太惨不忍睹了,求大神指点o(>n<)o)。

二、position属性详解

在CSS 2.1中,元素的定位方式是由position和display属性共同作用所决定的,我们先来看position属性

position属性的可取值:static | relative | absolute | fixed | inherit

默认值:static

每个值的意义:

static: 常规方式定位box,此时设置top, right, bottom, left属性是无效的。

relative: 元素本身的的位置的定位方式和static是一样的,但是实际位置会相对于原位置有所偏移,是通过top, right, bottom, left的设置实现的。注意:display设置为table-row-group, table-header-group, table-footer-group, table-row, table-column-group, table-column, table-cell和table-caption的元素是无法应用position: relative的,这也很好理解,这些表格类元素如果会相对于正常位置偏移的话不是很奇怪么!

absolute: 元素脱离文档流,“几乎”独立了。位置通过top, right, bottom, left来设置,当然,参照基点是包含元素的父元素~绝对定位的元素对相邻元素的定位没有任何影响,相互之间的层叠关系是通过z-index来设置的,同时,绝对定位元素的margin之间也不会发生折叠。

fixed: 这是个比较有趣的值。它的定位计算方式和绝对定位是一样的,但是也有不同。元素的位置一旦确定了,在屏幕显示器上,它会保持固定不动,在印刷媒体类型上,它会在每页出现在固定位置,在其他的媒体类型上,表现方式则没有定义。不过,如果希望一个box在屏幕和印刷媒体上的表现不同的话,可以使用@media rule的方式,例如:

CSS Code复制内容到剪贴板
  1. @media screen {   
  2.     h1#first { position: fixed; }   
  3. }   
  4. @media print {   
  5.     h1#first { position: static; }   
  6. }  

还有一个inherit值,不用多说,就是从父元素继承position值了。

三、定位方式:top, right, bottom, left

这四个属性其实可以放在一块儿说,其实是差不多的,只是定位的相对基线变了而已。文档上的说明有些铝耍还that's what official document is对吧?

可设定的值为:length, percentage, auto, inherit

不论设定的值为什么,意义都是元素的上右下左距离父元素的上右下左的边距。

这里要提一下auto值,对于非替换元素(non-replaced elements)和替换元素(replaced elements)auto的表现是不一样的,非替换元素指的是浏览器根据标签的元素和属性来判断具体显示的内容,如:

XML/HTML Code复制内容到剪贴板
  1. <input type="text" />  

这是一个文本输入框,换成其他的属性的话,浏览器的显示就会不一样。

替换元素的例子:

XML/HTML Code复制内容到剪贴板
  1. <p>I'm classicemi</p>  

(X)HTML的大多数元素都是非替换元素,他们将内容直接告诉浏览器,浏览器再显示出来。

下面回到auto上来,对于非替换元素,auto值的效果取决于哪些相关的属性同样具有auto值,比较难理解是吗,好的,我们给出下面的例子:

CSS Code复制内容到剪贴板
  1. <!DOCTYPE html>   
  2.  <html>   
  3.    <head>   
  4.      <title>A frame document with CSS 2.1</title>   
  5.      <style type="text/css" media="screen">   
  6.        body { height: 8.5in }   
  7.        #header {   
  8.          position: fixed;   
  9.          width: 100%;   
  10.          height: 15%;   
  11.          top: 0;   
  12.          rightright: 0;   
  13.          bottombottom: auto;   
  14.          left: 0;   
  15.        }   
  16.        #sidebar {   
  17.          position: fixed;   
  18.          width: 10em;   
  19.          height: auto;   
  20.          top: 15%;   
  21.          rightright: auto;   
  22.          bottombottom: 100px;   
  23.          left: 0;   
  24.        }   
  25.        #main {   
  26.          position: fixed;   
  27.          width: auto;   
  28.          height: auto;   
  29.          top: 15%;   
  30.          rightright: 0;   
  31.          bottombottom: 100px;   
  32.          left: 10em;   
  33.        }   
  34.        #footer {   
  35.          position: fixed;   
  36.          width: 100%;   
  37.          height: 100px;   
  38.          top: auto;   
  39.          rightright: 0;   
  40.          bottombottom: 0;   
  41.          left: 0;   
  42.        }   
  43.      </style>   
  44.    </head>   
  45.    <body>   
  46.      <div id="header"> ...  </div>   
  47.      <div id="sidebar"> ...  </div>   
  48.      <div id="main"> ...  </div>   
  49.      <div id="footer"> ...  </div>   
  50.    </body>   
  51.  </html>  

在浏览器中显示的布局大致是:

代码中,使用了auto的属性有: #header bottom, #sidebar right, #footer top. 而对于#main呢,它的height和width都是auto,也就是说main的长宽是自适应的,自动填充可用空间,这也就好理解了,所谓的auto,也就是使元素的上右下左距离能够根据相关联的,或者说共同父元素的子元素之间的关系自动调整。

四、Normal Flow

前面提到了很多次“常规文档流”,实际上也就是W3C文档中的Normal Flow,也可称为常规流。常规流的理解,主要围绕着两个方面,分别是格式化上下文(Formatting Context)和相对定位(Relative Positioning)。

格式化上下文,按照W3C文档的解释,分为Block Formatting Contexts(BFC)和Inline Farmatting Contexts(IFC),这里我觉得没有什么翻译成中文的必要了,因为如果我说“块级格式化上下文”的话,诸位能理解是什么意思吗,所以,叫BFC和IFC就挺好。

所谓BFC,文档上解释得挺拢虻ダ此担褪强榧box顺次垂直排列。当然也不能这么简单,原因是块级box的内部还会产生BFC,也就是说可以嵌套。

CSS Code复制内容到剪贴板
  1. <!DOCTYPE html>   
  2. <html>   
  3.     <head>   
  4.         <title>BFC</title>   
  5.         <meta charset="utf-8" />   
  6.     </head>   
  7.     <body>   
  8.         <div style="width: 400px; height: 300px; background: blue;">   
  9.             <div style="width: 200px; height: 100px; background: red;"></div>   
  10.             <div style="width: 100px; height: 150px; background: green;"></div>   
  11.         </div>   
  12.     </body>   
  13. </html>  

但是,当块级box内部都是行内box的时候,就不会产生BFC,而是产生IFC,但只要子元素中有一个块级box,就会产生BFC。Attention! 文档中指出,如果外层块级box的overflow: visible; 的话,不会产生BFC甚至IFC。

下面来看看IFC,IFC中包括文字以及行内元素,对于文字来说,排版实际上有很多名堂,尤其是对于英文字符,或者说字母类文本,如果各位对文字排版有兴趣的话,推荐各位一部视频教程,由美国著名IT教学网站lynda.com出品的网页设计排版视频教程《Typography.for.Web.Designers》,至于下载方法,这里就不多说了,相信大家各显神通都有办法。

如果在行内元素中同时包含文字的话,情况会比较复杂:

CSS Code复制内容到剪贴板
  1. <!DOCTYPE html>   
  2. <html>   
  3.     <head>   
  4.         <title>IFC</title>   
  5.         <meta charset="utf-8" />   
  6.     </head>   
  7.     <body>   
  8.         <div style="width: 400px; height: 300px; background: blue; overflow: visible;">   
  9.             <span style="font-size: 20px;">Something</span>   
  10.             <div style="display: inline-block; width: 200px; height: 100px; background: red;"></div>   
  11.         </div>   
  12.     </body>   
  13. </html>  

注意观察span和div的底部对齐差异。

行内框在行框垂直方向的对齐:

行框高度总是足够包含其容纳的所有框,它可能会高于它包含的最高的框。在这里会跟vertical-align属性相关:

vertical-align可能的取值:

baseline、sub、super、top、text-top、middle、bottom、text-bottom、length、%、inherit

举一个例子:

CSS Code复制内容到剪贴板
  1. <!DOCTYPE html>   
  2. <html>   
  3.     <head>   
  4.         <title>Vertical-align</title>   
  5.         <meta charset="utf-8" />   
  6.     </head>   
  7.     <body>   
  8.         <p style="background: grey; width: 600px;">   
  9.             <span style="font-size: 50px; border: 1px solid red;">hello</span>   
  10.             <span style="font-size: 30px; border: 1px solid green; vertical-align: top;">world</span>   
  11.         </p>   
  12.     </body>   
  13. </html>  

在水平方向上的对齐:

行内框宽度总和小于包含框的宽时,水平方向的对齐取决于text-align属性。

五、POSITION和OVERFLOW的关系
父节点设置overflow:scroll,但是不管滚动条如果滚动,但是子节点一直都不动。
当父节点不设置position情况下,子节点position的四种值的分析:
示例1.1:

CSS Code复制内容到剪贴板
  1. body{   
  2. A {overflow: scroll;}   
  3. A-1 {}   
  4. }  

效果:A-1会根据A滚动条的滚动而滚动
分析:A-1的默认position设置为static,当position为static时,A-1元素还是遵循正常的文档流,因此A-1会受它父节点属性的影响
示例1.2:

CSS Code复制内容到剪贴板
  1. body{   
  2. A {overflow: scroll;}   
  3. A-1 {position: relative;}   
  4. }  

效果:A-1会根据A滚动条的滚动而滚动
分析:当A-1的position设置为relative时,A-1元素还是遵循正常的文档流,因此A-1会受它父节点属性的影响
示例1.3:(重点)

CSS Code复制内容到剪贴板
  1. body{   
  2. A {overflow: scroll;}   
  3. A-1 {position: absolute;}   
  4. }  

效果:A-1不会根据A滚动条的滚动而滚动
分析:当A-1的position设置为absolute时,A-1元素脱离了文档流,所以A-1不再受父节点属性的影响
注意:这时在父节点没有设置position的时,只会受到body节点的影响
示例1.4:

CSS Code复制内容到剪贴板
  1. body{   
  2. A {overflow: scroll;}   
  3. A-1 {position: fixed;}   
  4. }  

效果:A-1不会根据A滚动条的滚动而滚动
分析:当A-1的position设置为fixed时,A-1元素脱离了文档流,这时A-1只受body元素的影响

当父节点设置position值为非static情况下,子节点position的四种值的分析:
示例2.1:

CSS Code复制内容到剪贴板
  1. body{   
  2. A {position:relative; overflow: scroll;}   
  3. A-1 {}   
  4. }  

效果:A-1会根据A滚动条的滚动而滚动
分析:跟示例1.1一样,当父节点A设置了position之后,子节点A-1还是遵循正常的文档流,因此A-1会受它父节点属性的影响
示例2.2:

CSS Code复制内容到剪贴板
  1. body{   
  2. A {position:relative; overflow: scroll;}   
  3. A-1 {position: relative;}   
  4. }  

效果:A-1会根据A滚动条的滚动而滚动
分析:跟示例1.2一样,当父节点A设置了position之后,子节点A-1还是遵循正常的文档流,因此A-1会受它父节点属性的影响
示例2.3:(重点, 注意跟1.3示例对比)

CSS Code复制内容到剪贴板
  1. body{   
  2. A {position:relative; overflow: scroll;}   
  3. A-1 {position: absolute;}   
  4. }  

效果:A-1会根据A滚动条的滚动而滚动
分析:当父节点A设置了position之后,效果就跟示例1.3不一样了,这时A-1会受到离它自己最近的一个设置了position属性的父节点的影响,再看下面一个示例:

CSS Code复制内容到剪贴板
  1. body{   
  2. A {position:relative; overflow: hidden;}   
  3. A-1 {overflow: scroll;}   
  4. A-1-1 {position: absolute;}   
  5. }  

注意:这时A-1-1不会收A-1的影响,但是会受到A的影响
示例2.4:

CSS Code复制内容到剪贴板
  1. body{   
  2. A {position:relative; overflow: scroll;}   
  3. A-1 {position: fixed;}   
  4. }  

效果:A-1不会根据A滚动条的滚动而滚动
分析:跟1.4示例一样,当子节点的position属性设置为fixed之后,不管的父节点是否设置了position值,都只会受到body节点的影响,其他任何节点都不会影响它


  • 上一条:
    CSS3绘制不规则图形的一些方法示例
    下一条:
    一波CSS高级实用技巧小结
  • 昵称:

    邮箱:

    0条评论 (评论内容有缓存机制,请悉知!)
    最新最热
    • 分类目录
    • 人生(杂谈)
    • 技术
    • linux
    • Java
    • php
    • 框架(架构)
    • 前端
    • ThinkPHP
    • 数据库
    • 微信(小程序)
    • Laravel
    • Redis
    • Docker
    • Go
    • swoole
    • Windows
    • Python
    • 苹果(mac/ios)
    • 相关文章
    • 使用 Alpine.js 排序插件对元素进行排序(0个评论)
    • 在js中使用jszip + file-saver实现批量下载OSS文件功能示例(0个评论)
    • 在vue中实现父页面按钮显示子组件中的el-dialog效果(0个评论)
    • 使用mock-server实现模拟接口对接流程步骤(0个评论)
    • vue项目打包程序实现把项目打包成一个exe可执行程序(0个评论)
    • 近期文章
    • 智能合约Solidity学习CryptoZombie第三课:组建僵尸军队(高级Solidity理论)(0个评论)
    • 智能合约Solidity学习CryptoZombie第二课:让你的僵尸猎食(0个评论)
    • 智能合约Solidity学习CryptoZombie第一课:生成一只你的僵尸(0个评论)
    • 在go中实现一个常用的先进先出的缓存淘汰算法示例代码(0个评论)
    • 在go+gin中使用"github.com/skip2/go-qrcode"实现url转二维码功能(0个评论)
    • 在go语言中使用api.geonames.org接口实现根据国际邮政编码获取地址信息功能(1个评论)
    • 在go语言中使用github.com/signintech/gopdf实现生成pdf分页文件功能(0个评论)
    • gmail发邮件报错:534 5.7.9 Application-specific password required...解决方案(0个评论)
    • 欧盟关于强迫劳动的规定的官方举报渠道及官方举报网站(0个评论)
    • 在go语言中使用github.com/signintech/gopdf实现生成pdf文件功能(0个评论)
    • 近期评论
    • 122 在

      学历:一种延缓就业设计,生活需求下的权衡之选中评论 工作几年后,报名考研了,到现在还没认真学习备考,迷茫中。作为一名北漂互联网打工人..
    • 123 在

      Clash for Windows作者删库跑路了,github已404中评论 按理说只要你在国内,所有的流量进出都在监控范围内,不管你怎么隐藏也没用,想搞你分..
    • 原梓番博客 在

      在Laravel框架中使用模型Model分表最简单的方法中评论 好久好久都没看友情链接申请了,今天刚看,已经添加。..
    • 博主 在

      佛跳墙vpn软件不会用?上不了网?佛跳墙vpn常见问题以及解决办法中评论 @1111老铁这个不行了,可以看看近期评论的其他文章..
    • 1111 在

      佛跳墙vpn软件不会用?上不了网?佛跳墙vpn常见问题以及解决办法中评论 网站不能打开,博主百忙中能否发个APP下载链接,佛跳墙或极光..
    • 2016-10
    • 2016-11
    • 2017-06
    • 2017-07
    • 2017-08
    • 2017-09
    • 2017-10
    • 2017-11
    • 2018-03
    • 2018-04
    • 2018-05
    • 2018-06
    • 2018-09
    • 2018-11
    • 2018-12
    • 2019-02
    • 2020-03
    • 2020-04
    • 2020-05
    • 2020-06
    • 2021-04
    • 2021-05
    • 2021-07
    • 2021-08
    • 2021-09
    • 2021-10
    • 2021-11
    • 2022-08
    • 2022-09
    • 2022-10
    • 2022-11
    • 2022-12
    • 2023-01
    • 2023-02
    • 2023-03
    • 2023-04
    • 2023-05
    • 2023-06
    • 2023-07
    • 2023-09
    • 2023-10
    • 2023-11
    • 2023-12
    • 2024-01
    • 2024-02
    • 2024-03
    • 2024-04
    Top

    Copyright·© 2019 侯体宗版权所有· 粤ICP备20027696号 PHP交流群

    侯体宗的博客