浮动与定位

主要内容: 浮动的介绍、清除浮动、各种定位、BFC以及外边距合并的介绍。

浮动

什么是浮动元素

浮动元素是float 的值不是none的元素。

浮动元素的特征

  • 任何元素都可以浮动。浮动元素会生成一个块级框,而不论它本身是何种元素
  • 浮动元素会尽可能远地向左或者向右浮动, 直到它的外边缘碰到包含框或者另外一个浮动元素的框的边缘
  • 浮动元素从网页的正常流动中移除,但是仍然保持部分的流动性(与绝对定位相反)
  • 由于浮动元素从网页的正常流中删除, 所以会造成父容器塌陷
  • 文本和内联元素会环绕浮动元素。浮动元素脱离普通流,如果浮动元素后面有一个文档流中元素, 那么这个元素的框会表现的像浮动元素不存在, 但是框的文本内容会受浮动元素影响,会移动以留出空间

浮动元素对其他元素的影响

  • 对父容器的影响:对于其父元素来说,元素浮动之后,它脱离当前正常的文档流,所以它也无法撑开其父元素,造成父容器的塌陷
  • 对其他浮动元素的影响:
    同一个方向的浮动元素:当一个浮动元素在浮动过程中碰到同一个方向的浮动元素时,它会紧跟在它们后面;
    反方向的浮动元素:互不影响,位于同一条水平线上,当空间不够时会被挤下
  • 普通元素的影响:
    如果浮动元素后面兄弟元素为块级元素,该元素会忽视浮动元素的而占据它的位置,但它的内部文字和其他行内元素都会环绕浮动元素。
    但是如果后面的块元素设置了clear属性时, 会对块元素产生影响, 具体情况取决于clear的值
  • 对文字的影响:文字会环绕浮动元素排列

清除浮动

清除浮动指什么

清除浮动指元素的侧边不允许出现浮动元素,从而使得浮动元素的不占据普通文档流空间的造成的父元素的高度塌陷问题得到解决,主要通过clear属性实现。

clear:指定一个元素是否可以在它之前的浮动元素旁边,或者必须向下移动(清除浮动) 在它的下面。clear 属性适用于浮动和非浮动元素。

当应用于非浮动块时,它将非浮动块的边框边界移动到所有相关浮动元素外边界的下方。这个行为作用时会导致margin collapsing不起作用。

当应用于浮动元素时,它将元素的外边界移动到所有相关的浮动元素外边界的下方。这会影响后面浮动元素的布局,后面的浮动元素的位置无法高于它之前的元素。

方法:

  1. 设置浮动包含块的父元素height值。
  2. 使得含块的父元素变成BFC。
  3. 通过添加:after伪元素,然后在伪元素上设置clear属性来实现。

如何清除浮动

清除浮动之前,可以看到由于浮动元素脱离了文档流, 父元素塌陷了:

清除浮动之前.png
  • 添加空的div,利用clear属性清除浮动
    如果我们想让父元素在视觉上包围浮动元素可以像下面这样处理,在最后添加一个空div,利用clear属性对它清理。缺点是增加了一个无意义的标签
清除浮动之后.png
  • 利用BFC可以包含浮动的特性让父容器形成BFC,从而达到清除浮动的目的 (具体怎么形成BFC后面会介绍)

使用BFC清除浮动也有它的局限性:
使用float的时候会使父容器长度缩短,而且有个重要缺陷:父容器float解决了其塌陷问题, 那么父容器的父容器怎么办;
overflow 属性会影响滚动条和绝对定位的元素;
position 会改变元素的定位方式;
display这几种方式没有解决低版本IE的问题……

  • 最标准,无副作用的清除浮动的方法: 给需要清除浮动的父元素加上以下代码(IE6.7不支持 )
.clearfix:after{
  content:' ';
  display: block;
  clear: both;              
}                 

或者:

.clearfix:after{
  content:' ';
  display: table;
  clear: both;              
}  

定位

CSS有三种基本的定位机制:普通流,浮动,绝对定位(absolute,fixed)

普通流

普通流是默认定位方式,在普通流中元素框的位置由元素在html中的位置决定,这也是我们最常见的方式,其中position: static与position:relative属于普通流的定位方式。

相对定位可以看作特殊的普通流定位,元素位置是相对于它在普通流中位置发生变化(即相对于元素本身正常位置进行定位)。在使用相对定位时,无论元素是否移动,元素在文档流中占据原来空间 ,只是表现出来的位置会改变。

浮动

设置了浮动的元素会脱离普通流,它可以向左或者向右移动直到它碰到了包含框或者另外一个浮动的边框。浮动元素会对其他浮动元素以及它后面的普通流中的文本产生影响。

