w3c标准 - Css - (4)CSS定位方案

w3c标准 - Css - (4)CSS定位方案 


1. 定位之前看一下BFC


(1) 解释


        BFC(Block formatting context)直译为"块级格式化上下文"。它是一个独立的渲染区域,只有Block-level box参与, 它规定了内部的Block-level Box如何布局,并且与这个区域与外部毫不相干。

(2)布局规则


普通文档流布局规则

浮动的元素是不会被父级计算高度
非浮动元素会覆盖浮动元素的位置
margin会传递给父级
两个相邻元素上下margin会重叠

BFC布局规则

浮动的元素会被父级计算高度(父级触发了BFC)
非浮动元素不会覆盖浮动元素位置(非浮动元素触发了BFC)
margin不会传递给父级(父级触发了BFC)
两个相邻元素上下margin会重叠(给其中一个元素增加一个父级,然后让他的父级触发BFC)
每个元素的margin box的左边, 与包含块border box的左边相接触(对于从左往右的格式化,否则相反)。即使存在浮动也是如此
BFC就是页面上的一个隔离的独立容器,容器里面的子元素不会影响到外面的元素。反之也如此


(3)触发方式:


float的值不为none
overflow的值不为visible
display的值为table-cell,table-caption和inline-block之一
position的值不为static或者reletive的任何一个

根元素html


4)作用:可以从布局规则中分析


2. 普通流


        正常的文档流指的就是在不适用与排列和定位相关的特殊css规则时,各种元素的排列规则。在HTML里面的写法就是从上到下,从左到右的排版布局。每个非浮动块级元素都独占一行,从上到下排列, 内联元素则从左到右排列。

margin :下面分四种情况对普通流margin调整盒子的位置进行解说。


(1) 行内元素之间的水平margin


        当两个行内元素紧邻时,它们之间的距离为第一个元素的右margin加上第二元素的左margin。

(2) 块级元素之间的竖直margin


        两个竖直排列的块级元素,它们之间的垂直距离不是上边的第一个元素的下margin和第二个元素的上margin的总和,而是两者中的较大者。这在实际制作网页的时候要特别注意。

note: 计算方式(两个盒子之间的距离)

<h3>css normal flow - margin collapse</h3>
<div class="top">
	Top div content.
</div>
<div class="bottom">
	Bottom div content.
</div>
.top {
	height: 300px;
	width: 600px;
	background-color: #09a800;
	padding: 20px;
	margin: 30px;
	margin-bottom: 40px;
}

.bottom {
	background-color: #c6e48b;
	height: 300px;
	width: 600px;
	padding: 20px;
	margin: 30px;
	margin-top: 30px;
	opacity: 0.6;
}
为了看着清楚,我们将上面的div设置了一个透明度。

1): 均为正值 -> MAX(X, Y)

                                               

2): 一个正值,一个负值 -> X + Y

                                              

3): 两个均为负值 -> MIN(X, Y)

                                             

Note: CSS及浏览器的设计者们希望我们在布局时,如果遇到上下两个并排内容块的安排,最好只设置其中每个块上或下margin的一处即可.

(3) 嵌套盒子之间的margin


<h3>css normal flow - embedded margin</h3>
<div class="parent">
	<div class="child">
		child div content.
	</div>
</div>	
.parent {
	height: 400px;
	width: 600px;
	background-color: #09a800;
}

.child {
	background-color: #c6e48b;
	padding: 20px;
}

然后看一下在.child上加上margin-top:30px和不加的效果,可以在下图中看到存在高度差

                                        

question: 
        这里的问题是,我们操作的是子元素div,为什么子元素的上边框距父元素的上padding(因为我们这个地方没有设置padding,所以是距父元素的上边框)存在20px没有起到效果,反而是让整个父元素的block box向下移动了20px; 相当于是在父元素上加上了一个margin-top的属性。

answer:
        这个地方发生了盒子塌陷的情况,根据规范,一个盒子如果没有上补白(padding-top)和上边框(border-top),那么这个盒子的上边距会和其内部文档流中的第一个子元素的上边距重叠,这也就是上面情况出现的原因。

