Html div 内浮动元素,div 外浮动。为什么?

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/2062258/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-29 01:51:02  来源:igfitidea点击:

Floating elements within a div, floats outside of div. Why?

csshtmlcss-float

提问by DavidR

Say you have a div, give it a definite widthand put elements in it, in my case an imgand another div.

假设你有一个div,给它一个明确的width并在其中放入元素,在我的情况下是 animg和 another div

The idea is that the content of the container divwill cause the container divto stretch out, and be a background for the content. But when I do this, the containing divshrinks to fit the non-floating objects, and the floating objects will be either all the way out, or half out, half in, and not have any bearing on the size of the big div.

这个想法是容器的内容div会导致容器div伸展,并成为内容的背景。但是当我这样做时,包含会div缩小以适应非浮动对象,并且浮动对象将要么完全伸出,要么一半伸出一半,并且与 big div.

Why is this? Is there something I'm missing, and how can I get floated items to stretch out the heightof a containing div?

为什么是这样?有什么我遗漏的,我怎样才能让浮动的项目伸出height包含的东西div

回答by Doug Neiner

The easiest is to put overflow:hiddenon the parent div and don't specify a height:

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

#parent { overflow: hidden }

Another way is to also float the parent div:

另一种方法是也浮动父div:

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

Another way uses a clear element:

另一种方法是使用 clear 元素:

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

CSS

CSS

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

回答by Oriol

Reason

原因

The problem is that floating elements are out-of-flow:

问题是浮动元素是流出的

An element is called out of flowif it is floated, absolutely positioned, or is the root element.

如果元素是浮动的、绝对定位的或者是根元素,则该元素被称为流外元素。

Therefore, they don't impact surrounding elements as an in-flowelement would.

因此,它们不会像流入元素那样影响周围的元素。

This is explained in 9.5 Floats:

这在9.5 Floats 中有解释:

Since a float is not in the flow, non-positioned block boxes created before and after the float box flow vertically as if the float did not exist. However, the current and subsequent line boxes created next to the float are shortened as necessary to make room for the margin box of the float.

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

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>

This is also specified in 10.6 Calculating heights and margins. For "normal" blocks,

这也在10.6 计算高度和边距中指定。对于“正常”块

Only children in the normal flow are taken into account (i.e., floating boxes and absolutely positioned boxes are ignored […])

只考虑正常流中的孩子(即,忽略浮动框和绝对定位框 [...])

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 solution: clearance

hacky 解决方案:清除

A way to solve the problem is forcing some in-flow element to be placed below all floats. Then, the height of the parent will grow to wrap that element (and thus the floats too).

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

This can be achieved using the clearproperty:

这可以通过使用来实现clear属性

This property indicates which sides of an element's box(es) may notbe adjacent to an earlier floating box.

此属性指示元素框的哪一侧可能与较早的浮动框相邻。

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>

So a solution is adding an empty element with clear: bothas the last sibling of the floats

所以一个解决方案是添加一个空元素clear: both作为浮动的最后一个兄弟

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

However, that is not semantic. So better generate a pseudo-elementat the end of the parent:

然而,这不是语义。所以最好在父元素的末尾生成一个伪元素

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

There are multiple variants of this approach, e.g. using the deprecated single colon syntax :afterto support old browsers, or using other block-leveldisplays like display: table.

这种方法有多种变体,例如使用已弃用的单冒号语法:after来支持旧浏览器,或使用其他块级显示,如display: table.

Solution: BFC roots

解决方案:BFC 根

There is an exception to the problematic behavior defined at the beginning: if a block element establishes a Block Formatting Context(is a BFC root), then it will also wrap its floating contents.

开头定义的有问题的行为有一个例外:如果一个块元素建立了一个块格式上下文(是一个 BFC 根),那么它也会包装它的浮动内容。

According to 10.6.7 'Auto' heights for block formatting context roots,

根据10.6.7 块格式上下文根的“自动”高度

If the element has any floating descendants whose bottom margin edge is below the element's bottom content edge, then the height is increased to include those edges.

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

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>

Additionally, as explained 9.5 Floats, BFC roots are also useful because of the following:

此外,如9.5 Floats 所述,BFC 根也很有用,因为以下原因:

The border box of a table, a block-level replaced element, or an element in the normal flow that establishes a new block formatting context […] must not overlap the margin box of any floats in the same block formatting context as the element itself.

表格的边框框、块级替换元素或正常流程中建立新的块格式上下文的元素 [...] 不得与元素本身在同一块格式上下文中的任何浮动的边距框重叠.

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>

A block formatting context is established by

