DDR爱好者之家 Design By 杰米

一、定位基本原理

对于前端开发工程师来说,编写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(>﹏<)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>  

在浏览器中显示的布局大致是:
CSS的position属性完全解析

代码中,使用了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>  

CSS的position属性完全解析

但是,当块级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>  

CSS的position属性完全解析

注意观察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>  

CSS的position属性完全解析

在水平方向上的对齐:

行内框宽度总和小于包含框的宽时,水平方向的对齐取决于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节点的影响,其他任何节点都不会影响它

DDR爱好者之家 Design By 杰米
广告合作:本站广告合作请联系QQ:858582 申请时备注:广告合作(否则不回)
免责声明:本站资源来自互联网收集,仅供用于学习和交流,请遵循相关法律法规,本站一切资源不代表本站立场,如有侵权、后门、不妥请联系本站删除!
DDR爱好者之家 Design By 杰米

《魔兽世界》大逃杀!60人新游玩模式《强袭风暴》3月21日上线

暴雪近日发布了《魔兽世界》10.2.6 更新内容,新游玩模式《强袭风暴》即将于3月21 日在亚服上线,届时玩家将前往阿拉希高地展开一场 60 人大逃杀对战。

艾泽拉斯的冒险者已经征服了艾泽拉斯的大地及遥远的彼岸。他们在对抗世界上最致命的敌人时展现出过人的手腕,并且成功阻止终结宇宙等级的威胁。当他们在为即将于《魔兽世界》资料片《地心之战》中来袭的萨拉塔斯势力做战斗准备时,他们还需要在熟悉的阿拉希高地面对一个全新的敌人──那就是彼此。在《巨龙崛起》10.2.6 更新的《强袭风暴》中,玩家将会进入一个全新的海盗主题大逃杀式限时活动,其中包含极高的风险和史诗级的奖励。

《强袭风暴》不是普通的战场,作为一个独立于主游戏之外的活动,玩家可以用大逃杀的风格来体验《魔兽世界》,不分职业、不分装备(除了你在赛局中捡到的),光是技巧和战略的强弱之分就能决定出谁才是能坚持到最后的赢家。本次活动将会开放单人和双人模式,玩家在加入海盗主题的预赛大厅区域前,可以从强袭风暴角色画面新增好友。游玩游戏将可以累计名望轨迹,《巨龙崛起》和《魔兽世界:巫妖王之怒 经典版》的玩家都可以获得奖励。