绝对定位

绝对定位的元素的位置是相对于距离最近的非static祖先元素位置决定的。如果元素没有已定位的祖先元素,那么他的位置就相对于初始包含块html来定位。
绝对定位使元素的位置与文档流无关,也不占据文档流空间,普通流中的元素布局就像绝对定位元素不存在一样。
由于绝对定位与文档流无关,所以绝对定位的元素可以覆盖页面上的其他元素,可以通过z-index属性控制叠放顺序,z-index越高,元素位置越靠上。

绝对定位的宽度是收缩的。

绝对定位包括 absolute和 fixed。fixed固定定位,固定定位是绝对定位的一种,固定定位的元素也不包含在普通文档流中,差异是固定元素的包含块儿是视窗(viewport)

CSS position属性

CSS属性 position用于指定一个元素在文档中的定位方式,position的值有以下种:

描述
inherit 从父元素继承position属性的值
static 默认值, 没有定位, 元素出现在正常的流中(此时 top, right, bottom, left 和 z-index 属性无效)
relative 生成相对定位的元素, 相对于元素本身正常位置进行定位,因此left: 20px; 会向元素的left位置添加 20px
absolute 生成绝对定位的元素,相对于static定位以外的第一个祖先元素(offset parent)进行定位,元素位置通过left,top,right以及bottom属性进行规定
fixed 生成绝对定位的元素, 相对于浏览器窗口进行定位。元素的位置通过left,top,right以及bottom属性进行规定
sticky CSS 3 新属性,兼容性差,一般用JS实现。表现类似position: relative和 position: absolute 的合体。在目标区域在屏幕中可见时,它的行为就像position: relative; 而当页面滚动超出目标区域时,它的表现就像position: fixed,它会固定在目标位置

TIPS :只有relative,absolute,fixed可以设置left,top,right,bottom 的值

position:relative 和 负margin 区别

position:relative和负margin都可以使元素位置发生偏移,二者有什么区别呢?

  • 使用position: relative对元素进行偏移时,由于元素在文档流中占据原来空间,相对自己原本的位置偏移,不影响其它普通流中元素的位置
  • 使用负margin 的话, 除了让元素自身发生偏移还影响其它普通流中的元素

BFC

BFC是什么

BFC的全称是block formatting context (块级格式化上下文),是Web页面的可视化CSS渲染出的一部分。它是块级盒布局出现的区域,也是浮动层元素进行交互的区域。
BFC是一个名词,是一个独立的布局环境,我们可以理解为一个箱子(实际上是看不见摸不着的),箱子里面物品的摆放是不受外界的影响的。

如何生成 BFC

W3C标准中这样描述:
Floats, absolutely positioned elements, block containers (such as inline-blocks, table-cells, and table-captions) that are not block boxes, and block boxes with ‘overflow’ other than ‘visible’ (except when that value has been propagated to the viewport) establish new block formatting contexts for their contents.

非块级盒子的浮动元素、绝对定位元素及块级容器(比如inline-blocks,table-cells和table-captions),以及overflow属性是visible之外任意值的块级盒子,都会创建了一个BFC。即当元素CSS属性设置了下列之一时,即可创建一个BFC:
float:left|right
position:absolute|fixed
display: table-cell|table-caption|inline-block
overflow: hidden|scroll|auto
注意:浮动不会影响其它块格式化上下文中元素的布局,并且清除浮动只能清除同一块格式化上下文中在它前面的元素的浮动。

BFC 作用

  • BFC会阻止垂直外边距(margin-top, margin-bottom)折叠
    创建了块级格式化上下文的元素,不和它的子元素发生 margin 折叠(垂直方向的)
image.png
  • BFC不会重叠浮动元素

由于浮动元素的层级比不浮动的元素层级高, 所以浮动元素会重叠后面的非浮动元素,我们只要让后面的元素形成BFC,就可以解决遮挡问题了

image.png

利用BFC使文字不再围绕浮动元素, 形成两栏布局

image.png
  • BFC清除浮动(实质是让父元素形成BFC包含浮动)
image.png

块格式化上下文对于定位与清除浮动很重要。定位和清除浮动的样式规则只适用于处于同一块格式化上下文内的元素。浮动不会影响其它块格式化上下文中元素的布局,并且清除浮动只能清除同一块格式化上下文中在它前面的元素的浮动。

外边距合并

块的顶部外边距和底部外边距有时被组合(折叠)为单个外边距,这种行为称为外边距塌陷(margin collapsing),有的地方翻译为外边距合并。

