浮动、定位、BFC、外边距合并

一、浮动元素有什么特征?对父容器、其他浮动元素、普通元素、文字分别有什么影响?

float指定一个元素沿着其容器左侧或者右侧放置,允许行内元素和文本围绕它。使用后,该元素会从正常流动中移除,虽然还会保持一定流动性(两个浮动碰到一起)。由于元素浮动后,脱离了普通文档流,并且一直左移或者右移直到碰到父元素边框或者另一个浮动元素才停止(一行占满会自动换行),所以,浮动元素会覆盖在普通文档流元素之上(如果有的话)。而且,父元素也会塌陷,不再包裹得住浮动元素。

参考:float | MDN

二、清除浮动指什么? 如何清除浮动? 两种以上方法

清除浮动,可以通过clear: left | right | both实现。或者对目标元素转换成不同的 BFC ,BFC后面再说,这里主要通过clear: both解决。直接上代码

1. 直接使用clear: both清除浮动,主要用于兄弟元素情况。

<style>
  .div1 {
    float: left;
    background-color: #333;
  }
  
  .div1,.div2 {
    width: 150px;
    height: 150px;
  }
    
  .div2 {
    background-color: #f03;
    clear: both;
  }
</style>
  <div class="div1"></div>
  <div class="div2"></div>

在线演示

2. 通过加一个额外标签,阻止父元素塌陷。

<style>
    .div1 {
        float: left;
        background-color: #333;
      }
  
    .div1,.div2 {
      width: 150px;
      height: 150px;
    }
    
    .div2 {
      background-color: #f03;
    }
  
    .clear {
      clear: both;
    }
</style>
<div class="div0">
  <div class="div1"></div>
  <div class="clear"></div>
</div>
<div class="div2"></div>

在线演示

3. 通过为父元素添加overflow:hidden来阻止父元素塌陷。

<style>
  .div0 {
    overflow: hidden;
  }
  
  .div1 {
    float: left;
    background-color: #333;
  }
  .div1,.div2 {
    width: 150px;
    height: 150px;
  }
  .div2 {
    background-color: #f00;
  }
</style>
<div class="div0">
  <div class="div1"></div>
</div>
<div class="div2"></div>

在线演示

三、有几种定位方式,分别是如何实现定位的,参考点是什么,使用场景是什么?

定位有四种:static --> 静态定位relative --> 相对定位absolute --> 绝对定位fixed --> 固定定位,下面详细说。

1. 静态定位。

positon: static其实就是元素默认值,正常的文档流。

2. 相对定位

position: relative是比静态定位强大一点点的定位。假如不为元素加上top、bottom、left、right,那么它表现得和静态定位一模一样。所以说它就是在静态定位的基础上多了个可选择移动效果,但在移动后,如top: 20px; left: 20px,该元素占据的空间还是原来位置,只是展示效果平移了而已,所以这样有可能覆盖其他元素。应用于不想脱离文档流,但又想平移的场景,同时relative也是absolute的参考对象,后面说。现在看个例子:

<style>
  div {
    display: inline-block;
    width: 200px;
    height: 200px;
  }
  
  .div1 {
    background-color: #333;
  }
  .div2 {
    background-color: #f00;
    position: relative;
    left: 20px;
    top: 20px;
  }
  .div3 {
    background-color: #0f0;
  }
</style>
<div class="div1"></div>
<div class="div2"></div>
<div class="div3"></div>

在线演示

3. 绝对定位

postion: absolute会使元素脱离文档流,变得无比强大,只有一个样式能束缚它,position: relative。所以要清楚的知道,绝对定位可以到处跑,但相对定位就是它的边界,就像悟空逃不出佛祖一样。如果父元素一直没有relative,它就会继续往上找,直到找到根元素或者relative祖先元素。与相对定位相比,绝对定位不再占据空间,可随意覆盖在任意元素上,只要它的z-index够大(z-inde后面说),举个例子:

<style>
  div {
    display: inline-block;
    width: 200px;
    height: 200px;
  }
  
  .div1 {
    background-color: #333;
  }
  .div2 {
    background-color: #f00;
    position: absolute;
    left: 20px;
    top: 20px;
  }
  .div3 {
    background-color: #0f0;
  }
</style>
<div class="div1"></div>
<div class="div2"></div>
<div class="div3"></div>

在线演示

4. 固定定位

position: fixed与绝对定位非常相似,除了两点:

  • 不再受到束缚,可自由翱翔。
  • 活动范围有限制,永远显示在当前浏览器视窗范围内。

举个例子:

<style>
  body{
    margin: 0;
  }
  .div1,.div2,.div3 {
    width: 100%;
    height: 500px;
  }
  .div1 {
    background-color: #333;
  }
  .div2 {
    background-color: #f00;
  }
  .div3 {
    background-color: #0f0;
  }
  .fixed {
    position: fixed;
    top: 0;
    left: 50%;
   
    
    margin-left: -100px;
    width: 200px;
    padding: 15px 0;
    border: 2px solid;
    text-align: center;
    background-color: #fff;
  }
</style>
<div class="div1"></div>
<div class="div2"></div>
<div class="div3"></div>
<div class="fixed">我就一直在这里</div>

在线演示

参考: 定位 | MDN

四、z-index有什么作用? 如何使用?

1. 没有z-index情况

你是否会有这个疑惑,当各种定位都跑到一起的时候,该显示谁呢?答案是:在没有z-index干扰之前,根据顺序显示,谁在最后,显示谁,举个例子:

  <style>
    body {
      margin: 0;
      font-size: 0;
    }
    div {
      display: inline-block;
      width: 200px;
      height: 200px;
    }
    
    .div1 {
      position: static;
      background-color: #333; 
    }
    
    .div2 {
      position: relative;
      background-color: #f00;
    }
    
    .div3 {
      position: absolute;
      background-color: #0f0;
      top: 0;
      left: 50px;
    }
    
    .div4 {
      position: fixed;
      background-color: #00f;
      top: 0;
      left: 300px;
    }
  </style>
  <div class="div1"></div>
  <div class="div2">
    <div class="div3"></div>
  </div>
  <div class="div4"></div>

在线演示

2. 开始使用z-index

那有没有一种办法,让前面的元素先显示呢?这就是z-index的作用了,默认定位的z-index: 0;为零(其实不是零,而是不存在,不存在和零在这里意思是不同的,下面分析)。谁的z-index大,就显示谁,还是刚才的例子,只不过加多一个z-index

/* 在 div3 那里加上 */
.div3 {
  z-index: 1;
}

在线演示
此时,div3应该跑出来了,不再被div4困住。想要div4再次显示,需要给div4加上z-index: 2(或者为 1 也可以,z-index相同,根据顺序显示)。因为,只要z-index比别人大 1 ,就可以达到覆盖效果,所以最好不要乱用,像直接写z-index: 9999这种是十分不妥的,万一以后你想覆盖它怎么办?而且要记住,只有当靠前的元素向覆盖后面的元素才用z-index,因为如果元素本来就是在最后,根据顺序显示,是无须加z-index的。

3. z-index: 0 和 默认没有(不写)z-index为什么不同

只要你设置了z-index,那么在为定位判断z-index时,要明白:只能在兄弟元素之间比较。举个例子:

  <style>
    body {
      margin: 0;
      font-size: 0;
    }
    div {
      display: inline-block;
      width: 200px;
      height: 200px;
    }
    
    .div1 {
      position: static;
      background-color: #333; 
    }
    
    .div2 {
      position: relative;
      background-color: #f00;
      z-index: 0;
    }
    
    .div3 {
      position: absolute;
      background-color: #0f0;
      top: 0;
      left: 50px;
      z-index: 999;
    }
    
    .div4 {
      position: fixed;
      background-color: #00f;
      top: 0;
      left: 300px;
      z-index: 2;
    }
  </style>
  <div class="div1"></div>
  <div class="div2">
    <div class="div3"></div>
  </div>
  <div class="div4"></div>

在线演示