块格式化上下文由

  • Block boxes with overflowother than visible, e.g. hidden

    .bfc-root {
      overflow: hidden;
      /* display: block; */
    }
    
  • Block containers that are not block boxes: when displayis set to inline-block, table-cellor table-caption.

    .bfc-root {
      display: inline-block;
    }
    
  • Floating elements: when floatis set to leftor right.

    .bfc-root {
      float: left;
    }
    
  • Absolutely positioned elements: when positionis set to absoluteor fixed.

    .bfc-root {
      position: absolute;
    }
    
  • 块框overflow除了visible,例如hidden

    .bfc-root {
      overflow: hidden;
      /* display: block; */
    }
    
  • 不是块框的块容器:whendisplay设置为inline-block,table-celltable-caption

    .bfc-root {
      display: inline-block;
    }
    
  • 浮动元素:whenfloat设置为leftright

    .bfc-root {
      float: left;
    }
    
  • 绝对定位元素:whenposition设置为absolutefixed

    .bfc-root {
      position: absolute;
    }
    

Note those may have undesired collateral effects, like clipping overflowing content, calculating auto widths with the shrink-to-fitalgorithm, or becoming out-of-flow. So the problem is that it's not possible to have an in-flow block-level element with visible overflow that establishes a BFC.

请注意,这些可能会产生不希望的附带影响,例如剪裁溢出的内容、使用收缩以适应算法计算自动宽度或变得不流动。所以问题是不可能有一个具有可见溢出的流入块级元素来建立 BFC。

Display L3addresses these issues:

Display L3解决了这些问题:

Created the flowand flow-rootinner display typesto better express flow layout display typesand to create an explicit switch for making an element a BFCroot. (This should eliminate the need for hacks like ::after { clear: both; }and overflow: hidden[…])

创建flow内部显示类型以更好地表达流布局显示类型并创建显式开关以使元素成为BFC根。(这应该消除对像和[...] 之类的黑客攻击的需要)flow-root::after { clear: both; }overflow: hidden

Sadly, there is no browser support yet. Eventually we may be able to use

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

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

回答by Nad

Put your floating div(s)in a divand in CSS give it overflow:hidden;
it will work fine.

把你的浮动div(s)放在 adiv和 CSS 中,overflow:hidden;
让它可以正常工作。

回答by mggluscevic

W3Schools recommendation:

W3Schools 推荐:

put overflow: autoon parent element and it will "color" whole background including elements margins. Also floating elements will stay inside of border.

放在overflow: auto父元素上,它将“着色”整个背景,包括元素边距。浮动元素也将留在边界内。

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

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

回答by LSerni

In some cases, i.e. when (if)you're just using floatto have elements flow on the same "line", you might use

在某些情况下,即当(如果)您只是float用来让元素在同一“行”上流动时,您可能会使用

display: inline-block;

instead of

代替

float: left;

Otherwise, using a clearelement at the end works, even if it may go against the grain to need an element to do what should be CSS work.

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

回答by Lucas Wilson-Richter

There's nothing missing. Float was designed for the case where you want an image (for example) to sit beside several paragraphs of text, so the text flows around the image. That wouldn't happen if the text "stretched" the container. Your first paragraph would end, and then your next paragraph would begin under the image (possibly several hundred pixels below).

什么都不缺。Float 是为您希望图像(例如)位于多段文本旁边的情况而设计的,因此文本在图像周围流动。如果文本“拉伸”了容器,则不会发生这种情况。您的第一段将结束,然后您的下一段将在图像下方开始(可能在下方数百个像素)。

And that's why you're getting the result you are.

这就是为什么你会得到你现在的结果。

回答by pendingfox

Here's more modern approach:

这是更现代的方法:

.parent {display: flow-root;} 

No more clearfixes.

没有更多的清除修复。

p.s. Using overflow: hidden; hides the box-shadow so...

ps 使用溢出:隐藏;隐藏框阴影所以......

回答by Flyout91

Thank you LSerniyou solved it for me.

谢谢LSerni,你帮我解决了。

To achieve this :

为达到这个 :

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

You have to do this :

你必须这样做:

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

回答by Sam Murray-Sutton

As Lucas says, what you are describing is the intended behaviour for the float property. What confuses many people is that float has been pushed well beyond its original intended usage in order to make up for shortcomings in the CSS layout model.

正如卢卡斯所说,您所描述的是 float 属性的预期行为。让很多人感到困惑的是,为了弥补 CSS 布局模型中的缺点,浮动已经远远超出了其最初的预期用途。

Have a look at Floatutorialif you'd like to get a better understanding of how this property works.

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

回答by Vijay Tiwari

You can easily do with first you can make the div flex and apply justify content right or left and your problem is solved.

您可以轻松地首先让 div flex 并向右或向左应用对齐内容,然后您的问题就解决了。

<div style="display: flex;padding-bottom: 8px;justify-content: flex-end;">
     <button style="font-weight: bold;outline: none;background-color: #2764ff;border-radius: 3px;margin-left: 12px;border: none;padding: 3px 6px;color: white;text-align: center;font-family: 'Open Sans', sans-serif;text-decoration: none;margin-right: 14px;">Sense</button>
    </div>