引子:

在谈到css定位问题的时候先来看一个小问题:

已知宽度(假如:100px)div框,水平居中,左右两百年的分别使用div框填充.且左右div自适应.

效果如下图:

这个问题的难点主要是浏览器宽度未知,且两边div自适应宽度.

第一种实现方法,是借助css3的新属性calc,实现代码如下:

body {
margin: 0;
padding: 0;
font-size:0;
}
.left_div {
background-color: #62FF09;
/*calc是css3属性可以动态计算,兼容不同浏览器的类型需要加识别的前缀,非常重要的是要有空格*/
width: -webkit-calc(50% - 50px);
width: calc(50%-50px);
height: 200px;
}
.mid_div {
width: 100px;
height: 200px;
margin-left: -50px;
background-color: #20FFDA;
margin:0 auto;
}
.right_div {
background-color: #FFF81B;
height: 200px;
width: -webkit-calc(50% - 50px);
}
div{display:inline-block;}

第二种实现方式就是借助与display属性,将所有的div框具有table的单元格的属性.

代码如下:

* {
padding: 0;
margin: 0;
}
.left_div, .mid_div, .right_div {
height: 200px;
display: table-cell;
}
.left_div {
width: 50%;
background: #369;
}
.mid_div {
//非IE识别的属性,(>=IE8)
min-width: 100px;
width: 100px;
background: #697;
}
.right_div {
width: 50%;
background: #126;
}

这里解决问题的主要思路是当中间的宽度确定后,因为所有div是单元格所以使用50%使左右的单元格平分剩下的宽度.


1.盒模型

盒模型又分IE盒模型和非IE盒模型:

看下面的一张图(来自维基百科):



由上面的图可以知道IE和非IE盒模型的区别主要是计算元素的宽度和高度不一样。

  1. IE浏览器: margin-left+width+margin-right
  2. 非IE浏览器:margin-left+border-left+padding-left+width+padding-right+border-right+margin-right

看一段代码:

<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>box-html</title>
<style type="text/css">
*{margin:0;padding:0;}
#body-box{
width:700px;
height:500px;
background-color:#FF00FF;
/*overflow:hidden;*/
}
.box-style{
width:500px;
height:300px;
border:10px dashed black;
background-color:red;
margin:10px 0 0 20px;
padding: 10px 10px 10px 10px;
}
</style>
</head>
<body>
<div id="body-box">
<div class="box-style">你好帅呀</div>
</div>
</body>
</html>

效果如下:

很明显我们发现一个问题,就是子元素的margin-top作用在了父元素上。

当我们给父元素添加一个overflow:hidden属性时,结果正常。

如下图:

这是为什么呢?

overflow 样式值为 非 visilbe 时,实际上是创建了 CSS 2.1 规范定义的 Block Formatting Contexts。创建了它的元素,会重新计算其内部元素位置,从而获得确切高度。这样父容器也就包含了浮动元素高度。这个名词过于晦涩,在 CSS 3 草案中被变更为名词 Root Flow,顾名思义,是创建了一个新的根布局流,这个布局流是独立的,不影响其外部元素的。实际上,这个特性与 早期 IE 的 hasLayout 特性十分相似。

经过测试在IE8以上的浏览器表现与chrome和firefox浏览器表现效果相同。但是在IE7以下浏览器不用设置这个属性就可以表现正常的效果。如下图:

很明显发现的一个问题就是IE8(包括IE8)以上浏览器的background-color是border+padding+content.而IE8(不包括)是padding+content

再来看一个示例,代码如下:

<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>TestBox</title>
<style type="text/css">
body{margin:0;}
.item1{
width:200px;
height:300px;
border:2px solid #f73bd6;
padding:100px 0 0 0;
}
.item2{
width:150px;
height:200px;
margin:150px 0 0 0;
border:2px solid #f73bd6;
}
</style>
</head>
<body>
<div class="item1">
<div class="item2"></div>
</div>
</body>
</html>

我非别在非IE浏览器(且>=IE8也同样的效果)中测试的结果如下:

在IE7中的效果如下图:

在<=IE6之下显示的效果如下(默认会将父级框撑开):

关于div的最小(最大)宽度和高度在IE8(>=)之上和非IE浏览器上都实现了min-height,maxheight,min-width,max-width这四个属性。

关于body的问题:

看下面一段代码:

