微博客

一 前言

众所周知,HTML、CSS、JavaScript是所有网页技术的基础与核心。HTML 是语义,CSS是控制信息,JavaScript是逻辑、动态。HTML定义了大量标签并赋予各个标签以特定的含义及默认的显示方式,例如 <img> 标签代表图片元素;而CSS控制着这些标签如何呈现出来 ,及通常所说的渲染,如各个标签的位置和层。JavaScript 是一种动态语言,有了HTML和CSS后,网页仍只是静态的,如何动态的操作这些标签?当前这由JavaScript 完成, 但不排除后面出现新的语言,或者JavaScript的变体。

本文档将介绍CSS2.1规范及其在WebKit中的实现。 下面给出本文档涉及的术语定义:

  • absolutely positioned:  absolute or fixed 定位,见规范9.6
  • positioned element: 除static定位外的元素,见规范  9.3.2
  • replaced element,  该元素的内容(如何渲染该元素)不由CSS  规范描述,即该元素的外观、尺寸等由外部资源确定,如 HTML 的<img>元素; replaced element 通常有 src属性 , “intrinsic”width/height, 见规范 3.1
  • stack context:  层叠上下文

       

二 CSS 规范

2.1 Box Model

2. 1 Controlling box

由上知,在网页渲染过程中,每个元素都会被当做box来排版。在CSS 2.1 中定义了三类box, 由display 属性指定:

  1. block box, 垂直方向layout
  2. inline box, 水平方向 layout
  3. run-in box , run-in box 是比较特殊的box,遵循如下规范:

           1.  如果 run-in box 包含 block box,那么这个 run-in box 也成为 block box 

           2.如果紧跟在 run-in box 之后的兄弟节点是 block box,那么这个 run-in box 就会做为此 block box 里的 inline boxrun-in box 不能进入已经一个已经以 run-in box 开头的块内,也不能进入本身就是 display:run-in; 的块内

         3. 否则,run-in box 成为 block box  不过WebKit 并不严格遵循run-in box模型。 html 标签元素究竟产生block box 还是inline box 取决于如下两个因素:

  1. 标签本身
  2. css的display 属性

在HTML 规范定义了Block element 、inline element, 一般具有如下区别:

  • block-level elements generally can contain text, data, inline elements, or other block-level elements.
  • block-level elements generally begin new lines of text.
  • block-level elements inherit directionality information differently from inline elements.

如,div 标签为block-level element, <a>为inline-level 元素, http://htmlhelp.com/reference/html40/block.html 给出了所有的block-level element, http://htmlhelp.com/reference/html40/inline.html 给出了所有的inline-level element。

回到html 标签元素究竟产生block box 还是inline box的话题,一般情况下block-level 产生block box, inline-level 元素产生inline box。 但是,这可以通过 css的display改变。

display 属性的使用见http://www.w3school.com.cn/css/pr_class_display.asp

2.3 定位

根据2.1、2.2,每一个元素处理成一个box,但如何安排所有的box,确定每个box的位置? 这就是定位(position)。一般定位的过程分为如下几步:

  • 首先需要确定参考坐标系;
  • 其次根据参考坐标,确定其定位算法
  • 计算位置信息

css的定位机制也不例外。

2.3.1 containing box

containing box就是定位过程中的参考系。 在CSS 2.1 的 9.2.1、10.对containing box 有相关介绍。 在CSS 2.1中, 许多box 的位置和尺寸都根据一个规则的矩形box的边缘来确定,这个规则的矩形box就是containing box。 一般来说,generated boxes对其后代boxes承担containining box的作用;对其,我们认为该box对其后代extablishes containing box 。 ‘a box’s containing box ’意味着 该box 所live的 containing box 而不是其产生的 containing box。

