CSS定位与布局:普通流

CSS 定位与布局属于CSS的基础,也是CSS布局影响很大的一部分,具体主要包括三种定位与布局机制Positioning schemes ):普通流,浮动,绝对定位。
其实除了这三种之外,还有一些定位机制,但是这三种可以说在网站的应用是最多的,随便打开一个网站搜索一下这些属性,少则出现几十次,多则上百,官方文档也有对这三个属性的辨析< Comparison of normal flow, floats, and absolute positioning>,这篇博文很多内容是受  葵中剑@剑空 前辈的博文 CSS定位机制之一:普通流 的启发,在此感谢前辈的博文分享。
 
CSS定位与布局:普通流
 
官方文档介绍:
 
In CSS 2.1, a box may be laid out according to three positioning schemes:
1.  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.
2.  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.
3.  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.
 
普通流( normal flow )
标准里的定义:Normal flow. In CSS 2.1, normal flow includes block formatting of block boxes, inline formatting of inline boxes, relative positioning of block or inline boxes, and positioning of run-in boxes.(这个属于CSS3新定义的属性,还未去了解)

即普通流包括:块格式化( block formatting ),行内格式化( inline formatting ),相对定位(relative positioning ),以及 run-in boxes(CSS3)的定位。

任何被渲染的元素都属于一个 box ,并且不是 block ,就是 inline 。在普通流中的 Box(框) 属于一种 formatting context(格式化上下文) ,类型可以是 block ,或者是 inline ,但不能同时属于这两者。并且, Block boxes(块框) 在 block formatting context(块格式化上下文) 里格式化, Inline boxes(块内框) 则在 inline formatting context(行内格式化上下文) 里格式化。即使是未被任何元素包裹的文本,根据不同的情况,也会属于匿名的 block boxes 或者 inline boxes。

普通流过程:
1、block formatting context:块级元素按照在HTML中的顺序,在容器框中从左到右,从上到下依次分配空间,每个块级元素独占一行,margin属性决定相邻inline-block元素距离,同一个BFC中的垂直边界被重叠(collapse)。其中,浮动的块级元素会有inline-block元素的一些表现,具体将在float定位中细讲。
 
2、inline formatting context:行内元素在容器框中的顶端开始水平排布,这里有必要说明下margin,padding,border的不同表现。
 
------------------------------------------------------举个栗子---------------------------------------------------
HTML:
1 <div class="container">
2      <a class="inlineEle" href="#">inline element</a>
3      <a class="inlineEle" href="#">inline element</a>
4 </div>
CSS:
.container{
    border: 1px solid #000;
}
.inlineEle {
    background-color: #bbb;
    border: 10px solid #000;
    margin: 10px;
    padding:20px;
    height: 100px;
    width: 300px;
}
chrome,firefox,opera,IE8+表现如下:
 
IE6,IE7下的表现:
 
IE6,IE7下,当容器框加了height:100px后内联元素高度变为line-height,其他部分被截掉了:
margin:水平的margin有效,但是垂直的margin不影响高度,或者说无效。
border:border的有兼容性问题,chrome,firefox,opera,IE8+下会表现出所有边框,但是垂直方向的border虽然出现了但是,并不能撑开容器框,当容器框设置overflow:hidden的时候会被hidden掉。在IE6,IE7下垂直方向的border已经不见了。其实IE5我也出于好奇测试了一下,发现居然表现和chrome等一样,实在是匪夷所思。不过IE5已经不在我的考虑之内了。
padding:padding均能表现,但是同样垂直方向的padding也无法撑开容器框,当容器框设置overflow:hidden的时候也会被hidden掉。
width,height:对于行内元素无效。
-----------------------------------------------------吃完栗子-----------------------------------------------------
 
一个水平行中的所有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无法截断,如单词过长或者指定不换行,则会溢出容器。
 
3、对block box和inline box进行相对定位(position:relative),即相对于已排布的位置进行偏移,元素基于普通流的排布空间依然保留。
 
普通流中有一个比较重要的概念,即Formatting context。Formatting context是W3C CSS2.1规范中的一个概念。它是页面中的一块渲染区域,并且有一套渲染规则,它决定了其子元素将如何定位,以及和其他元素的关系和相互作用。
 
最常见的 Formatting context 有 Block fomatting context (简称BFC)和 Inline formatting context (简称IFC)。 
CSS2.1 中只有BFC和IFC, CSS3中还增加了GFC和FFC。下面只讲 BFC,IFC有机会再补充。
 
Block fomatting context 的创建:
  1. 根元素
  2. float属性不为none
  3. position为absolute或fixed
  4. display为inline-block, table-cell, table-caption, flex, inline-flex
  5. overflow不为visible