<style type="text/css">
*{margin:0;padding:0;}
div{
width:300px;
height:200px;
background-color:#9feb3d;
}
body{
border:5px solid #eb3dda;
background-color:#3d3deb;
}
</style>
<body>
<div>
<ul>
<li>你是第1个</li>
<li>你是第2个</li>
<li>你是第3个</li>
<li>你是第4个</li>
<li>你是第5个</li>
</ul>
</div>
</body>

并且代码的效果图如下:

由上可以知道body是一个特殊的div(盒子)。它的background-color会延伸到margin。

标准流的概念:

在不使用其他的与排列和定位相关的特殊CSS规则时,各种元素的排列规则。


2.浮动

float 属性定义元素在哪个方向浮动。以往这个属性总应用于图像,使文本围绕在图像周围,不过在 CSS 中,任何元素都可以浮动。浮动元素会生成一个块级框,而不论它本身是何种元素,且浮动元素的宽度是根据内容的宽度确定的。

看下面的一段代码:

<body>
<span class="test-float1">你好吧</span>
<span class="test-float2">我是还是吧</span>
</body>

然后分别对.test-float1和.test-float2应用样式,代码如下:

*{padding:0;margin:0px;}
span{
background-color:#f73bd6;
margin:0 0 0 10px;
}
.test-float1{
float:left;
height:100px;
width:20px;
}
.test-float2{
/*float:left;*/
height:100px;
width:20px;
}

效果如下:

由上面的代码我们可以得出一个结论,span作为一个行内元素本来是没有width和height属性的,但是当对行内元素使用float属性后,该元素具有了width和height属性

注意:

假如在一行之上只有极少的空间可供浮动元素,那么这个元素会跳至下一行,这个过程会持续到某一行拥有足够的空间为止。

浮动的框可以向左或向右移动,直到它的外边缘碰到包含框或另一个浮动框的边框为止。由于浮动框不在文档的普通流中,所以文档的普通流中的块框表现得就像浮动框不存在一样。

看下面的一段代码:

<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>TestFloat</title>
<style type="text/css">
body{
margin:0;
} .item1, .item2, .item3, .item4{
width:200px;
height:100px;
background-color:#d8f73b;
margin:10px 0 0 0;
}
.item1{
float:right;
}
.item2{
/*float:left;*/
} </style>
</head>
<body>
<div id="body-div">
<div class="item1">item1</div>
<div class="item2">item2</div>
<div class="item3">item3</div>
<div class="item4">item4</div>
</div>
</body>
</html>

这个时候看到页面的结果有一个很明显的bug,如下图:

可以很明显的看到在浮动的item1和item2有一个间隔没有在一条水平线上。

这个时候就回到了我们开头的问题,我们给父级的div盒子添加overflow属性触发父级div的BFC。代码如下:

<style type="text/css">
body{
margin:0;
}
//触发父级元素的BFC
#body-div{
overflow:hidden;
}
.item1, .item2, .item3, .item4{
width:200px;
height:100px;
background-color:#d8f73b;
margin:10px 0 0 0;
}
.item1{
float:right;
}
.item2{
/*float:left;*/
} </style>

效果如下图:

有关BFC的定义:

BFC(W3C CSS 2.1 规范中的一个概念)就是所谓的Block formatting contexts (块级格式化上下文)。创建了 BFC的元素就是一个独立的盒子,里面的子元素不会在布局上影响外面的元素,反之亦然,同时BFC仍然属于文档中的普通流。

那么怎么触发BFC呢?

  1. float 除了none以外的值
  2. overflow 除了visible 以外的值(hidden,auto,scroll )
  3. display (table-cell,table-caption,inline-block)
  4. position(absolute,fixed)
  5. fieldset元素

注意:

display:table 本身并不会创建BFC,但是它会产生匿名框(anonymous boxes),而匿名框中的display:table-cell可以创建新的BFC,换句话说,触发块级格式化上下文的是匿名框,而不是 display:table。所以通过display:table和display:table-cell创建的BFC效果是不一样的。


fieldset 元素在www.w3.org里目前没有任何有关这个触发行为的信息,直到HTML5标准里才出现。有些浏览器bugs(Webkit,Mozilla)提到过这个触发行为,但是没有任何官方声明。实际上,即使fieldset在大多数的浏览器上都能创建新的块级格式化上下文,开发者也不应该把这当做是理所当然的。CSS 2.1没有定义哪种属性适用于表单控件,也没有定义如何使用CSS来给它们添加样式。用户代理可能会给这些属性应用CSS属性,建议开发者们把这种支持当做实验性质的,更高版本的CSS可能会进一步规范这个。