solution: 

1)  根据上面的原因,大家应该可以想到解决的方案最少有两个,加padding-top, border-top
我这个地方只是用padding-top进行,①使用border会破坏原先的布局,因为border毕竟是有宽度的,②对于块元素内部的话,与其第一个元素使用margin进行布局,为什么不适用父元素的padding进行呢,在我看来margin的使用还是同一个层级下的两个上下并列的块级元素应用更为恰当。

                                      

2) 父元素添加overflow:hidden
        关于这个后面会有提到。 第一张的内容可以知道,现在父级元素是一个BFC环境,所以不会随着子元素的margin问题产生偏移,这个BFC自己的特性。作为一个独立容器,所以这个容器一定是封闭的,所以就不存在上面出现的情况。

3) 子元素加上display: inline-block
        子元素已经是一个独立容器,就不会与父级元素的上边框重叠,而且BFC不会对外面的布局产生影响。

3. float 


(1) float属性

        定义元素朝哪个方向移动


(2)浮动层 

        给元素的float属性赋值后,就是脱离文档流,进行左右浮动,紧贴着父元素(默认为body文本区域)的左右边框。而此浮动元素在文档流空出的位置,由后续的(非浮动)元素填充上去:块级元素直接填充上去,若跟浮动元素的范围发生重叠,浮动元素覆盖块级元素。内联元素:有空隙就插入。


(3)层级关系

        首先看一下图片,层级顺序

                                      

(4) float: left


a. 块级元素float A: 紧跟着的兄弟元素为块级元素 B(不带有float属性)
 

summary: 相邻块级元素B会填充A的位置,并且发生重叠,具有float属性的A在上层。

b. 块级元素float A: 紧跟着的兄弟元素为内联元素B (不带有float属性)


        由于带有float属性之后的块级元素相当于inline-display,所以在当前html的BFC中,A相对于B而言是一个内联元素,所以他们之间的布局就是在A的box宽度之后继续布局,如果div的宽度沾满了浏览器,那B就会排到下一行,否则就紧跟着A元素。


c. 内联元素A: 紧跟着的兄弟元素为块级元素B (不带有float属性)


          从上面的图片可以看到给内联元素加上float元素,这个元素也变成了一个inline-block的元素,大家可以看到黄色框标注的width, height属性已经起了作用。而且可以看到B元素还是填充到了之前A元素的位置。

至于文字的移动,请看本人手动画的一个图: 



请看红色箭头的左边部分是div没有加上float的示例,对应上面图片的左边部分,从上面的层级顺序图中可以看出层级关系inline/inline-block盒子 > float盒子 > block盒子

为什么span在div的上方而没有在div的元素上?

        这个的原因在于,span的外侧有一个匿名的块级元素,所以文字的显示还是在包含文字的父级块级元素的范围内显示,除非在block盒子层和inline/inline-block盒子之间有浮动盒子,并且占用了所有的空间,这样居于上层文字只好移动到(float层)下一排了(后面有范例)。

        有一天,div不太爽,非要自己加一个float属性,然后与span在同一个区域内,然后我们在看箭头右边的部分,此时由于span加上了一个float属性,变成了float盒子所以原先的包含span的匿名块级元素也就不存在了,所以这个div会顶上占有原先span所处的位置,对于是否会占有前面的空间,还需要看前面是否含有其他的inline/inline-block元素,因为如果还有其他的inline/inline-block元素的话,匿名的盒子还是会有的,那样的话div的位置就不会有变化,其实所有的布局都在BFC中的,有兴趣的可以了解一下。然后我们继续看一下图中的情况,因为现在span的层级变高,div元素顶上了原先span的位置,而且div中没有float层级,所以div的content会被具有float属性的span元素挤到后面的位置,没办法,谁让人家在层级高(float)的地方有人呢!

然后我们看一下说上面文字移动到(float层)下一排的情况。