containing box的确定过程如下:

    1. 用户代理(比如浏览器)选择根元素作为 containing block(称之为初始 containing block); 
    2. 对于其它元素,除非元素使用的是绝对位置,containing block 由最近的块级祖先元素盒子的内容边界组成;
    3. 如果元素有属性 ‘position:fixed’,containing block 由view port (视口)建立。 fixed 和absolute的区别
    4. 如果元素有属性 ‘position:absolute’,containing block 由最近的 position 不是 static 的祖先建立,按下面的步骤:

如果祖先是块级元素,containing block 由祖先的 padding edge 形成 (见box-model 图)

如果祖先是内联元素,containing block 取决于祖先的 direction 属性;

如果 direction 是 ltr(左到右),祖先产生的第一个盒子的上、左内容边界是 containing block 的上方和左方,祖先的最后一个盒子的下、右内容边界是 containing block 的下方和右方;

如果 direction 是 rtl(右到左),祖先产生的第一个盒子的上、右内容边界是 containing block 的上方和右方,祖先的最后一个盒子的下、左内容边界是 containing block 的下方和左方。

  • 如果没有祖先,根元素盒子的内容边界确定为 containing block。

  2.3.2 flow

CSS 用flow来代表定位算法。 当前包括: normal flow、float flow 和 absolutely flow,如下:

Normal Flow 是CSS 2.1规范中定义的,在一般通俗文档中被表述为“文档流”,是最重要的定位机制。 其通俗描述为 将窗体自上而下分成一行行,并在每行中按从左至右的顺序排放元素,即为文档流。在规范中如下定义:

  1. 任何被渲染的元素都是一Box, block box 或者 inline box,但不能同时属于这两类;
  2. Normal flow 定位过程包括 包括 block formatting context 、inline formatting context 、Relative positioning 三个过程;
  3. block formatting context:  块级元素按照其在HTML中的顺序,在其容器框里从左上角开始,从上到下垂直地依次分配空间、堆砌( stack ),并独占一行,边界紧贴父容器。两相邻元素间的距离由 margin 性决定,在同一个 block formatting context 中的垂直边界将被重叠( collapse )。并且,除非创建一个新的 block formatting context ,否则块级元素的宽度不受浮动元素的影响(这就是浮动元素能盖在块级元素上面的原因)
  4. inline formatting context: 行内元素从容器的顶端开始,一个接一个地水平排布。水平填充、边框和边距对行内元素有效。但垂直的填充、边框和空白边不影 响其高度。一个水平行中的所有 inline box 组成了名为 line box 的矩形区域。 line box 的高度始终容下所有的 inline box ,并只与行高有关。 line box 的宽度受到父容器和浮动元素存在的影响(这就是文本环绕浮动元素)。如果 line box 的宽度小于容器, line box 的水平排布就取决于 text-align 。如果 line box 的宽度大于容器,则截断 line box 并换行在新的 line box 中重新排布元素(截断处不应用 padding 和 margin 值)。如果 line box 无法截断,如单词过长或者指定不换行,则会溢出容器;
  5. elative positioning: 对这些 block box 和 inline box 进行相对定位,即相对于已排布的位置进行偏移。元素在其中保留原来所占用的空间

看到这里,读者可能会问,什么时候开始block formatting context,什么时候属于inline formatting context?  下面的这些情况,将会创建一个新的 block formatting context

  • 根元素
  • 浮动或绝对定位的元素
  • display 值为 inline-blocks , table-cell 或 table-caption
  • overflow 值为非 visible

     当block-level box作为block containing box时,见2.3.1,其可能仅仅包括其他的block box ; 或者创建新的 inline formatting context, 此时,其内只能包括inline boxes。 因此,block box 内要么只有其他的block box,要么只有 inline box,不能同时拥有,(如果其内既包括inline和block元素时,将产生匿名box以确保上述条件形成),也就是说,当只有inline box时将创建 inline formatting context。下面是Normal Flow的三个特性:
1、默认情况下,相邻的文档元素根据先后顺序从左到右,从上到下,按照 display 属性来布局元素(分行或不分行);
2、脱离Normal Flow 的元素:定位属性 position 的属性值为 absolute、fixed 的元素会脱离Normal flow
3、如果元素没有定义高度,元素所包含的内容会把元素撑开,但是脱离Normal Flow 的元素不会占据父元素的布局空间因此无法撑开父元素高度,浮动元素仍占据父元素的布局空间,但无法撑开父元素的高度接下来看看Floatflow,float元素定义元素浮动到左侧或右侧,以往这个属性一般应用于图像,使文字围绕在图像周围,有如下几个要点。

*  浮动元素的布局是基于的,不会完全脱离normalflow

*  浮动元素将按 inline-block 形式布局(haslayout),即使将他设置为 display:inline;

* 浮动元素仍占据父元素的布局空间,但无法撑开父元素的高度

最后看看 absolute 和fixed 定位。 这两类元素定位的算法是一样的,区别只在于确定其containing box的方式

不一样,见2.3.1.由上面知 absolute/fixed 元素从normalflow中完全脱离出来,确定新的block formatting context,其子元素或子absolute/fixed元素将按照一般的Normalflow进行定位;An absolutely positioned box extablishes a new containing block fornormalflowchildren and absolutely (but not fixed) positioned descendats.。

2.3.3 display float 和position 的关系

  • 浮动元素的布局是基于Normal flow的,不会完全脱离Normal flow
  • 如果 display 的值为none, 则忽略position与float, 这种情况下, 元素不产生box
  • 否则,  当positon为absolute时,float的属性就会失效,display的属性 参考下表,从下表知道,inline-table 变成table,其他都会变成block,即即使是inline成为block。
  • 当float为left或right时, display参考下表,由表知道,无论是否设置display:block,浏览器都会当成block来处理。
  • 浮动元素对自身的影响:浮动元素将按 inline-block 形式布局(haslayout),即使将他设置为 display:inline;

 

2.3.4 其他

1. inline boxes 中包括 block boxes的情况: 当inline box中包含 block box时, 该inline (和它在同一个inline box中的 inline 祖先一起)被该block box 打破,inline box 被拆分成2个inine box,两个 inline box 处于block box的两头;前后两个inline boxx都将各自产生一个anonymous block box ,产生的anonymous block box 跟先前的block box 相邻。如果该inline box 是相对定位,则对该inline box的任何 “平移”(偏移)结果都将影响了该inline box内的block box。

2.4  分层

2.3节定位决定了每个元素的(x,y)位置,但是如何显示呢? 元素(x,y)出现重叠时怎么处理呢? 这就是本节提到的分层的主题。把网页看成一个立体结构,定位决定了其x-y坐标,显然还缺z坐标。 这可通过css 的z-index属性指定。 z-index : 仅仅应用于positioned elements (即除static外的元素),想想为什么? 思考什么情况下才会出现重叠? 。

使用如下:

z-index="integer/auto", integer是生成box在当前层叠上下文中(stack context)的层叠级别,越打层级越高; 如果为auto,则生成box在当前层叠上下文中的层叠级别和它的父box相同,因此不会产生新的层。

stack contex ,层叠上下文:

css 层叠的结构,涉及层叠上下文,层叠上下文是一个抽象的容器,它可以包含层,也可以包含其子元素创建的层叠上下文。在层叠上下文内部,各层按照规则在 Z 轴方向上从后向前排列。从一个父层叠上下文的角度来看,层叠上下文本身是其中一个不可分割的最小单位;其他层叠上下文中的框,不可 能出现在它里面的框的中间位置。 也就是说,层叠上下文本身被看作一个单独的层处理,它在 Z 轴上的顺序与其子层无关。在给定的层叠上下文中,每个元素都有一个整型的层叠级别,它描述了在相同层叠上下文中元素在“Z轴”上的显示顺序。同一个层叠上 下文中,层叠级别大的显示在上,层叠级别小的显示在下,相同层叠级别的框会根据文档树中的位置,按照前后倒置的方式显示。根元素形成根层叠上下文。其他层 叠上下文由任何 ‘z-index’ 计算后的值不是 "auto" 的定位元素生成。不同层叠上下文中,元素显示顺序以父级层叠上下文的层叠级别来决定显示的先后顺序。与自身的层叠级别无关。