注:
1、 CSS level 3 specification中,BFC(CSS3中用 "flow root" 表示)在以下情况中可以建立:position 的值不为 “static” 或者 “relative” ,即 fixed 也能建立BFC,但其实fixed算是 absolute positioning 的一个子集,在规范中引用一个绝对定位的元素(或他的box模型)意味着该元素的 “position” 属性值 “absolute” 或 “fixed”,因此在CSS2.1 中使用这个值也会触发 BFC ,只是在 CSS3 中更加明确了这一点。
2、display:table 本身并没有建立BFC,但是它能够产生匿名框,匿名框(display:table-cell)才会建立BFC。
即使两种样式都建立了BFC(隐式或显式),clear 属性作用在 display:table 和 display:table-cell 是不一样的。
3、fieldset元素也能触发BFC。www.w3.org上并没有对它的表现的描述,直到HTML5的规范中才有。有一些浏览器bugs(Webkit,Mozilla)提到过,但是都不是官方声明的。参考文章的作者 Thierry Koblentz认为:即使fieldsets在大多数浏览器中都能建立BFC,也是不推荐的,CSS2.1中没有定义该属性应用于表单控件和框架,或者如何用CSS添加样式,用户代理可能可以为其提供CSS样式属性。故应该把这种支持作为实验性质的,未来版本的CSS可能会明确支持。
 
