在CSS编程中,相信很多人对于上面标题中的这些术语有很大的疑惑,接下来让我们一点点拨开它们的神秘面纱,以及纠正几个关键性的错误,通篇文章我就不提供图示了,我想能看到我这篇文章的人估计也对这些术语表现出来的图示已经很清楚了,这里就不再麻烦上图了。
在解释之前,首先说几本CSS的经典之作(要搞前台的人应该必读的):
1,Cascading Style Sheets Level 2 Revision 1 (CSS 2.1) Specification 这是最最权威的手册,是标准规范,可惜是英文的,实际上那些翻译人士完全可以出版一本这样的中文版。
2,CSS: The Definitive Guide, 3rd Edition,这是O'Reilly出的书,有中文版《CSS权威指南》,这本书不错的。
好了,我们开始进入我们的话题:
首先,我们来一段英语和语文知识,"The stream flow to the sea",翻译成中文:“溪流流向大海”。嗯,英文很好理解,stream:溪流,flow:流向。但是中文呢?“溪流”可以缩减成一个“流”字,那么这句话就成了“流流向大海”,晕了,2个流,连起来读读看“流流”。嗯,我说到这里,估计有些相当聪明的人马上醒悟到了,马上醒悟到困惑他多年的疑问解决了。嗯,困惑大家的原来是中文和英文的翻译歧义造成的,“流流”,第一个“流”是名词,翻译自stream,表示实实在在的内容,类似文件流(编程的人最熟悉这个了,文件操作么太重要了,什么InputStream,OutputStream)。第二个“流”是动词,翻译自flow,表示“流向”。
搞明白了“流”的关键以后,接着让我们再继续挖掘下去:
the normal flow of the document,让我们好好翻译这句话:文档的正常流向。嗯,这个时候最最关键的问题来了,咱们中国人一向惜字如金,曾经在很小的时候,就给我们灌输中文的奥妙之处,比如”僧敲月门下“,到底是敲好呢,还是推的好,字字斟酌过去。于是翻译上面一句话的时候,有些聪明人士就开始玩起中文的奥妙来了,翻译成了”文档的正常流“,嗯,这个还算是好的,更绝的是翻译成了”文档流“。嗯,我写到这里,相信所有的大家都应该明白了,问题原来出在这里。你翻译成了”文档流“了,误导了大家,因为”文档流“是名词,根据词面上的意思以及程序员的编程经历,理所应当的认为是文档的流内容了,倒翻过去,应该是document stream,一个英文单词的差别,意义可是千差万别了。至于翻译成”文档的正常流“也存在同样的问题,尽管比”文档流“稍微好点。
好了,搞明白了上面的翻译问题,让我们回到CSS Specification中,看看它是如何解释”文档的正常流向“(千万不要缩减成”文档流“哦,以后永远记住了)。
在http://www.w3.org/TR/CSS21/visuren.html#positioning-scheme中说道:
In CSS 2.1, a box may be laid out according to three positioning schemes:
- Normal flow. In CSS 2.1, normal flow includes block formatting of block-level boxes, inline formatting of inline-level boxes, and relative positioning of block-level and inline-level boxes.
- Floats. In the float model, a box is first laid out according to the normal flow, then taken out of the flow and shifted to the left or right as far as possible. Content may flow along the side of a float.
- Absolute positioning. In the absolute positioning model, a box is removed from the normal flow entirely (it has no impact on later siblings) and assigned a position with respect to a containing block.
让我这里稍微解释一下:(有些翻译上的细节我就不考虑了,大致意思不会出错即可)
一个box的布局满足3种定位模式:
1,正常流向:块级、行内、以及相对定位的那些元素。
2,浮动:首先根据正常流向布局,然后脱离正常流向(意思是:不再是正常流向了)浮动到左边或者右边,box内的剩余内容沿着这个浮动元素的周围布局。
3,绝对定位:box从正常流向中完全移除(意思是:和上面的float相比,就根本没有正常流向过)。
嗯,看到这里,大家就开始摇头了,这还是没有说明白啊,而且越说我越糊涂了。嗯,我知道你在想什么,呵呵。
上面这一段是为了解释”脱离(移除)文档正常流向“这个概念的,而不是解释”浮动、定位“这些具体含义的。再强调一下:”脱离(移除)文档正常流向“是指:不再是文档的正常流向了。和文档的流内容、空间没有任何关系。或者更直白一点说:不再是是文档的正常布局了,而是发生变化的布局。
举个例子说一下:一个div,没有任何样式的时候,属于”块级元素“,那么应该符合上面3种定位模式中的”正常流向“模式,假如给这个div加上float:left属性,那么 the div has been taken out of the normal flow of the document,也就是不再是正常流向了,那么属于什么啊?恩,只有3种模式,不属于正常流向,应该属于”浮动“这个模式。那么对于浏览器引擎来说,就采用”浮动“这种模式的渲染引擎来处理该div。
在css中有一个z-index属性,因为网页是“立体的”,它有z轴,这个z轴的大小就由z-index控制。默认情况下,所有页面元素均位于z-index:0这一层,而这一层顺序排列的元素就构成了“文档流”。无论是position还是float,它们都是通过改变文档流来实现定位。
css有三种基本的定位机制:文档流、浮动和绝对定位。除非专门指定,否则所有元素都在文档流中定位。也就是说,文档流中的元素的位置由元素在 X(HTML) 中的位置决定。css定位的基本思想很简单,它允许你使得元素相对于其正常应该出现的位置,或者相对于父元素、另一个元素甚至浏览器窗口本身的位置来进行定位。
CSS定位大致可以分成三类模型:普通流模型、浮动模型、和定位模型;
普通文档流:顾名思义,普通流中的元素的位置由在HTML中的位置决定,根据上下级和前后的顺序,一个一个的排列在界面上;当然根据元素的类型不一样,排列的方式会不一样,但先后顺序,显示层次关系不会改变;
一般在HTML元素分为两种:块级元素和行内元素。像div,p这些的元素属于块级元素;而span,strong等属于行内元素。块级元素是从上到下一行一行的排列,默认一个块级元素会占用一行,而跟在后面的元素会令起一行排列;行内元素是在一行中水平布置,从前到后的排列;如下面的css代码:
<div style="background-color:Blue" mce_style="background-color:Blue">我是块级元素,我单独占一行</div>
<div style="background-color:Yellow" mce_style="background-color:Yellow">我是块级元素,我一行一行的排列</div>
<span style="background-color:Green" mce_style="background-color:Green">我的行内元素,我水平的排列</span>
<span style="background-color:Gray" mce_style="background-color:Gray">我是行内元素,没有那么霸道</span>
(一)float:
float属性定位的元素位于z-index:0层。它是通过float:left和float:right来控制元素在0层左浮或右浮。float会改变正常的文档流排列,影响到周围元素。float元素在文档流中一个挨一个排列。但注意,只是float元素之间一个挨一个排列,对于非float的元素,float元素是视而不见的,会越过它们。
如下面的一段代码:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
|
<
html
>
<
head
>
<
style
type
=
"text/css"
>
.fl{float:left;background:red;border:solid 1px #00f;}
.nfl{background:#ff0;border:solid 1px #000;}
</
style
>
</
head
>
<
body
>
<
span
class
=
"fl"
>我是float元素1</
span
>
<
span
class
=
"nfl"
>我是非float元素</
span
>
<
span
class
=
"fl"
>我是float元素2</
span
>
<
span
class
=
"fl"
>我是float元素3</
span
>
</
body
>
</
html
>
|
概括来说,float:left时,会把非float元素挤到所有float元素的右边,float:right时是挤到左边。
(二)position:
position属性包括下面四个值:
- static(默认)
- 元素框正常生成。块级元素生成一个矩形框,作为文档流的一部分,行内元素则会创建一个或多个行框,置于其父元素中。
- relative
- 元素框偏移某个距离。元素仍保持其未定位前的框的形状,它原本所占的空间仍保留。
- absolute
- 元素框从文档流完全删除,并相对于其包含块定位。包含块可能是文档中的另一个元素或者是初始包含块。元素原先在正常文档流中所占的空间会关闭,就好像元素原来不存在一样。元素定位后生成一个块级框,而不论原来它在正常流中生成何种类型的框。
- fixed
- 元素框的表现类似于将 position 设置为 absolute,不过其包含块是视窗本身。
1. 静态(static):
元素顺序显示,在一个文档流中,一个挨着一个,但是不像relative那样可以设置top之类的。静态定位仅仅意味着内容遵循正常从上到下的HTML流。
2. 相对(relative):
一个相对定位的元素相对它在HTML流中的当前位置而放置。移动一个带有相对定位的元素,在该元素本该放置的地方留下了一个“洞”。相对定位的主要用处不是移动一个元素,而是给行内在它内部的绝对定位的元素设定一个新的参考点。
position: relative的元素相对于自己本来应该在的位置进行偏移,偏移后的位置可能覆盖别人(是漂浮在上方)。它原来的位置也空着,因为它会被加入到文档流中。
3. 绝对(absolute):
绝对定位让你通过以pixel、em、percentage来指定一个左、右、上或者下的位置来确定一个元素的位置。此外,绝对定位的元素被完全与页面流分离,换句话说,网页上的其他东西甚至不知道这个绝对定位的元素的存在。
absolute定位的一般用法:
- 如果一个标签有一个绝对的位置,并且它不在任何其他应用了absolute、relative或者fixed定位的标签里面,那么它是相对于页面(body元素)进行定位的。
- 如果一个标签处在另一个带有absolute、relative或者fixed定位的标签里面,那么它是相对于该元素的边界进行定位的。
4. 固定(fixed):
一个固定的元素被锁定在屏幕的位置上。fixed是相对浏览器窗口的固定位置定位,如网页中的“回到顶部”按钮。
注意:不要试图给同一个样式既应用float属性又应用任何一种定位,除了静态或者相对定位之外。浮动和绝对或者固定定位不可能同时作用在同一个元素上。
参考资料:
1. w3c school
2. 《CSS实战手册》
3. 《编写高质量代码——Web前端开发修炼之道》