深刻理解CSS网页布局-理论篇

在CSS网页开发布局中,须要对浮动和定位有深入的理解才能在开发中游刃有余。css

基于此,在博客园中作了本篇总结,这些总结来自实践经验和阅读一些书籍后的理解总结,主要内容为浮动,清除浮动,定位。html

(可点击屏幕左边的目录查阅)ide

一. float属性深刻理解

首先简单布局一下,代码以下:布局

<!DOCTYPE html>
<html>
<head>
    <meta charset="utf-8">
    <title>css Test</title>
<style type="text/css">

#bigBox {
    border: 2px solid Gray;
    width: 500px;
    height: 400px;
    margin: 100px auto;
}

#box1{
    background: yellow;
    width: 100px;
    height: 100px;
}

#box2{
    background: SkyBlue;
    width: 120px;
    height: 100px;
}

#box3{
    background: pink;
    width: 140px;
    height: 100px;
}


</style>
</head>
<body>

<div id="bigBox">
    <div id="box1">1</div>
    <div id="box2">2</div>
    <div id="box3">3</div>
</div>

</body>
</html>

效果图:测试

图p1spa

1. 脱离文档流

脱离文档流,即在元素原来的位置中脱离出来,能够理解为漂浮起来,可是要注意一些细节。3d

细节一

若浮动元素后面有不浮动的元素,那么其后面不浮动的元素会把浮动元素视为消失,而后顶到它的位置中。code

咱们来测试一下:对第二个div(id=box2)设置浮动,观察第三个div的位置htm

#box1{
    background: yellow;
    width: 100px;
    height: 100px;
}

#box2{
    background: SkyBlue;
    width: 120px;
    height: 100px;

    float:left;/*测试内容*/
}

#box3{
    background: pink;
    width: 140px;
    height: 100px;
}

效果图:对象

图p2

咱们能够看到第三个div顶到浮动div原来的位置上去了,这里的float:left 设置为right,也一样,即第二个div消失了,后面的顶上去。

效果图:

 图p3

 

细节二

咱们不能理解为设置float以后,这个元素就彻底漂浮在没有设置float元素的上面,虽然在细节一中的效果图中看是漂浮在上面(2在3的上面)。这个细节就是浮动只对后面的元素形成影响(所谓影响,就是后面的元素把它视为消失),对于排在它前面的同级块元素,不会对其位置形成影响。(即若是前面的同级块元素没有设置浮动,那么它也不会漂浮到这个元素的上面)。细节一的p1例子已经验证了这一特性(2仍是在1的下面)。

那么,对于排在前面的同级内联元素呢?对于同级内联元素,设置了float属性的元素与前面的内联元素属于同一层面,并且优先级高于前面的同级内联元素,这里的优先级指位置优先级,好比float:left,那么前面的内联元素若是原来占据最左边,那么它因为优先级低于浮动元素,因此它就会让位与浮动元素,排在浮动元素的右边。

咱们来看一下测试代码(重点查看注释的测试内容):

#box1{
    background: yellow;
    width: 100px;
    height: 100px;
    display: inline-block; /*测试内容*/
}

#box2{
    background: SkyBlue;
    width: 120px;
    height: 100px;

    float:left;  /*测试内容*/
}

#box3{
    background: pink;
    width: 140px;
    height: 100px;
}

效果图:

图p4

分析:对于1(这里用数字表明相应的div,上下同)来讲,因为排在浮动的2的前面,因此它不管是否为块元素,都和2属于同一层面,再因为它不是块元素,因此它的位置优先级别低于2,因为2的float:left,向左浮动,因此它靠最左,1被挤到它的右边。对于3来讲,2因为是浮动,因此视为消失了,可是因为3是块元素,因此独占一行,因而就有了上面的效果。

 

细节三

 文字永远会被挤出。咱们把1,2设置浮动,把3注释,而后添加p标签。查看一下状况:

<div id="bigBox">
    <div id="box1">1</div>
    <div id="box2">2</div>
    <!-- <div id="box3">3</div> -->
    <p>HelloWorld! HelloWorld! HelloWorld! HelloWorld! HelloWorld! HelloWorld! HelloWorld! HelloWorld! HelloWorld! HelloWorld! 10个HelloWorld!</p>
</div>

图p5

实际上,并非P元素和1,2浮动元素并列排在了一块儿,在细节一二中,咱们知道p元素必定是顶到1的位置中的,可是因为文字永远是被挤出来的,因此他们被挤到2的左边,此时实现了一个文字环绕效果。咱们能够给P元素添加背景色来查看一下实际:

p {
    background-color: red;
}

 图p6

 

2. 没有固定尺寸的父级元素没法自适应浮动的子元素(全部子元素都为浮动)

一样的,父元素属于文档流,若是子元素中有设置浮动的,那么也视为消失,因此父元素不会包裹它,若是所有子元素都为浮动,那么至关于这个父元素里面没有子元素,此时的表现和子元素为空同样。

咱们先来看一下,在没有浮动元素的文档流中的状况:

代码:

body {
    margin: 0 300px;
}

#bigBox {
    border: 2px solid Gray;
/*    width: 500px;
    height: 400px;*//*测试内容:这里要设置去掉宽高*/
    margin: 100px auto;
}

#box1{
    background: yellow;
    width: 100px;
    height: 100px;
}

#box2{
    background: SkyBlue;
    width: 120px;
    height: 100px;
}

#box3{
    background: pink;
    width: 140px;
    height: 100px;
}
<body>

<div id="bigBox">
    <div id="box1">1</div>
    <div id="box2">2</div>
    <div id="box3">3</div>
</div>

</body>

效果图:

图p7

这里的div(id=bigBox,1,2,3的父级元素)没有设置宽高,因此自动支撑起了子元素的宽高,因为1,2,3都是块元素,因此独占一行,宽度自动适应为body的宽度,因此如效果图所示,这是没有设置浮动的状况。

咱们把2设置为浮动,查看一下效果:

#box2{
    background: SkyBlue;
    width: 120px;
    height: 100px;
    float: left; /*测试内容*/
}

效果图:

图p8

父元素仍是能够适应,不过视2为消失。

下面咱们把所有子元素都设置为浮动,查看一下效果:

body {
    margin: 0 300px;
}

#bigBox {
    border: 2px solid Gray;
/*    width: 500px;
    height: 400px;*/
    margin: 100px auto;
}

#box1{
    background: yellow;
    width: 100px;
    height: 100px;
    float: left; /*测试内容*/
}

#box2{
    background: SkyBlue;
    width: 120px;
    height: 100px;
    float: left; /*测试内容*/
}

#box3{
    background: pink;
    width: 140px;
    height: 100px;
    float:left; /*测试内容*/
}

图p9

 

咱们把1,2,3去掉,查看没有子元素的父元素的效果图,而后对比一下:

<body>

<div id="bigBox">
  <!--   <div id="box1">1</div>
    <div id="box2">2</div>
    <div id="box3">3</div> -->
</div>

</body>
</html>

图p10

结果和p9是同样的,也就是p9中父元素把1,2,3视为消失了。

 

二. 清除浮动

1. 清除浮动方法(非父元素受影响)

方法一:设置clear属性,这个属性设置在受影响的元素(非父级)上

clear属性值有left,right,both,通常状况下对使用both清除浮动,咱们来看一下:

#box1{
    background: yellow;
    width: 100px;
    height: 100px;
}

#box2{
    background: SkyBlue;
    width: 120px;
    height: 100px;
    float: left; /*测试内容*/
}

#box3{
    background: pink;
    width: 140px;
    height: 100px;
    clear:both; /*测试内容*/
}

图p11

请对比p2,能够这样形象理解,把原来2的消失变成了可见,而后就排在它的后面。

 

方法二:额外添加一个空元素,并设置clear属性

<div id="bigBox">
    <div id="box1">1</div>
    <div id="box2">2</div>
    <div id="clear"></div> <!-- 测试内容 -->
    <div id="box3">3</div>