BFC的特性:

1)块级格式化上下文会阻止外边距叠加

当两个相邻的块框在同一个块级格式化上下文中时,它们之间垂直方向的外边距会发生叠加。换句话说,如果这两个相邻的块框不属于同一个块级格式化上下文,那么它们的外边距就不会叠加。

2)块级格式化上下文不会重叠浮动元素

根据规定,一个块级格式化上下文的边框不能和它里面的元素的外边距重叠。这就意味着浏览器将会给块级格式化上下文创建隐式的外边距来阻止它和浮动元 素的外边距叠加。由于这个原因,当给一个挨着浮动的块级格式化上下文添加负的外边距时将会不起作用(Webkit和IE6在这点上有一个问题——可以看这 个测试用例)。

3)块级格式化上下文通常可以包含浮动

触发了BFC的话,就不会被float元素覆盖,当子元素全部浮动的时候也能够正确地包含了

深入研究浮动:

来看下面的一段代码:

<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Document</title>
<style type="text/css">
body{margin:0;}
#body-div{
background-color:#ffff99;
border:1px solid #111111;
padding:5px;
}
#body-div div{
padding:10px;
margin:15px;
background-color:#90baff;
}
#body-div p{
border:5px dashed #111111;
background-color:#ff90ba;
}
.item1{
border:5px dashed #111111;
/*float:left;*/
}
.item2{
border:5px dashed #f73b4d; }
.item3{
border:5px dashed #0000CD; }
</style>
</head>
<body>
<div id="body-div">
<div class="item1">Box-1</div>
<div class="item2">Box-2</div>
<div class="item3">Box-3</div>
<p>让我们更详细地看看浮动和清理。假设希望让一个图片浮动到文本块的左边,并且希望这幅图片和文本包含在另一个具有背景颜色和边框的元素中。您可能编写下面的代码:让我们更详细地看看浮动和清理。假设希望让一个图片浮动到文本块的左边,并且希望这幅图片和文本包含在另一个具有背景颜色和边框的元素中。您可能编写下面的代码:让我们更详细地看看浮动和清理。假设希望让一个图片浮动到文本块的左边,并且希望这幅图片和文本包含在另一个具有背景颜色和边框的元素中。您可能编写下面的代码:</p>
</div>
</body>
</html>

显示效果如下图:

2.1为Box-1设置浮动

.item1{
border:5px dashed #111111;
float:left;
}

效果如下图:

可以看到标准流中的Box-2的文字在围绕着Box-1排列,而此时的Box-1的宽度不再伸展,而是能容纳下内容的最小宽度。

因为此时的Box-1已经脱离了标准流,标准流中的Box-2会顶到原来Box-1的位置(也就是Box-2的左边框和Box-1的左边框重合)此时Box-2的文字会围绕着Box-1排列。

2.2为Box-2设置浮动

.item2{
border:5px dashed #f73b4d;
float:left;
}

效果如下图:

这是很容易看出Box-3和Box-1的左边框重合。Box-3的文字围绕Box-2,并且Box-1和Box-2之间的空白是两者之间的margin产生的。

2.3为Box-3设置浮动

    .item3{
border:5px dashed #0000CD;
float:left; }

效果如下图:

这个时候可以很明显的看出三个浮动的盒子(都脱离文档流)都被P标签的盒子所包围,并且被文字环绕。

2.4设置Box-3浮动的方向

.item3{
border:5px dashed #0000CD;
float:right; }

效果如下图:

这个时候当我把浏览器窗口的宽度逐渐的缩小到不能容纳三个div宽度的时候,会有什么效果呢?如下图:

注意:

这种效果我只在IE浏览器(<=IE8的浏览器中出现更怪异的情况)里面测试的时候可以小到让Box-3换行。

在mac下得chrome,firefox和safari当窗口缩小到一定的宽度的时候,就无法在缩小宽度。无法出现Box-3被挤到下一行的情况。

如下图:

这时如果我们设置item2右浮动item3左浮动当我缩小浏览器窗口的时候,会出现如下的情况(mac下chrome和safari中仍旧是之上的情况,缩小到一定宽度无法再缩小)。

由此我们可以得出一个结论:

当浮动的元素在一行无法显示完全时,元素会按照普通流的顺序(Dom排列顺序)被挤到下一行。

2.5浮动的边界

增加Box-1的高度,当缩小浏览器的宽度的时候,会出现如下的现象:

主要是因为这个时候Box-3的边缘被Box-1的边缘卡住的缘故。

如下图红色的地方会有三个margin值:

2.6取消浮动的影响

使用CSS属性Clear,它有三个值left,right,both。

如我们取消p元素左右两侧的浮动:

代码如下:

#body-div p{
border:5px dashed #111111;
background-color:#ff90ba;
clear:both;
}

效果如下:

2.7浮动的影响

当然浮动对父级元素也会带来影响,比如说伟大的“塌陷”,看代码:

<style type="text/css">
body{margin:0;}
#body-div{
background-color:#ffff99;
border:1px solid #111111;
padding:5px;
}
#body-div div{
padding:10px;
margin:15px;
background-color:#90baff;
}
#body-div p{
border:5px dashed #111111;
background-color:#ff90ba;
clear:both;
}
.item1{
border:5px dashed #111111;
float:left;
height:30px;
}
.item2{
border:5px dashed #f73b4d;
float:left;
}
.item3{
border:5px dashed #0000CD;
float:left; }
</style>