外边距合并的场景

  • 相邻的兄弟姐妹元素外边距合并
    毗邻的两个兄弟元素之间的外边距会塌陷(除非后者兄弟姐妹需要清除过去的浮动)
    例如下面box1和box2合并后的外边距是两个外边距中的较大值 40px


    相邻元素外边距合并.png
  • 块级父元素与其第一个/最后一个子元素外边距合并
    如果块级父元素中,不存在上边框、上内边距、内联元素、清除浮动这四条属性(也可以说,当上边框宽度及上内边距距离为0时),那么这个块级元素和其第一个子元素的上边距就可以说”挨到了一起“。
    此时这个块级父元素和其第一个子元素就会发生上外边距合并现象,换句话说,此时这个父元素对外展现出来的外边距将直接变成这个父元素和其第一个子元素的margin-top的较大者。
    类似的,块级父元素的 margin-bottom与它的最后一个子元素的margin-bottom之间会发生下外边距合并现象。
    下例中父元素ct 与它第一个子元素box1的外边距合并, 对外展现外边距30px


    父子外边距合并.png
  • 空块元素外边距合并
    如果存在一个空的块级元素,其 border、padding、inline content、height、min-height 都不存在。那么此时它的上下边距中间将没有任何阻隔,此时它的上下外边距将会合并
    我们先来看空元素box1没有外边距的时候,box2是紧挨body的

image.png

然后我们来给空元素box1添加外边距,这里我们为了更直观的看空元素的外边距到底会发生什么变化, 给box2也设置一个左外边距

image.png

可以看到空元素box1 的上下外边距也发生了合并

关于外边距合并,可以看下MDN 上的介绍https://developer.mozilla.org/zh-CN/docs/Web/CSS/CSS_Box_Model/Mastering_margin_collapsing

合并后外边距大小
  • 两个合并的margin都是正值的时候,其大小是其中的最大外边距;
  • 在负外边距的情况下,合并后的外边距为最大正外边距与最小负外边距(即负边距中绝对值最大的一个)之和
  • 当 margin 都是负值的时候,合并后的外边距是比较小的外边距
  • 所有毗邻的margin要一起参与运算,不能分步进行

阻止相邻元素外边距合并

不让相邻元素外边距合并的方法
  • 被非空内容、padding、border 或 clear 分隔开
  • 不在一个普通流中或一个BFC中
  • margin在垂直方向上不毗邻
实例
  • 对于父子外边距合并


    父子外边距合并了.png

(1)可以通过给父元素加border/ padding来阻止外边距合并

外边距没有合并.png

(2)创建了块级格式化上下文的元素,不和它的子元素发生 margin 折叠

image.png
  • 对于相邻块元素
    (1)浮动元素、inline-block 元素、绝对定位元素的 margin 不会和垂直方向上其他元素的 margin 折叠。所以我们只要根据需要给两个块元素添加相关属性就好了,太多了,就不截图了......
    (2)利用BFC防止margin折叠(与阻止父子外边距折叠用法有区别),见下图:
image.png

例外的情况

  • 根元素的外边距不会参与折叠
  • 不设置任何属性的空span和空div不影响任何布局,可以无视之。
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 194,242评论 5 459
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 81,769评论 2 371
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 141,484评论 0 319
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 52,133评论 1 263
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 61,007评论 4 355
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 46,080评论 1 272
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 36,496评论 3 381
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 35,190评论 0 253
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 39,464评论 1 290
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 34,549评论 2 309
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 36,330评论 1 326
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 32,205评论 3 312
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 37,567评论 3 298
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 28,889评论 0 17
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 30,160评论 1 250
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 41,475评论 2 341
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 40,650评论 2 335

推荐阅读更多精彩内容

  • 基本介绍 文档对象模型 (DOM) 是HTML和XML文档的编程接口。它给文档(结构树)提供了一个结构化的表述并且...
    草鞋弟阅读 417评论 0 0
  • 节点 节点类型 每个节点都有一个 nodeType 属性,用于表示节点类型。nodeType 属性返回节点的类型。...
    练晓习阅读 430评论 0 4
  • 题目1: dom对象的innerText和innerHTML有什么区别? innerText是一个可写属性,返回元...
    QQQQQCY阅读 179评论 0 0
  • 题目1: dom对象的innerText和innerHTML有什么区别? innerText是一个可写属性,返回元...
    Taaaaaaaurus阅读 198评论 0 1
  • 今天是行动营的最后一天,此时此刻我坐在家里吹着电扇,耳塞里是宋冬野的《安和桥》,偶然点开年少时玩伴的朋友圈,一张老...
    青豆Reborn阅读 160评论 0 0