大家看一下上面的图片,A是具有float属性的span标签,B是普通具有文字内容的div元素,C是一个普通的没有文字内容的div元素。然后现在大家看到当浮动元素的宽度过宽时(底层元素的空间不足以显示内容了),然后文字就会跑到当前float层的下一排去显示,大家请注意,这个时候文字还是属于原先的元素的,只是匿名的行内元素移动了位置,并不会产生新的float元素和匿名div元素,我测试过,大家感兴趣的也可以测试一下
后面的情况就不介绍了,因为了解到层级关系以及bfc的内容,其实下次遇到这种问题分析一下就ok了。

(5) 清除浮动


a. 父元素加上 overflow: hidden
        因为overflow.hidden会触发BFC。 BFC的意思是,我这个元素里面的子孙元素,不会影响外部元素的布局。但浮动本身会造成行内宽度的压缩,出现文字环绕效果。如此一来,浮动元素越宽,当然行内的可容纳的文字数就越少,文字的行数就会增加,文档流高度也就增加。这样,就影响了其外部元素的布局。所以从BFC的本意来说,必须给浮动元素撑出高度,使得后续的元素无法跟浮动元素共享同一水平位置,这也是BFC的特性,大家有兴趣的看一下html的高度会涵盖float属性(PS: html是BFC元素)。

b. 浮动元素后面加上div并且带有clear: both属性。
        clear: both属性之后的元素会忽略上一个元素的浮动声明而不去补之前的空缺。

Summary
       究其原理: 猜测(PS: 基准一定是block box层)是添加出一个匿名块级元素包含float元素,但是a原因的是将这个匿名块级元素包含于BFC元素,b原因的是将匿名块级元素包含于当前的父级元素。

4. position


(1) 解释: Position属性: 规定元素的定位类型


(2) 值

a. static: 默认值,没有定位。元素出现在正常的流中(忽略 top, bottom, left, right 或者 z-index 声明)。
b. relative :相对定位;不脱离文档流的布局,只改变自身的位置,在文档流原先的位置遗留空白区域。定位的起始位置为此元素原先在文档流的位置。
c. absolute :绝对定位;脱离文档流的布局,遗留下来的空间由后面的元素填充。定位的起始位置为最近的父元素(postion不为static),否则为Body文档本身
d. fixed :固定定位;类似于absolute,但不随着滚动条的移动而改变位置。


当然仅仅是position的话是不能够完成定位,还需要top, right, bootom, left

(3)总结:

a. position的值不为static或者reletive的任何一个会触发BFC,想到这会不会想到关于margin的问题。
b. absolute 和 relative :含有此2个值的边缘元素,浏览器缩小到此元素不可见时,会出现滚动条。 fixed :含有此值的边缘元素,浏览器缩小到此元素不可见时,不会出现滚动条。
c. 层级关系: 具有定位属性的但是没有z-index的元素对应上面层级关系图的z-index:auto层级。

(4)z-index


z-index 属性有下面两个作用:

指定当前元素的堆叠顺序
给当前元素创建一个新的堆叠上下文

这个属性只能应用在 position 属性为 relative , absolute 或者 fixed 的元素上。

5. 关于margin的相关信息


Margins of the root element's box do not collapse.(根元素不折叠)

If the top and bottom margins of an element with clearance are adjoining, its margins collapse with the adjoining margins of following siblings but that resulting margin does not collapse with the bottom margin of the parent block.(有间隙不折叠)

Margins between a floated box and any other box do not collapse (not even between a float and its in-flow children). (浮动不折叠)

Margins of elements that establish new block formatting contexts (such as floats and elements with 'overflow' other than 'visible') do not collapse with their in-flow children.(创建BFC与子不折叠)

Margins of absolutely positioned boxes do not collapse (not even with their in-flow children).(positioned 不折叠)

Margins of inline-block boxes do not collapse (not even with their in-flow children).(inline-box 不折叠)

The bottom margin of an in-flow block-level element always collapses with the top margin of its next in-flow block-level sibling, unless that sibling has clearance.(兄弟有间隙不折叠)

The top margin of an in-flow block element collapses with its first in-flow block-level child's top margin if the element has no top border, no top padding, and the child has no clearance.(父子间有padding 和 border 不折叠)
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值