【从0到1学Web前端】CSS定位问题一(盒模型,浮动,BFC)

引子:

在谈到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。

上面的结论是我在 IE11 浏览器中模拟IE8IE9得出的结论,上面的文字是有问题的(可能是因为升级IE11后,浏览器的解析内核跟IE8和IE9不一样,因为微软IE浏览器的标准也是一直在改变的)。

在真实的IE8IE9background-color都仅仅是padding+content 。而IE11中background-colorborder+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
    点赞
  • 8
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
HTML、CSS、JavaScript是Web开发中的三个核心技术。HTML是超文本标记语言,用于描述网页内容;CSS是层叠样式表,用于描述网页布局和样式;JavaScript是用于网页交互和动态效果的脚本语言。 盒模型是指在Web开发中,每个元素可以看做是一个矩形的盒子,包含内容区域、内边距、边框和外边距四部分。有两种盒模型,分别是标准盒模型和IE盒模型。标准盒模型的宽度和高度只包括内容区域,而IE盒模型的宽度和高度包括了内容区域、内边距和边框。设置盒模型的方式是通过CSS的box-sizing属性,可以设置为content-box(标准盒模型)或border-box(IE盒模型)。 CSS选择器用于选择需要样式化的HTML元素。常见的选择器有标签选择器、类选择器、ID选择器、后代选择器、子元素选择器等。优先级是指当多个选择器应用到同一个元素时,哪一个选择器的样式会被应用。优先级的计算方式是通过不同选择器的权重来计算的,权重越高的选择器优先级越高。 要居中一个元素,可以使用CSS的flex布局或者绝对定位。使用flex布局时,设置父元素的display属性为flex,同时设置justify-content和align-items属性为center。使用绝对定位时,设置父元素的position属性为relative,子元素的position属性为absolute,同时设置left和top属性为50%。 清除浮动是指当一个元素设置了浮动后,会导致其父元素高度塌陷,无法撑开父元素。可以通过在父元素中添加一个clearfix类来清除浮动,或者使用CSS的overflow属性将父元素设置为auto或hidden。 BFC(块级格式化上下文)是指一个独立的渲染区域,可以防止元素间的margin重叠,并且可以自动适应父元素的宽度。应用场景包括浮动元素、定位元素、inline-block元素等。 CSS3新增了很多新特性,包括圆角、阴影、渐变、变形、动画、媒体查询等。 响应式设计是指根据用户使用设备的不同,自适应地改变网页的布局和样式。实现方式包括使用CSS的媒体查询、弹性布局、流式布局等。 跨域是指在同一域名下的网页请求其他域名下的资源。解决跨域问题的方式包括JSONP、CORS、代理等。 HTTP状态码是指在HTTP协议中,服务器响应客户端请求时返回的状态码。常见的状态码包括200 OK、404 Not Found、500 Internal Server Error等。 事件冒泡和事件捕获是指在DOM中,当一个事件被触发时,会从最内层的元素开始,逐级向外层元素冒泡或者向内层元素捕获。可以使用事件对象的stopPropagation方法来阻止事件冒泡或者捕获。 闭包是指函数和其相关的引用环境组合而成的实体,可以访问其定义时的变量。闭包的作用包括保护变量、模块化编程、实现私有变量等。 ES6新增了很多新特性,包括let、const、箭头函数、模板字符串、解构赋值、Promise等。 实现异步编程的方式包括回调函数、Promise、async/await等。 React的生命周期包括componentDidMount、componentWillUnmount、shouldComponentUpdate等,在组件的不同阶段会触发不同的生命周期函数,可以在这些函数中进行状态管理和数据处理。

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值