效果如下图:

所有子元素的浮动不会将父级元素的高度撑开。

那么怎么解决这个问题呢?

一个很古老的办法就是在所有子元素的末尾添加一个空的div,并且设置它的clear:both。

看代码如下:

#body-div  .clear-float{
clear:both;
border:0;
padding:0;
margin:0;
}

效果如下:

其实我在IE各版本浏览器和非IE浏览器中测试的效果都是如上面的效果可意很容易的发现父级的div盒子并没有被完全的撑开。

不过有大神已经研究出了clearfix的写法,可以达到最合理的效果,主要目的就是触发父级盒子自身的BFC。

版本一:

    .clearfix:after {
content: "\200B";
display: block;
height: 0;
clear: both;
} .clearfix {
*zoom: 1;/*IE/7/6*/
}

content:”\200B”;这个参数,Unicode字符里有一个“零宽度空格”,即 U+200B,代替原来的“.”,可以缩减代码量。而且不再使用visibility:hidden。

版本二:

.clearfix:before, .clearfix:after {
content: "";
display: table;
}
.clearfix:after {
clear: both;
}
.clearfix {
*zoom: 1; /*IE/7/6 */
}

经过测试在IE的各个版本的浏览器中和非IE浏览器都能够正常的得到结果。

推荐阅读:

清除浮动:

http://mp.weixin.qq.com/s?__biz=MjM5MzMyNzg0MA==&mid=205433384&idx=2&sn=dbee05fdab1039a1bfa8d5e3dbbec76b&scene=5#rd

深入理解BFC:

http://www.cnblogs.com/v10258/p/3530290.html

版权声明:本文为博主原创文章,未经博主允许不得转载。

