CSS3与页面布局学习总结(三)——BFC、定位、浮动、垂直居中

CSS3与页面布局学习总结(三)——BFC、定位、浮动、垂直居中

 

一、BFC与IFC

1.1、BFC与IFC概要

BFC(Block Formatting Context)即“块级格式化上下文”, IFC(Inline Formatting Context)即行内格式化上下文。常规流(也称标准流、普通流)是一个文档在被显示时最常见的布局形态。一个框在常规流中必须属于一个格式化上下文,你可以把BFC想象成一个大箱子,箱子外边的元素将不与箱子内的元素产生作用。

BFC是W3C CSS 2.1 规范中的一个概念,它决定了元素如何对其内容进行定位,以及与其他元素的关系和相互作用。当涉及到可视化布局的时候,Block Formatting Context提供了一个环境,HTML元素在这个环境中按照一定规则进行布局。一个环境中的元素不会影响到其它环境中的布局。比如浮动元素会形成BFC,浮动元素内部子元素的主要受该浮动元素影响,两个浮动元素之间是互不影响的。也可以说BFC就是一个作用范围。

在普通流中的 Box(框) 属于一种 formatting context(格式化上下文) ,类型可以是 block ,或者是 inline ,但不能同时属于这两者。并且, Block boxes(块框) 在 block formatting context(块格式化上下文) 里格式化, Inline boxes(块内框) 则在 Inline Formatting Context(行内格式化上下文) 里格式化。

1.2、如何产生BFC

当一个HTML元素满足下面条件的任何一点,都可以产生Block Formatting Context:
a)、float的值不为none

b)、overflow的值不为visible

c)、display的值为table-cell, table-caption, inline-block中的任何一个

d)、position的值不为relative和static

CSS3触发BFC方式则可以简单描述为:在元素定位非static,relative的情况下触发,float也是一种定位方式。

1.3、BFC的作用与特点

a)、不和浮动元素重叠,清除外部浮动,阻止浮动元素覆盖

如果一个浮动元素后面跟着一个非浮动的元素,那么就会产生一个重叠的现象。常规流(也称标准流、普通流)是一个文档在被显示时最常见的布局形态,当float不为none时,position为absolute、fixed时元素将脱离标准流。

没有BFC的情况:

示例代码:

 View Code

运行结果:

此时的div1因为float已经产生了BFC,在div2中添加样式overflow:hidden让其产生BFC,代码如下:

复制代码
            #div2{
                width: 300px;
                height: 300px;
                background: lightblue;
                overflow: hidden;
            }
复制代码

运行结果:

b)、清除元素内部浮动,计算浮动元素的高度

只要把父元素设为BFC就可以清理子元素的浮动了,最常见的用法就是在父元素上设置overflow: hidden样式,对于IE6加上zoom:1就可以了(IE Haslayout)。

当一个元素的内部元素浮动时不会计算其高度,示例如下:

 View Code

运行结果:

修改div0让其触发BFC,还原高度,代码如下:

复制代码
            #div0 {
                border: 2px solid lightsalmon;
                padding: 20px;
                width: 400px;
                overflow: hidden;  /*让div0触发BFC*/
            }
复制代码

 

运行结果:

 

c)、外边距将不再与上下文之外的元素折叠 

示例代码:

 View Code

如果此时将脚本的div1与div2同时变成BFC环境,修改的css如下:

复制代码
            #div1 {
                width: 200px;
                height: 200px;
                background: lightgreen;
                margin-bottom: 100px;
                overflow: hidden;
            }
            
            #div2 {
                width: 200px;
                height: 200px;
                background: lightblue;
                margin-top: 100px;
                overflow: hidden;
            }
复制代码

执行时会发现效果还是一样,此时的div1与div2都是BFC上下文,但是要求的是:外边距将不再与上下文之外的元素折叠,按照要求,我们应该将div1与div2放在不同的上下文中,修改后的脚本如下:

复制代码
<!DOCTYPE html>
<html>
    <head>
        <meta charset="UTF-8">
        <title>BFC与IFC</title>
        <style type="text/css">
            #div1 {
                width: 200px;
                height: 200px;
                background: lightgreen;
                margin-bottom: 100px;
            }
            
            #div2 {
                width: 200px;
                height: 200px;
                background: lightblue;
                margin-top: 100px;
            }
            #div2-outer
            {
                overflow: hidden;
            }
        </style>
    </head>
    <body>
        <h2>BFC与IFC</h2>
        <div id="div1">div1
        </div>
        <div id="div2-outer">
            <div id="div2">div2
            </div>
        </div>
    </body>
</html>
复制代码

运行结果如下:

 d)、元素会一个接一个地被垂直放置,它们的起点是一个包含块的顶部(文字不会环绕布局)

示例代码:

 View Code

没有BFC时的运行结果:

从运行结果可以看出div与p还是重叠了,只是文字被挤出,和前面提到的重叠是同一个意思,将p元素触发BFC后的效果如下图所示:

            p{
                overflow: hidden;
            }

运行结果:

1.4、IE与Layout

Layout是 IE 浏览器渲染引擎的一个组成部分。在 IE 浏览器中,一个元素要么自己对自身的内容进行组织和计算大小, 要么依赖于包含块来计算尺寸和组织内容,hasLayout 与 BFC 有很多相似之处。在IE中,元素使用“布局”概念来控制尺寸和定位,分为拥有布局和没有布局两种情况,拥有布局的元素由它控制本身及其子元素的尺寸和定位,而没有布局的元素则通过父元素(最近的拥有布局的祖先元素)来控制尺寸和定位,而一个元素是否拥有布局则由 hasLayout 属性告知浏览器,它是个布尔型变量,true 代表元素拥有布局,false 代表元素没有布局。简而言之,hasLayout 只是一个 IE 下专有的属性,hasLayout 为 true 的元素浏览器会赋予它一系列的效果。
特别注意的是,hasLayout 在 IE 8 及之后的 IE 版本中已经被抛弃,所以在实际开发中只需针对 IE 8 以下的浏览器为某些元素触发 hasLayout。

出发IE下的haslayout方法:

display: inline-block
height: (除 auto 外任何值)
width: (除 auto 外任何值)
float: (left 或 right)
position: absolute
writing-mode: tb-rl
zoom: (除 normal 外任意值)
min-height: (任意值)
min-width: (任意值)
max-height: (除 none 外任意值)
max-width: (除 none 外任意值)
overflow: (除 visible 外任意值,仅用于块级元素)
overflow-x: (除 visible 外任意值,仅用于块级元素)
overflow-y: (除 visible 外任意值,仅用于块级元素)
position: fixed

综合前面的内容清除浮动的写法如下:

.floatfix{
*zoom:1;  /*在旧版本的IE浏览器缩放大小,触发haslayout*/
}
.floatfix:after{
content:"";
display:table;
clear:both;
}

1.5、IFC

 

 

除了BFC还有IFC,GFC,FFC,是不同格式化上下文(Formatting Context)的简称,GFC是网格格式化上下文(Grid Formatting Context),FFC是弹性盒格式化上下文(Flex Formatting Context),FKC是开封菜的意思:)。

二、定位

使用css布局position非常重要,他的语法如下:

position:static | relative | absolute | fixed | center | page | sticky
默认值:static,center、page、sticky是CSS3中新增加的值。

2.1、static
可以认为静态的,默认元素都是静态的定位,对象遵循常规流。此时4个定位偏移属性不会被应用,也就是使用left,right,bottom,top将不会生效。

示例:

 View Code

运行结果:

定义偏移并未起作用。

2.2、relative

相对定位,对象遵循常规流,并且参照自身在常规流中的位置通过top,right,bottom,left这4个定位偏移属性进行偏移时不会影响常规流中的任何元素。

示例代码:

复制代码
<!DOCTYPE html>
<html>
    <head>
        <meta charset="UTF-8">
        <title>相对定位</title>
        <style type="text/css">
            div {
                width: 200px;
                height: 200px;
                background: lightblue;
                margin: 10px;
            }
            #div1 {
                position: relative;  /*相对定位*/
                left:30px;  /*在自己原有位置上相对左边偏移30像素*/
                bottom: -30px;
                background: lightgreen;
            }
        </style>
    </head>
    <body>
        <div id="div1">div1
        </div>
        <div id="div2">div2
        </div>
    </body>