</div>
#clear {
    clear: both;
}

一样能够达到预期效果:

 图p12

 

2. 清除浮动方法(父元素受影响)

图p7中咱们看到父元素把子元素1,2,3视为消失,因此没法自适应子元素的宽度,为了消除子元素浮动对父元素的影响,这里有三个方法能够解决问题,咱们来测试分析一下。

先把父元素受影响的代码和效果图贴出来:

<!DOCTYPE html>
<html>
<head>
    <meta charset="utf-8">
    <title>css Test</title>
<style type="text/css">

body {
    margin: 0 300px;
}

#bigBox {
    border: 2px solid Gray;
/*    width: 500px;
    height: 400px;*/
    margin: 100px auto;
    /*clear: both;*/
}

#box1{
    background: yellow;
    width: 100px;
    height: 100px;
    float: left; /*测试内容*/
}

#box2{
    background: SkyBlue;
    width: 120px;
    height: 100px;
    float: left; /*测试内容*/
}

#box3{
    background: pink;
    width: 140px;
    height: 100px;
    float: left; /*测试内容*/
}

#clear {
    clear: both;
}

</style>
</head>
<body>

<div id="bigBox">
    <div id="box1">1</div>
    <div id="box2">2</div>
    <div id="box3">3</div>
</div>

</body>
</html>
View Code

图p13

 

方法一:在父元素里面添加一个空的子元素,放在最后面,并设置clear属性

<div id="bigBox">
    <div id="box1">1</div>
    <div id="box2">2</div>
    <div id="box3">3</div>
    <!-- 这是一个清除浮动的空标签 -->
    <div id="clear"></div>
</div>

效果图:

图p14

分析:原理很简单,空div设置了clear属性,因此它不受前面1,2,3的影响,因此它就会排在1,2,3的后面,形成了空div与顶部之间有了必定的距离,这个距离就拉大了父元素的尺寸,因此从表现上看,就像是清除了浮动,达到咱们想要的效果。

此方法的弊端就是添加了额外的无心义的标签。

 

方法二:在父元素上设置overflow:hidden;

#bigBox {
    border: 2px solid Gray;
/*    width: 500px;
    height: 400px;*/
    margin: 100px auto;
    overflow:hidden; /*测试内容*/
}

效果图:

 图p15

 

深刻理解overflow属性

overflow的属性值有:visible(默认值),hidden,scroll,auto,inherit

经常使用的是hidden属性,除了visible以外,不算inherit(继承)在内的其余三个属性值,若是设置了,那么该元素就会与浮动元素在同一个层面。咱们能够看到文章开头的图p2中,2浮动在3的上面,由于它们不在同一个层面,若是对3设置overflow:hidden;(三个属性均可),那么他们就属于同一个层面,此时3虽然受浮动的影响,可是因为同一个层面的关系,因此它排在了2的后面,咱们来测试一下。

#box1{
    background: yellow;
    width: 100px;
    height: 100px;
}

#box2{
    background: SkyBlue;
    width: 120px;
    height: 100px;
    float: left; /*测试内容*/
}

#box3{
    background: pink;
    width: 140px;
    height: 100px;
    overflow: hidden;/*测试内容*/
}

效果图:

图p16

咱们比较图p2和p16,就能够看出overflow的这一特性。

回到咱们讨论的父元素上面,父元素设置overflow属性,因此它就与全部浮动的子元素在同一层面上,因此就支撑了起来。不过它的弊端就是overflow的三个属性会对子元素超出父元素的部分不显示出来,可能形成信息缺失。

 

特别注意

在ie6及如下版本中(怪异模式),overflow的设置仍是不起做用,这里就要用到ie特有的一个属性zoom来解决,只要设置zoom:1,即原来的大小便可,代码以下:

#bigBox {
    border: 2px solid Gray;
/*    width: 500px;
    height: 400px;*/
    margin: 100px auto;
    overflow: hidden;
    zoom:1;/*添加这个属性,可兼容ie6*/
}

 

方法三:使用自定义伪类,设置清除属性

