css定位规则

之前写前端总会发现自己css定位代码得不到预期效果,有时候甚至要费上好几个小时来解决一个小问题,但最后还是不清楚原理。于是决定要系统地学下定位。翻了四五天w3c的规范,发现定位规则实际上是非常复杂的,有些效果要触发所需的充分条件都有十几条,涉及n个概念,w3school教程里面的定位规则并不完全准确(那个网站部分内容让我觉得写的人并不精通定位规则)。同时也发现之前以为等价的几个概念实际上是独立的。以上两点便是之前一直觉得定位规则诡异的原因。

但是,全面地把这些规则学通很难,也完全没有必要。师兄们是靠经验写前端,久而久之自己会形成一套固定的定位写法,简单又可靠。因此,我只想尝试整理出一套系统而又精的定位知识,并且把自己做定位的套路记录下来。


元素生成框

首先应该明确几个概念和它们的关系。这些概念包括:元素element(inline 或者 block),框 box(inline 或者 block),框模型box model,块级框block-level box,内联级框inline-level box,  container box,包含块containing block , 块级格式化上下文 block formatting contexts,内联格式化上下文 inline formatting contexts 。里面有很多概念长得很像,但是有些是完全不同的!而且它们各自有独立的作用。我之前觉得定位规则诡异的主要原因就是简单把父级box和containing box简单看成是同一个概念。其实还有不少看似很像但是不一样的概念,像block box ,inline box ,这里略。(注意核对英文单词来确认是否为同一个概念)

下面来简单理一下这些概念之间的关系。在这之前,应当先理解element在文档树中的父子关系和框模型box model,这里略。

首先,可以粗略地认为,html文档中的 每一个元素element 会对应生成 一个在浏览器中真实可见的 框box,其模型为框模型box model。内联元素inline element 生成内联级框inline-level box,块级元素block element 生成 块级框block-level box。由于html文档中的元素间具有家族关系,因此元素生成的框也有家族关系。框之间的家族关系表现在父框包含子框。

w3c关于这点的原文为:Each block-level element generates a principal block-level box that contains descendant boxes and generated content and is also the box involved in any positioning scheme.Inline-level elements generate inline-level boxes, which are boxes that participate in an inline formatting context.


元素的家族关系 

(图片出自http://www.ddcat.net/blog/?p=216)


格式化上下文决定定位规则

那这些一个包着一个的框具体应该怎么定位呢?考虑定位不能离开三个概念:包含块containing block , 块级格式化上下文 block formatting contexts,内联格式化上下文 inline formatting contexts 。

Formatting contexts 是个不同于框的概念,准确来说是框产生formatting contexts。什么条件下框才会生成formatting context ,会生成哪种 formatting context,等下有讲。

考虑一个框会怎么定位,就要先考虑它在哪个formatting context中  还有  它和哪些框存在于同一个formatting context中。对于block formatting context(BFC).假设A框是B,D框的父框,B框是C框的父框,A促发条件生成了一个BFC。那么,B,C,D都同在A产生的BFC里面。但若B又促发条件,产生了新的BFC,那么 B,D在A产生的BFC里面,而C只在B产生的BFC中。(这个问题最切身的影响是外边距折叠和浮动,两个框产生外边距折叠有一个必要条件是,两个框处于同一个BFC中。)而对于inline formatting context(IFC),一个IFC里面所有内联级元素都处于该IFC中(不考虑嵌套)。而产生IFC的块级框会存在于一个BFC中。块级框只存在于BFC中,内联级框只存在于IFC中。

以下是生成formatting context的促发条件:

Block formatting contexts:浮动框,绝对定位框,inline-block 的内联级框 ,overflow属性不为visible的框都会生成一个新的block formatting context。

W3C原文:Floats, absolutely positioned elements, block containers (such as inline-blocks, table-cells, and table-captions) that are not block boxes, and block boxes with 'overflow' other than 'visible' (except when that value has been propagated to the viewport) establish new block formatting contexts for their contents.

Inline formatting contexts:block-level box 和 inline-block 的inline-level box 也是 container box(还是要注意不要把这和其他相似的概念混淆),container box 若只含内联级框,就生成inline formatting context,否则,只要含一个块级框,就不会生成新的formatting context,并且自动生成无名块级框把所有内联元素包起来。

W3C原文:Except for table boxes, which are described in a later chapter, and replaced elements, a block-level box is also a block container box. A block container box either contains only block-level boxes or establishes an inline formatting context and thus contains only inline-level boxes. Not all block container boxes are block-level boxes: non-replaced inline blocks and non-replaced table cells are block containers but not block-level boxes. Block-level boxes that are also block containers are called block boxes.

稍微总结一下:文档树中的每个element对应生成一个框。某些框促发条件生成formatting context。最后每个框都会在某个formatting context中。而生成规则使得BFC中全为块级框,IFC中全为内联级框。

有了formatting context,才能谈定位规则,因为定位规则实际上是由formatting context决定的。BFC对BFC中的框有一套定位规则,IFC对IFC中的框有另一套定位规则。简单来说,BFC中的每一个框各占一行(也就是我以前理解的块级框要换行),IFC中会尝试用一个行框尽可能多地把多个框包起来,放在一行里面显示(也就是我以前理解的内联级框会在同一行上显示)。详细:http://www.w3help.org/zh-cn/kb/010/


以包含块为基准算出定位结果

好了,以上规则规定了哪些框会在同一个上下文(formatting context)中,这影响了元素定位效果。但是要明确规定框究竟在哪个位置,靠上下文这个无形无具体位置的概念是不够的。

因此我们需要 包含块containing block 这个有固定区域有固定位置的概念来作为框定位的基准。首先应该明确,包含块不是框,更加不能简单理解为父级框(上个学期因为这个问题好多时间都哗哗流掉5555555555)。准确来说,包含块是网页上的区域。每个框都有它的 包含块containing block ,框的包含块的区域和位置总是比该框早确定下来,然后该框就可以 以包含块为基准,按照所在formatting context 对框规定的定位规则,明确得出框的位置了。

那框的包含块是怎么确定的,为什么框的包含块总是先与框确定下来?直接看下面两个图。(其实两张图讲的是一个内容)



图片来自http://www.w3help.org/zh-cn/kb/010/

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 202,802评论 5 476
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 85,109评论 2 379
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 149,683评论 0 335
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 54,458评论 1 273
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 63,452评论 5 364
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,505评论 1 281
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 37,901评论 3 395
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,550评论 0 256
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 40,763评论 1 296
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,556评论 2 319
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,629评论 1 329
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,330评论 4 318
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 38,898评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,897评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,140评论 1 259
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 42,807评论 2 349
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,339评论 2 342

推荐阅读更多精彩内容

  • 问答题47 /72 常见浏览器兼容性问题与解决方案? 参考答案 (1)浏览器兼容问题一:不同浏览器的标签默认的外补...
    _Yfling阅读 13,722评论 1 92
  • 先前在学习CSS float时,有同学提到了BFC这个词,作为求知好问的好学生,哪里不懂查哪里,那么今天就来研究一...
    这名字真不对阅读 6,542评论 3 19
  • 什么是BFC BFC全称是Block Formatting Context,即块格式化上下文。它是CSS2.1规范...
    陌客百里阅读 530评论 3 4
  • 转载自(http://web.jobbole.com/83274/) BFC BFC全称是Block Format...
    居客侠阅读 2,132评论 0 20
  • 1.解决margin叠加问题 三P每个p之间的距离为50px,发生了外边距叠加。 要解决这个叠加问题即让每个P之间...
    岁月帮凶ds阅读 498评论 1 0