</html>
复制代码

 

运行结果:

2.3、absolute

绝对定位,对象脱离常规流,此时偏移属性参照的是离自身最近的定位祖先元素,如果没有定位的祖先元素,则一直回溯到body元素。盒子的偏移位置不影响常规流中的任何元素,其margin不与其他任何margin折叠。

元素定位参考的是离自身最近的定位祖先元素,要满足两个条件,第一个是自己的祖先元素,可以是父元素也可以是父元素的父元素,一直找,如果没有则选择body为对照对象。第二个条件是要求祖先元素必须定位,通俗说就是position的属性值为非static都行。

示例代码:

复制代码
<!DOCTYPE html>
<html>

    <head>
        <meta charset="UTF-8">
        <title>绝对定位</title>
        <style type="text/css">
            div {
                border: 2px solid darkturquoise;
                padding: 10px;
            }
            
            #div1 {
                width: 400px;
                height: 400px;
            }
            
            #div2 {
                width: 300px;
                height: 300px;
            }
            
            #div3 {
                width: 200px;
                height: 200px;
                position: absolute;
                right: 5px;
                top: 5px;
            }
        </style>
    </head>

    <body>
        <div id="div1"> div1
            <div id="div2"> div2
                <div id="div3">div3
                </div>
            </div>
        </div>

    </body>

</html>
复制代码

运行结果:

 因为div3使用absolute绝对定位,它的参考对象是父元素div2,div1都不满足条件,因为两者都没有进行定位,是默认的定位值static,根据约定最终找到body,所以会出现在页面的右上角。此时如果想让div3的参照对象为div1,则可以修改代码为:

复制代码
<!DOCTYPE html>
<html>

    <head>
        <meta charset="UTF-8">
        <title>绝对定位</title>
        <style type="text/css">
            div {
                border: 2px solid darkturquoise;
                padding: 10px;
            }
            #div1 {
                width: 400px;
                height: 400px;
                position: relative;  /*相对定位*/
            }
            #div2 {
                width: 300px;
                height: 300px;
            }
            #div3 {
                width: 200px;
                height: 200px;
                position: absolute;
                right: 5px;
                bottom: 5px;
            }
        </style>
    </head>
    <body>
        <div id="div1"> div1
            <div id="div2"> div2
                <div id="div3">div3
                </div>
            </div>
        </div>
    </body>
</html>
复制代码

运行结果:

 

2.4、fixed

固定定位,与absolute一致,但偏移定位是以窗口为参考。当出现滚动条时,对象不会随着滚动。

如下图所示:

复制代码
<!DOCTYPE html>
<html>
    <head>
        <meta charset="UTF-8">
        <title>固定定位</title>
        <style type="text/css">
            body{
                height: 3000px;
            }
            #top{
                width: 50px;
                height: 70px;
                line-height: 70px;
                text-align: center;
                background: lightblue;
                position: fixed;
                right: 1px;
                bottom: 30%;
            }
        </style>
    </head>
    <body>
        <h2 id="title">固定定位</h2>
        <div id="top"><a href="#title">回顶部</a></div>
    </body>
</html>
复制代码

 

运行结果:

center:
与absolute一致,但偏移定位是以定位祖先元素的中心点为参考。盒子在其包含容器垂直水平居中。(CSS3)
page:
与absolute一致。元素在分页媒体或者区域块内,元素的包含块始终是初始包含块,否则取决于每个absolute模式。(CSS3)
sticky:
对象在常态时遵循常规流。它就像是relative和fixed的合体,当在屏幕中时按常规流排版,当卷动到屏幕外时则表现如fixed。该属性的表现是现实中你见到的吸附效果。(CSS3)

2.5、菜单

使用前面的内容实现了一个简单的下拉菜单,效果如下:

菜单结构:

 View Code

 

 

三、浮动

四、垂直居中

五、示例下载

posted @ 2016-11-28 14:40  MJ明杰  阅读(112)  评论(0编辑  收藏  举报