【从0到1学Web前端】CSS定位问题一(盒模型,浮动,BFC) 分类: HTML+CSS 2015-05-27 22:24 813人阅读 评论(1) 收藏的更多相关文章

  1. 前端知识概述----公司内部的一次分享 分类: JavaScript HTML+CSS 2015-04-16 21:24 2593人阅读 评论(2) 收藏

    因为公司内部一个纯后端团队要做一些适合自己团队的web页面,所以就有了这次分享.知识都是很基础,有的知识也只是做了解简单介绍.主要是想让大家对前端有一个基本的了解.现在做一个总结.欢迎大家拍砖. 知识 ...

  2. 【从0到1学Web前端】CSS定位问题二(float和display的使用) 分类: HTML+CSS 2015-05-28 22:03 812人阅读 评论(1) 收藏

    display 属性规定元素应该生成的框的类型. 这个属性用于定义建立布局时元素生成的显示框类型.对于 HTML 等文档类型,如果使用 display 不谨慎会很危险,因为可能违反 HTML 中已经定 ...

  3. 利用OpenMP实现埃拉托斯特尼(Eratosthenes)素数筛法并行化 分类: 算法与数据结构 2015-05-09 12:24 157人阅读 评论(0) 收藏

    1.算法简介 1.1筛法起源 筛法是一种简单检定素数的算法.据说是古希腊的埃拉托斯特尼(Eratosthenes,约公元前274-194年)发明的,又称埃拉托斯特尼筛法(sieve of Eratos ...

  4. Hiking 分类: 比赛 HDU 函数 2015-08-09 21:24 3人阅读 评论(0) 收藏

    Hiking Time Limit: 6000/3000 MS (Java/Others) Memory Limit: 131072/131072 K (Java/Others) Total Subm ...

  5. 1.PHP站内搜索 分类: PHP开发实例 2015-07-31 22:48 4人阅读 评论(0) 收藏

    PHP站内搜索:多关键字.加亮显示 1.SQL语句中的模糊查找 $sql = "SELECT * FROM `message` WHERE `content`like '%$k[0]%' a ...

  6. 菜鸟学习-C语言函数参数传递详解-结构体与数组 分类: C/C++ Nginx 2015-07-14 10:24 89人阅读 评论(0) 收藏

    C语言中结构体作为函数参数,有两种方式:传值和传址. 1.传值时结构体参数会被拷贝一份,在函数体内修改结构体参数成员的值实际上是修改调用参数的一个临时拷贝的成员的值,这不会影响到调用参数.在这种情况下 ...

  7. IOS开发之IOS8.0最新UIAlertController 分类: ios技术 2015-01-20 14:24 144人阅读 评论(1) 收藏

    最近苹果更新的IOS8 对以前进行了很大的修改, 更新的API也让人捉急,据说iOS 8的新特性之一就是让接口更有适应性.更灵活,因此许多视图控制器的实现方式发生了巨大的变化.比如全新的UIPrese ...

  8. UI基础:视图控制器.屏幕旋转.MVC 分类: iOS学习-UI 2015-07-02 22:21 62人阅读 评论(0) 收藏

    UIViewController 视图控制器,继承自UIResponder,作用:管理视图并且响应事件 功能: 1.分担APPdelegate的工作 2.实现模块独立,能提高复用性 创建UIViewC ...

  9. UI基础:UI程序执行顺序(UIApplicationMain()函数),自定义视图 分类: iOS学习-UI 2015-07-02 22:09 68人阅读 评论(0) 收藏

    UI程序的一般执行顺序: 先进入main里面,执行函数UIApplicationMain(),通过该函数创建应用程序对象和指定其代理并实现监听,当执行函数UIApplicationMain()时还会做 ...

随机推荐

  1. HDU 5321 Beautiful Set (莫比乌斯反演 + 逆元 + 组合数学)

    题意:给定一个 n 个数的集合,然后让你求两个值, 1.是将这个集合的数进行全排列后的每个区间的gcd之和. 2.是求这个集合的所有的子集的gcd乘以子集大小的和. 析:对于先求出len,len[i] ...

  2. Curry化函数

    <script> function fn(){ var i, rult = 0, len = arguments.length; for (i=0;i<len ;i++ ) { ru ...

  3. 好文推荐系列-------(5)js模块化编程

    本文主要来源于阮一峰的<Javascript模块化编程>系列文章整合,原文地址:http://www.ruanyifeng.com/blog/2012/10/javascript_modu ...

  4. poj 2240 Arbitrage(最短路问题)

    Description Arbitrage is the use of discrepancies in currency exchange rates to transform one unit o ...

  5. WORD文档中插入页码的问题

    原文链接:http://www.360doc.com/content/11/0216/15/849254_93539436.shtml 一.页码从第二页开始1.选择“插入-页码”,打开“页码”对话框. ...

  6. Mac-控制台更新svn版本

    brew install subversion 直接安装svbversion至最新版本

  7. SSM_CRUD新手练习(3)创建数据库

    在上一节我们已经完成了基本的SSM配置,现在需要创建我们数据库. 我们需要两张表分别为tbl_emp(员工表)和tbl_dedpt(部门表).同时d_id是部门表对应dept_id的外键. 需要注意的 ...

  8. openresty + lua 2、openresty 连接 redis,实现 crud

    redis 的话,openresty 已经集成,ng 的话,自己引入即可. github 地址:https://github.com/openresty/lua-resty-redis github  ...

  9. hdu 5050 大数

    http://acm.hdu.edu.cn/showproblem.php?pid=5050 大数模板最大公约数 信kuangbin,能AC #include <cstdio> #incl ...

  10. Delphi IDHTTP控件:GET/POST 请求

    Delphi IDHTTP控件:GET/POST 请求   最近一直在使用IDHTTP,下面是一些关于 GET.POST 请求基本使用方法的代码 一.GET 请求 1 procedure GetDem ...