在上面的例子中,可以看到,绝对定位(positon: absolute)已经有z-index: 999,比固定定位(positon: fixed)的z-index: 2大得多,但因为相对定位(position: relative)的z-index只有 0 ,因此绝对定位无法实现最顶覆盖。但如果相对定位(position:relative)不写z-index的话,结果又会是不一样的了,各位可自行测试。

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

相对定位(postition: relative)的使用,不但使元素保持文档流,而且使用top、bottom、left、right位移也不会改变本身占据空间位置。而负margin是静态定位(position: static)位移的小技巧,是会让元素本身位置发生改变的,使用在相对定位上也有同样效果。看例子:

<style>
  body {
    margin: 0;
    padding-left: 100px;
  }
  .inline-block {
    display: inline-block;
    width: 200px;
    height: 200px;
    background-color: #333;
  }
  .div1 {
    position: relative;
    top: 0;
    left: -20px;
    /* margin-left: -20px; */
  }
  .div2 {
    margin-left: -20px;
  }
</style>
<div class="inline-block div1"></div>
<div class="inline-block"></div>
<div></div>
<div class="inline-block div2"></div>
<div class="inline-block"></div>

在线演示

记住,对相对元素使用负margin也是会使元素本身位置发生改变的,因为相对定位还是文档流。

六、BFC 是什么?如何生成 BFC ?BFC 有什么作用?举例说明

BFC(Block Formatting Context),译为块格式化上下文,说实话,这晦涩的翻译会让人更加困惑这个定义,且看我们怎么逐层分解!

1. 何为 BFC ?