这是最实用和推荐的方法,通常把这个伪类的名称设置为 -XXX-clearFix,好比新浪微博就是用 -weibo-clearFix,在使用的过程当中,咱们习惯性的使用伪对象after的方法,在clearFix后面添加一些清除浮动的属性。

.-test-clearFix:after {
    clear: both;
    display: block;
    visibility: hidden; /*设置不可见*/
    height: 0;
    line-height: 0;
    content: ""; /*after伪对象必须的属性,能够设置内容为空*/
}

.-test-clearFix {}

在父级div里面添加这个类便可:

<div id="bigBox" class="-test-clearFix">
    <div id="box1">1</div>
    <div id="box2">2</div>
    <div id="box3">3</div>
</div>

效果图:

图p17

 

三. 相对定位和绝对定位

1. 相对定位

特色一

相对自身偏移。

相对定位比较好理解,它相对于自身进行了定位,所设置的偏移属性的参照物为自己原来的位置。

特色二

元素原来的位置不脱离文档流,占据了位置。

对于特色1、二,咱们来测试一下:

#bigBox {
    border: 2px solid Gray;
    width: 500px;
    height: 400px;
    margin: 100px auto; 
}

#box1{
    background: yellow;
    width: 100px;
    height: 100px;
    float: left;
}

#box2{
    background: SkyBlue;
    width: 120px;
    height: 100px;

    float: left;
    position: relative;/*测试内容*/
    top: -140px;
}

#box3{
    background: pink;
    width: 140px;
    height: 100px;

    float: left;
}

图p18

2占据了原来的位置,因此3不会靠左移动。

 

2.绝对定位:absolute

特色一

脱离文档流

绝对定位和float属性有类似之处,设置了这个属性的元素会脱离文档流,脱离文档流后的表现和float同样,可是它没法清除浮动也不占据位置。

#bigBox {
    border: 2px solid Gray;
/*    width: 500px;
    height: 400px;*/
    margin: 100px auto;
    position: relative; /*测试内容*/
}

#box1{
    background: yellow;
    width: 100px;
    height: 100px;
    position: absolute;/*测试内容*/
}

#box2{
    background: SkyBlue;
    width: 120px;
    height: 100px;
    position: absolute; /*测试内容*/
}

#box3{
    background: pink;
    width: 140px;
    height: 100px;
    position: absolute; /*测试内容*/
}

效果图:

图p19

图中能够看出1,2,3进行了绝对定位,而且重叠在了一块儿。其重叠特性为下面的特色二。

 

特色二

排再文档流后面的绝对定位元素显示的优先级高于前面的绝对定位元素。

为了区分,咱们来给出必定的位移,观察先后优先级:

#bigBox {
    border: 2px solid Gray;
/*    width: 500px;
    height: 400px;*/
    margin: 100px auto;
    position: relative; /*测试内容*/
}

#box1{
    background: yellow;
    width: 100px;
    height: 100px;
    position: absolute;/*测试内容*/
}

#box2{
    background: SkyBlue;
    width: 120px;
    height: 100px;
    position: absolute; /*测试内容*/
    left: 50px;
    top:40px;
}

#box3{
    background: pink;
    width: 140px;
    height: 100px;
    position: absolute; /*测试内容*/
    left: 80px;
    top: 20px;
}

图p20

图中能够看出优先级 3>2>1

 

特色三

绝对定位,其父级元素若是没有设置定位属性,则以更高级别的有设置定位属性的做为参照物进行定位,若是父级元素都没有定位属性,则以body做为参照。

(代码参考"特色一"中的代码#bigBox里面,设置了relative属性,里面的1,2,3以该父级元素进行绝对定位)

 

3. 绝对定位:fixed

这个定位属性是最简单的,其特色是脱离文档流,不占据位置,而后固定在屏幕,不会对文档流形成影响。这里就不进行代码验证。

 

深刻理解了这些属性,就能够在实际工做中灵活应用,后续会总结一些布局实战。本文如有不妥之处,欢迎批评指正。

相关文章
相关标签/搜索