首页 文章

div中的浮动元素浮动在div之外 . 为什么?

提问于
浏览
225

假设你有一个div,说你把它涂成绿色并给它一个明确的宽度,当我把东西放进去时,在我的情况下是一个img和另一个div . 这个想法是容器div的内容将导致容器div延伸,并成为内容的背景 . 但是当我这样做时,包含的div会缩小以适应非浮动对象,并且浮动对象将一直向外,或者一半,一半,并且与大div的大小没有任何关系 .

为什么是这样?有没有我缺少的东西,我怎样才能获得浮动的物品来拉伸包含div的高度?

9 回答

  • 11

    最简单的是将 overflow:hidden 放在父div上并且不指定高度:

    #parent { overflow: hidden }
    

    另一种方法是浮动父div:

    #parent { float: left; width: 100% }
    

    另一种方式使用清晰元素:

    <div class="parent">
       <img class="floated_child" src="..." />
       <span class="clear"></span>
    </div>
    

    CSS

    span.clear { clear: left; display: block; }
    
  • 8

    原因

    问题是浮动元素是out-of-flow

    如果元素浮动,绝对定位或是根元素,则称其为流出流 .

    因此,它们不会像in-flow元素那样影响周围的元素 .

    这在9.5 Floats中解释:

    由于浮动不在流中,因此在浮动框之前和之后创建的非定位块框垂直流动,就像浮动不存在一样 . 但是,根据需要缩短浮动旁边创建的当前和后续行框,以便为浮动的边距框腾出空间 .

    enter image description here

    html {
      width: 550px;
      border: 1px solid;
    }
    body {
      font-family: sans-serif;
      color: rgba(0,0,0,.15);
    }
    body:after {
      content: '';
      display: block;
      clear: both;
    }
    div {
      position: relative;
    }
    div:after {
      font-size: 200%;
      position: absolute;
      left: 0;
      right: 0;
      top: 0;
      text-align: center;
    }
    .block-sibling {
      border: 3px solid green;
    }
    .block-sibling:after {
      content: 'Block sibling';
      color: green;
    }
    .float {
      float: left;
      border: 3px solid red;
      height: 90px;
      width: 150px;
      z-index: 1;
    }
    .float:after {
      content: 'Float';
      color: red;
    }
    
    <div class="float"></div>
    <div class="block-sibling">
      Lorem ipsum dolor sit amet, consectetur adipiscing elit. Donec a diam lectus. Sed sit amet ipsum mauris. Maecenas congue ligula ac quam viverra nec consectetur ante hendrerit. Donec et mollis dolor. Praesent et diam eget libero egestas mattis sit amet vitae augue. Nam tincidunt congue enim, ut porta lorem lacinia consectetur. Donec ut libero sed arcu vehicula ultricies a non tortor.
    </div>
    

    这也在10.6 Calculating heights and margins中指定 . 对于"normal" blocks

    只考虑正常流量的儿童(即浮动框和绝对定位的框被忽略[...])

    enter image description here

    html {
      width: 550px;
      border: 1px solid;
    }
    body {
      font-family: sans-serif;
      color: rgba(0,0,0,.15);
    }
    body:after {
      content: '';
      display: block;
      clear: both;
    }
    div {
      position: relative;
    }
    div:after {
      font-size: 200%;
      position: absolute;
      left: 0;
      right: 0;
      top: 0;
      text-align: center;
    }
    .block-parent {
      border: 3px solid blue;
    }
    .block-parent:after {
      content: 'Block parent';
      color: blue;
    }
    .float {
      float: left;
      border: 3px solid red;
      height: 130px;
      width: 150px;
    }
    .float:after {
      content: 'Float';
      color: red;
    }
    
    <div class="block-parent">
      <div class="float"></div>
      Lorem ipsum dolor sit amet, consectetur adipiscing elit. Donec a diam lectus. Sed sit amet ipsum mauris. Maecenas congue ligula ac quam viverra nec consectetur ante hendrerit.
    </div>
    

    Hacky解决方案:清除

    解决问题的一种方法是强制将一些流入元素放置在所有浮点下面 . 然后,父级的高度将增长以包裹该元素(因此浮动也是如此) .

    这可以使用the clear property来实现:

    此属性指示元素框的哪些边可能不与较早的浮动框相邻 .

    enter image description here

    html {
      width: 550px;
      border: 1px solid;
    }
    body {
      font-family: sans-serif;
      color: rgba(0,0,0,.15);
    }
    body:after {
      content: '';
      display: block;
      clear: both;
    }
    div {
      position: relative;
    }
    div:after {
      font-size: 200%;
      position: absolute;
      left: 0;
      right: 0;
      top: 0;
      text-align: center;
    }
    .block-parent {
      border: 3px solid blue;
    }
    .block-parent:after {
      content: 'Block parent';
      color: blue;
    }
    .float {
      float: left;
      border: 3px solid red;
      height: 84px;
      width: 150px;
    }
    .float:after {
      content: 'Float';
      color: red;
    }
    .clear {
      clear: both;
      text-align: center;
      height: 37px;
      border: 3px dashed pink;
    }
    .clear:after {
      position: static;
      content: 'Block sibling with clearance';
      color: pink;
    }
    
    <div class="block-parent">
      <div class="float"></div>
      Lorem ipsum dolor sit amet, consectetur adipiscing elit. Donec a diam lectus. Sed sit amet ipsum mauris. Maecenas congue ligula ac quam viverra.
      <div class="clear"></div>
    </div>
    

    因此,解决方案是添加一个空元素,其中 clear: both 作为浮点数的最后一个兄弟

    <div style="clear: both"></div>
    

    但是,这不是语义上的 . 因此,最好在父节点的末尾生成pseudo-element

    .clearfix::after {
      clear: both;
      display: block;
    }
    

    这种方法有多种变体,例如使用不推荐的单冒号语法 :after 来支持旧浏览器,或使用其他block-level显示,如 display: table .

    解决方案:BFC根源

    开头定义的问题行为有一个例外:如果块元素 Build Block Formatting Context(是BFC根),那么它也会包装其浮动内容 .

    根据10.6.7 'Auto' heights for block formatting context roots

    如果元素具有任何浮动后代,其下边距边缘低于元素的底部内容边缘,则增加高度以包括这些边 .

    enter image description here

    html {
      width: 550px;
      border: 1px solid;
    }
    body {
      font-family: sans-serif;
      color: rgba(0,0,0,.15);
    }
    body:after {
      content: '';
      display: block;
      clear: both;
    }
    div {
      position: relative;
    }
    div:after {
      font-size: 200%;
      position: absolute;
      left: 0;
      right: 0;
      top: 0;
      text-align: center;
    }
    .block-parent {
      border: 3px solid blue;
    }
    .block-parent.bfc-root:after {
      content: 'BFC parent';
      color: blue;
    }
    .float {
      float: left;
      border: 3px solid red;
      height: 127px;
      width: 150px;
    }
    .float:after {
      content: 'Float';
      color: red;
    }
    .bfc-root {
      overflow: hidden;
    }
    
    <div class="block-parent bfc-root">
      <div class="float"></div>
      Lorem ipsum dolor sit amet, consectetur adipiscing elit. Donec a diam lectus. Sed sit amet ipsum mauris. Maecenas congue ligula ac quam viverra nec consectetur ante hendrerit.
    </div>
    

    另外,正如9.5 Floats所解释的那样,由于以下原因,BFC根也很有用:

    表格的边框,块级替换元素或正常流程中 Build 新块格式上下文的元素[...]不得与同一块格式化上下文中任何浮点数的边距框重叠 . 本身 .

    enter image description here

    html {
      width: 550px;
      border: 1px solid;
    }
    body {
      font-family: sans-serif;
      color: rgba(0,0,0,.15);
    }
    body:after {
      content: '';
      display: block;
      clear: both;
    }
    div {
      position: relative;
    }
    div:after {
      font-size: 200%;
      position: absolute;
      left: 0;
      right: 0;
      top: 0;
      text-align: center;
    }
    .block-sibling {
      border: 3px solid green;
    }
    .block-sibling.bfc-root:after {
      content: 'BFC sibling';
      color: green;
    }
    .float {
      float: left;
      border: 3px solid red;
      height: 90px;
      width: 150px;
      z-index: 1;
    }
    .float:after {
      content: 'Float';
      color: red;
    }
    .bfc-root {
      overflow: hidden;
    }
    
    <div class="float"></div>
    <div class="block-sibling bfc-root">
      Lorem ipsum dolor sit amet, consectetur adipiscing elit. Donec a diam lectus. Sed sit amet ipsum mauris. Maecenas congue ligula ac quam viverra nec consectetur ante hendrerit. Donec et mollis dolor. Praesent et diam eget libero egestas mattis sit amet vitae augue. Nam tincidunt congue enim, ut porta lorem lacinia consectetur.
    </div>
    

    块格式化上下文由 . Build

    .bfc-root {
      overflow: hidden;
      /* display: block; */
    }
    
    • 阻止非块框的容器:display设置为 inline-blocktable-celltable-caption 时 .
    .bfc-root {
      display: inline-block;
    }
    
    • 浮动元素:float设置为 leftright 时 .
    .bfc-root {
      float: left;
    }
    
    • 绝对定位的元素:当position设置为 absolutefixed 时 .
    .bfc-root {
      position: absolute;
    }
    

    请注意,这些可能会产生不希望的附带效果,例如剪切溢出的内容,使用shrink-to-fit算法计算自动宽度或变得不流动 . 所以问题在于,不可能有一个具有可见溢出的流内块级元素来 Build BFC .

    Display L3解决了这些问题:

    创建了flow和flow-root内部显示类型,以更好地表达流布局显示类型,并创建一个显式开关,使元素成为BFC根 . (这应该消除像:: clear:both;}和overflow:hidden [...]之类的:: hack的需求 .

    可悲的是,目前还没有浏览器支持 . 最终我们可以使用

    .bfc-root {
      display: flow-root;
    }
    
  • 133

    把你的浮动 div(s) 放在 div 中并在CSS中给它 overflow:hidden;
    它会工作正常 .

  • 4

    没有什么遗漏 . Float是为您希望图像(例如)放在几段文本旁边的情况而设计的,因此文本会围绕图像流动 . 如果文本“拉伸”容器,那就不会发生 . 你的第一段将结束,然后你的下一段将在图像下开始(可能是几百个下面的像素) .

    这就是为什么你得到的结果 .

  • 340

    W3Schools推荐:

    overflow: auto 放在父元素上,它将"color"整个背景,包括元素边距 . 浮动元素也将留在边界内 .

    http://www.w3schools.com/css/tryit.asp?filename=trycss_layout_clearfix

  • 11

    在某些情况下,即 when (if) 你只是使用 float 让元素在同一个"line"上流动,你可能会使用

    display: inline-block;
    

    代替

    float: left;
    

    否则,在最后使用 clear 元素工作,即使它可能违背谷物需要一个元素来做应该是CSS的工作 .

  • 6

    谢谢 LSerni 你为我解决了 .

    为达到这个 :

    +-----------------------------------------+
    | +-------+                     +-------+ |
    | | Text1 |                     | Text1 | |
    | +-------+                     +-------+ |
    |+----------------------------------------+
    

    你必须这样做:

    <div style="overflow:auto">
        <div style="display:inline-block;float:left"> Text1 </div>
        <div style="display:inline-block;float:right"> Text2 </div>
    </div>
    
  • 19

    这是更现代的方法:

    .parent {display: flow-root;}
    

    没有更多明确的修正 .

    附:使用溢出:隐藏;隐藏盒子阴影所以......

  • 5

    正如Lucas所说,你所描述的是float属性的预期行为 . 令许多人感到困惑的是,为了弥补CSS布局模型中的缺点,浮动已经远远超出其原始预期用途 .

    如果您希望更好地了解此属性的工作原理,请查看Floatutorial .

相关问题