层叠上下文的构成:

每个层叠上下文都有如下的层组成(显示顺序从后到前):

  1. 形成层叠上下文的元素的背景和边框
  2. 层叠级别为负值的后代层叠上下文
  3. 常规流内非行内非定位的子元素组成的层
  4. 非定位的浮动子元素和它们的内容组成的层
  5. 常规流内行内非定位子元素组成的层
  6. 任何 z-index 是 auto 的定位子元素,以及 z-index 是 0 的层叠上下文组成的层
  7. 层叠级别为正值的后代层叠上下文

示意图:

细节请参考: http://www.w3help.org/zh-cn/kb/013/ 

2.5  Visual effets

如何控制元素是否可见?元素溢出(overflow)时如何显示?这牵涉到 overflow、clipping、visibility属性。

  • overflow: 应用于 non-replaced block-level elements, table cells and inline-block elements
  • clip:  应用于 absolutely positioned elements (absolutely and fixed),设置可见区域,思考为什么只用于absolutely positioned elements?
  • visibility: 应用于 all elements ,即使为hidden 也参与layout (display:none 的元素才不参与 layout)

下表是overflow的取值:

下表是clip的取值:

下表是visibllity的取值:

2.6 CSS尺寸表示

css尺寸表示包括绝度度量和相对度量,如下: 

三 总结

CSS 主要究竟都包括哪些呢? 下图做了简单总结: 

介绍就到这了,留下几个问题:

  • CSS究竟是什么? CSS每个规则应用的主要场景是什么,例如float?
  • 其Noraml flow 为什么这么设计? 优点是什么?缺点是什么?
  • CSS的改变什么情况下容易导致重新layout,从而影响性能? 如何避免?
  • 元素如何应用css?css的优先级如何确定? 这类代码应如何写效率比较高?
  • CSS 绘制时,是根据分层来逐层绘制吗? 分层在什么情况下产生?分层跟layout有什么关系?
  • CSS的排版机制跟其他排版机制的区别? 例如GUI中控件位置, book的排版,word等。
  • 你最希望CSS 还具备什么功能? 哦,看CSS3吧?!

四 参考文献

https://developer.mozilla.org/en/CSS/Visual_formatting_model Visual formatting model

http://mattryall.net/blog/2008/08/css-layout-fundamentals-block-and-inline-boxes CSS layout fundamentals, part 3: block and inline boxes

http://blog.sina.com.cn/s/blog_616a82920100yshb.html  Block Boxes VS Inline Boxes

http://www.w3help.org/zh-cn/kb/013/ 分层的显示( Layered presentation )

http://www.w3help.org/zh-cn/kb/008/  containing block

http://www.swordair.com/blog/2011/03/577/ Block-level Box & Block Container Box & Block Box

http://www.swordair.com/blog/2010/08/415/ CSS 普通流(Normal flow) (文档流)

http://www.cftea.com/c/2009/01/4ADRBHOD480VEFRW.asp   containing box

http://www.swordair.com/blog/tag/run-in-display/    CSS:displaty run-in

http://www.w3school.com.cn/css/pr_class_position.asp CSS position 属性

http://hi.baidu.com/smartcarlf/blog/item/8b23c404c8d425d27b89473d.html 元素布局中的 display 、position、float

 

摘自三生石畔的博客,原文链接已丢失

posted on 2013-05-20 18:07  飞鸟42  阅读(315)  评论(0编辑  收藏  举报