Block fomatting context 的作用与影响:
  1. 在同一个BFC中,boxes会在垂直方向,从一个containing block的顶部一个接一个放置,兄弟 boxes 的垂直距离由 ”margin“ 值决定。相邻 block boxes 的垂直 margin 会折叠(CSS2.1 8.3.1 Collapsing margins)。
  2. 在同一个BFC中,每一个 box 的左外边缘与 containing block 左边缘接触(从右到左的格式化则是右边缘接触)。即使是浮动元素(虽然一个box的line boxes会因为浮动元素而收缩),除非 box 建立一个新的BFC(会因为和浮动元素接触而收缩)。
  3. BFC 使在同一个BFC中的相邻 block boxes 的垂直margin值不会折叠。
  4. BFC能够包含浮动元素。
  5. BFC区域不会与浮动元素重叠。
  6. 计算BFC的高度时,浮动元素也参与计算。(CSS2.1 10.6.7 'Auto' heights for block formatting context roots 
  7. BFC就是页面上的一个隔离的独立容器,容器里面的子元素不会影响到外面的元素。反之也如此。
因为BFC内部的元素和外部的元素绝对不会互相影响,因此, 当BFC外部存在浮动时,它不应该影响BFC内部Box的布局,BFC会收缩而不与浮动有重叠。同样的,当BFC内部有浮动时,为了不影响外部元素的布局,BFC计算高度时会包括浮动的高度。避免margin重叠也是这样的一个道理。
 
-----------------------------------------------------举几个栗子说明一下-----------------------------------------------------
栗子一(BFC 使在同一个BFC中的相邻 block boxes 的垂直margin值不会折叠):
HTML:
<div class="container">
    <div class="collapsediv">同一个BFC中的div.1</div>
    <div class="collapsediv">同一个BFC中的div.2</div>
</div>
CSS:
.container {
    border: 1px solid #000;
    overflow: hidden;
    *zoom: 1;
}
.collapsediv {
    background-color: #ccc;
    width: 300px;
    height: 100px;
    margin: 50px;
}
注:这里的*zoom:1是对IE6的hack,涉及到IE的私有属性hasLayout 。
表现如下:
 
此时 div.1 的 margin-bottom 和 div.2 的 margin-top 重叠了,如果给下面的div.2包裹在触发了BFC的容器中,则div.1和div.2则属于不同的BFC,则margin不会折叠(此时如果在.warp元素上加padding-top或者border属性都可以使margin不重叠,效果和出发BFC相同。当然IE6、IE7除外 )。
修改后的HTML:
<div class="container">
    <div class="collapsediv_1">同一个BFC中的div.1</div>
    <div class="wrap">
        <div class="collapsediv_2">同一个BFC中的div.2</div>
    </div>
</div>
CSS:
.collapsediv{
    background-color: #ccc;
    width: 300px;
    height: 100px;
    margin: 50px;
}
.wrap {
    overflow: hidden;
    *zoom: 1;
}
.inlineEle {
    background-color: #bbb;
    border: 10px solid #000;
    margin: 10px;
    padding: 20px;
    height: 100px;
    width: 300px;
}
表现如下:
 
栗子二(BFC能够包含浮动元素+计算BFC的高度时,浮动元素也参与计算):
HTML:
<div class="container">
    <div class="floatdiv">浮动div.1</div>
    <div class="floatdiv">浮动div.2</div>
</div>
CSS:
.container {
    border: 2px solid #000;
}
 .floatdiv {
    background-color: #ccc;
    width: 100px;
    height: 50px;
    float: left;
    border:1px solid #666;
}
表现如下:
 
浮动元素脱离了普通流,使得容器框的高度变为0,此时为容器建立BFC就可以包含浮动元素,同时也说明此时计算容器框的高度时,浮动元素也参与计算。
修改后的CSS:
container {
    border: 2px solid #000;
    overflow: hidden;
    *zoom: 1;
}
表现如下:
 
注:除了创建 BFC,还可以用清除浮动的方法,需要留意的是用 clear 清除浮动只会清除同一个BFC中的浮动元素。
 
栗子三(BFC区域不会与浮动元素重叠)
HTML代码:
<div class="container">
    <div class="floatdiv">浮动div</div>
    <div class="nofloatdiv">不浮动div</div>
</div>
CSS:
.floatdiv {
    background-color: #ccc;
    float: left;
    height: 50px;
}
.nofloatdiv {
    background-color: #999;
    height: 100px;
}
.container {
    border: 1px solid #000;
    height: 150px;
}
 
 
在chrome,firefox,opera,IE8+表现如下:
 

IE7表现如下:

 
IE6表现如下,这里浮动和不浮动的div之间有3px的间距,这是IE6及以下版本独有的3px的bug:

修改CSS如下:
.nofloatdiv {
    background-color: #999;
    height: 100px;
    overflow: hidden;
    *zoom:1;
}
除了IE6表现不变外,其他浏览器(包括IE7)表现如下:
 
-----------------------------------------------------吃完栗子-----------------------------------------------------
 
除了IE6,IE7外,和浮动元素相邻的块元素建立BFC后,不会和浮动元素重叠。而IE6、IE7在加了height属性后其实就触发了IE的私有属性hasLayout,以及IE6还存在3px的bug,这都和IE的私有属性hasLayout有关。关于hasLayout,这是IE7及更低版本所有的一个IE私有属性,和BFC有些类似,是IE兼容性的一个罪魁祸首,关于这个属性有一篇很旧但是很详实的文章 On having layout(蓝色理想转载的中文翻译版本),原文: On having layout
 
BFC总结:
BFC 神奇背后的原理的总结个人觉得不错,很容易理解,也很容易记住。此处引用一下:
BFC就是页面上的一个隔离的独立容器,容器里面的子元素不会影响到外面的元素。反之也如此。
因为BFC内部的元素和外部的元素绝对不会互相影响,因此, 当BFC外部存在浮动时,它不应该影响BFC内部Box的布局,BFC会通过变窄,而不与浮动有重叠。同样的,当BFC内部有浮动时,为了不影响外部元素的布局,BFC计算高度时会包括浮动的高度。避免margin重叠也是这样的一个道理。
 
参考文档:
 
参考文章:
Thierry Koblentz  CSS 101:Block Formatting Contexts . 
 
感谢文章作者。
 
水平有限,错误欢迎指正。原创博文,转载请注明出处。

转载于:https://www.cnblogs.com/JuFoFu/p/4410030.html

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
本火锅店点餐系统采用Java语言和Vue技术,框架采用SSM,搭配Mysql数据库,运行在Idea里,采用小程序模式。本火锅店点餐系统提供管理员、用户两种角色的服务。总的功能包括菜品的查询、菜品的购买、餐桌预定和订单管理。本系统可以帮助管理员更新菜品信息和管理订单信息,帮助用户实现在线的点餐方式,并可以实现餐桌预定。本系统采用成熟技术开发可以完成点餐管理的相关工作。 本系统的功能围绕用户、管理员两种权限设计。根据不同权限的不同需求设计出更符合用户要求的功能。本系统中管理员主要负责审核管理用户,发布分享新的菜品,审核用户的订餐信息和餐桌预定信息等,用户可以对需要的菜品进行购买、预定餐桌等。用户可以管理个人资料、查询菜品、在线点餐和预定餐桌、管理订单等,用户的个人资料是由管理员添加用户资料时产生,用户的订单内容由用户在购买菜品时产生,用户预定信息由用户在预定餐桌操作时产生。 本系统的功能设计为管理员、用户两部分。管理员为菜品管理、菜品分类管理、用户管理、订单管理等,用户的功能为查询菜品,在线点餐、预定餐桌、管理个人信息等。 管理员负责用户信息的删除和管理,用户的姓名和手机号都可以由管理员在此功能里看到。管理员可以对菜品的信息进行管理、审核。本功能可以实现菜品的定时更新和审核管理。本功能包括查询餐桌,也可以发布新的餐桌信息。管理员可以查询已预定的餐桌,并进行审核。管理员可以管理公告和系统的轮播图,可以安排活动。管理员可以对个人的资料进行修改和管理,管理员还可以在本功能里修改密码。管理员可以查询用户的订单,并完成菜品的安排。 当用户登录进系统后可以修改自己的资料,可以使自己信息的保持正确性。还可以修改密码。用户可以浏览所有的菜品,可以查看详细的菜品内容,也可以进行菜品的点餐。在本功能里用户可以进行点餐。用户可以浏览没有预定出去的餐桌,选择合适的餐桌可以进行预定。用户可以管理购物车里的菜品。用户可以管理自己的订单,在订单管理界面里也可以进行查询操作。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值