首先要明白,BFC 指的是一个虚拟区域,一个块级盒布局区域,,可以说是一个环境每个区域间相互不受影响。当你使用了以下元素时,你就为这个元素开辟了一个 BFC 保护区,用来保护这个元素。 参考:块格式上下文 | MDN

  • 根元素或者其他包含它的元素(document
  • 浮动元素(元素的float不是none
  • 绝对定位元素(positionabsolute或者fixed
  • 内联块状元素(display: inline-block
  • 表格单元格(display: table-cell
  • 表格标题(display: table-caption
  • overflow值不是visible的块元素(默认就是overflow: visible

特别地,当里面元素都是行内元素或者文本时,创建出来的 BFC 就是 IFC(Inline Formatting Context)。

2. 如何理解 BFC ?

CSS 的渲染是从上往下排列元素块的,最大的 BFC 就是 Document,在它里面的元素都要遵守他的规则。但 Document 里面允许创建新的 BFC,这些新的 BFC 会为自己内部建立新的规则,而且每个 BFC 之间不会相互干扰(就是基于这点解决外边距合并和清除浮动的)。形象的理解就是, Document 是国家;普通块元素是市(overflow: visible);新的 BFC 是省、直辖市(float、absolute、inline-block),他们允许有自己规则。

3. BFC 作用。

解决外边距合并和清除浮动。外边距合并下面说,现在说说清除浮动。

阻止浮动元素对其他元素的影响,可以为浮动元素新创建 BFC ,这样浮动元素就不会影响外部元素了,如下,通过overflow: hidden创建了 BFC(虽然本身float也创建了 BFC ,但因为它在父元素内部,不会影响父元素外部的元素),阻止其影响其他元素:

<style>
  .div0 {
    overflow: hidden;
  }
  
  .float {
    float: left;
    background: #333;
  }
  
  .float,.div1 {
    width: 200px;
    height: 200px;
  }
  
  .div1 {
    background: #f00;
  }
</style>
<div class="div0">
  <div class="float"></div>
  <div class="float"></div>
</div>
<div class="div1"></div>

在线演示

参考:
什么是 BFC | Div.IO
关于 BFC | 穆乙
CSS 布局 | winter

七、在什么场景下会出现外边距合并?如何合并?如何不让相邻元素外边距合并?给个父子外边距合并的范例

1. 何为外边距合并?

外边距合并(margin collapsing),准确来说,是外边距塌陷。指的是 BFC 中相邻的另个块盒子的左右边距和上下边距发送叠加,两者取最大值:

<style>
  div {
    width: 200px;
    height: 200px;
    background: #333;
    margin: 100px;
  }
</style>
<div></div>
<div></div>

在线预览

在上面例子中,两个<div>之间的间距只有100px,没有达到预想中的200px,这就是外边距合并。

2. 如何解决外边距合并?

a. 首先要明确,外边距合并只会发生在 BFC, 所以当前规则是 IFC 的话,就不会出现这种情况了,看例子:

<style>
  div {
    display: inline-block;
    width: 200px;
    height: 200px;
    background-color: #333;
    margin: 100px;
  }
</style>
<div></div>
<div></div>
<div></div>
<div></div>

b. 全部都是浮动元素不会出现外边距合并

  <style>
    div {
      float: left;
      width: 200px;
      height: 200px;
      background-color: #333;
      margin: 100px;
    }
  </style>
  <div></div>
  <div></div>
  <div></div>
  <div></div>

在线预览

c. 利用 BFC 来阻止合并

我们已经知道 BFC 之间不会相互影响,所以让外边距合并的元素各自创建一个 BFC ,就可以解决该问题

  <style>
    .div1 {
      width: 200px;
      height: 200px;
      margin: 100px;
      background-color: #333;
    }
    .div0 {
      overflow: hidden;
    }
  </style>
  <div class="div0">
    <div class="div1"></div>
  </div>
  <div class="div1"></div>

在线预览

在上面例子,我们只建立了一个 BFC ,overflow: hidden建立。因为这个 BFC 不会影响的外边的其他元素,所以效果就达到了。其实,在清除浮动的时候,在相邻的非浮动元素加上overflow: hidden达到清除浮动效果,也是这个原理,因为float脱离了文档流,但建立了新的 BFC,所以我们为受影响的元素创建 BFC 的话,根据 BFC 之间不会相互影响的规则,就可以达到清除浮动效果。如下例子:

  <style>
    body {
      margin: 0;
      padding: 1px;
    }
    div {
      width: 200px;
      height: 200px;
      background: #333;
      margin: 20px;
    }
    .float {
      float: left;
    }
    .normal {
      overflow: hidden;
    }
  </style>
  <div class="float"></div>
  <div class="normal"></div>

在线预览

d. 当容器没有paddingborder时,内部的margin会引发外边距合并(父子外边距合并)

这是一种很难发现的情况,但外边距合并是会被内边距padding阻止的,所以给父元素加1px的内边距可以解决问题。或者为这个子元素建立新的 BFC,即在父元素加overflow: hidden(其他也可以)。

  <style>
    .div0 {
      margin: 100px;
      background: red;
      padding: 1px;
      /* overflow: hidden; */
    }
      .div1 {
        width: 200px;
        height: 200px;
        background-color: #333;
        margin: 150px;
      }
  </style>
  <div class="div0">
    <div class="div1"></div>
  </div>

在线预览
参考:
谈外边距合并 | winter
外边距合并 | MDN

八、编程任务

任务十 | GitHub

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

推荐阅读更多精彩内容

  • 1. 浮动元素有什么特征?对父容器、其他浮动元素、普通元素、文字分别有什么影响? 浮动元素脱离了普通文档流。如果父...
    从这到那阅读 413评论 0 0
  • relative:生成相对定位的元素,通过top,bottom,left,right的位置相对于其正常位置进行定位...
    zx9426阅读 930评论 0 2
  • 一,浮动元素有什么特征?对父容器、其他浮动元素、普通元素、文字分别有什么影响? 浮动模型是一种可视化格式模型,浮动...
    DeeJay_Y阅读 858评论 0 4
  • 问答题47 /72 常见浏览器兼容性问题与解决方案? 参考答案 (1)浏览器兼容问题一:不同浏览器的标签默认的外补...
    _Yfling阅读 13,728评论 1 92
  • 浮动元素有什么特征?对父容器、其他浮动元素、普通元素、文字分别有什么影响? 特征: 脱离正常文档流,沿其容器的左侧...
    _Dot912阅读 706评论 0 3