为什么浮动div被阻止包装到容器边缘?

时间:2015-08-11 23:50:19

标签: html css

我在<div>包装器中留下了3个<div>个元素。当屏幕变窄时,第3 <div>个应该环绕并将自己定位在第1 <div>之下。然而,我遇到的是,第3 <div>只包裹到第2 <div>,我无法弄清楚原因。请检查我的CSS,并指出我出错的地方。

&#13;
&#13;
body {
  background: #d2e1ff;
  font-size: 80%;
  font-family: Verdana,Arial,sans-serif;
}
#step2 {
	min-width: 150px;
	max-width: 600px;
}
label {
  font-size: 80%;
}
input[type="text"] {
  width: 98%;
}
.element {
  float: left;
  margin-right: 3%;
  margin-bottom: 1%;
}
.element label {
  display: inline-block;
  width: 100%;
}
.column1 {
  width: 30%;
}
.column2 {
  width: 40%;
}
input#day,input#month {
  margin-right: 2%;
  width: 2em;
}
input#day,input#month,input#year {
  color: #999999;
  width: 3em;
}
@media all and (max-width:400px){
	.element {
		width: 100%;
		display: block;
	}
}
&#13;
<div id="step2">
  <div class="element column2">
    <label for="telephone">Telephone number</label>
    <input id="telephone" type="text" name="telephone">
  </div>
  <div class="element column2">
    <label for="gender">Gender</label>
    <select id="gender" name="gender">
      <option value="">Select Gender</option>
      <option value="m">Male</option>
      <option value="f">Female</option>
    </select>
  </div>
  <div class="element column1">
    <label for="day">Date of birth</label>
    <input id="day" type="text" name="day" value="dd">
    <input id="month" type="text" name="month" value="mm">
    <input id="year" type="text" name="year" value="yyyy">
  </div>
</div>
&#13;
&#13;
&#13;

2 个答案:

答案 0 :(得分:3)

这是一个有趣的行为。你是对的:认为第三个div应该一直包裹并将自己定位在第1列中的第一个div下是合理的。这就是浮点数应该如何工作。

这是一个简单的演示。三个盒子,向左漂浮。就像你的布局一样。当您调整屏幕宽度时,它们会按预期进行换行。

DEMO

这就是你所经历的:

DEMO

解决问题的方法非常简单:

  

为每个div添加height规则。

.element {
    float: left;
    margin-right: 3%;
    margin-bottom: 1%;
    height: 50px; /* This solves the problem */
}

DEMO

以下是发生的事情......

似乎来自Telephone输入字段的填充正在使div框#1略高于Gender框。这个额外的高度实际上阻止了div#3移动到容器的边缘。

在此图像中,出生日期框(左侧浮动)无法一直包裹到容器边缘。电话div阻止了它。

enter image description here

如果我们给电话输入padding: 0,则高度会降低并且障碍物被移除:

input[type="text"] { padding: 0; }

enter image description here

但是谁想要没有填充的文本字段?

这个问题有一个干净,简单而有效的解决方案,它不涉及从表单输入中删除填充:向div类添加高度规则(如上所述)。

.element { height: 50px; }

enter image description here

DEMO

第二种可能的解决方案是给div#2足够的底部边距以清除div#1的高度。

<div class="element column2" style="margin-bottom: 10px">
<!-- not necessarily recommending inline style; just for demo purposes -->

一面注意......

倒塌的容器
您的父容器(id="step2")没有包装任何内容,因为您已经浮动了子元素 - 这会将它们从normal flow中移出 - 但您没有“通知父级”。因此,您的容器div的高度为0,因为它没有内容。

要自己观察此行为,请在Chrome开发者工具中突出显示div id="step2"或在其周围添加边框。

在您的代码中,父容器id="step2"的顶部和底部边框正在触摸,因为该框没有内容,因此没有高度。

enter image description here

从实际角度来看,这意味着此容器上会丢失许多样式(尝试将背景颜色添加到#step2)。

有几种方法可以解决此问题 - 称为 clearfix methods 。在这种情况下,我使用了overflow属性。将overflow: auto添加到容器div

#step2 { overflow: auto; }

enter image description here

DEMO

希望这会有所帮助。祝你好运!

答案 1 :(得分:0)

第三个clear: left没有<div>规则。布局仅前进到第二个<div>的底部,这比第一个略短。第三个div漂浮在左边,但第一个就像在路上一样。所以它并没有一直走到边缘。

如果您对浮动的工作方式感兴趣,请参阅Introduction to floats

  

浮动框向左或向右移动,直到其边缘接触包含块边缘或另一个浮动边缘

(强调补充)

这里我添加了一些背景颜色来显示问题。我还将clear: left添加到了新的new-row类。

body {
  background: #d2e1ff;
  font-size: 80%;
  font-family: Verdana,Arial,sans-serif;
}
#step2 {
	min-width: 150px;
	max-width: 600px;
}
label {
  font-size: 80%;
}
input[type="text"] {
  width: 98%;
}
.element {
  float: left;
  margin-right: 3%;
  margin-bottom: 1%;
}
.element label {
  display: inline-block;
  width: 100%;
}
.column1 {
  width: 30%;
  background-color: lime;
}
.column2 {
  width: 40%;
  background-color: yellow;
}
.new-row {
  clear: left;
}
input#day,input#month {
  margin-right: 2%;
  width: 2em;
}
input#day,input#month,input#year {
  color: #999999;
  width: 3em;
}
@media all and (max-width:400px){
	.element {
		width: 100%;
		display: block;
	}
}
<div id="step2">
  <div class="element column2">
    <label for="telephone">Telephone number</label>
    <input id="telephone" type="text" name="telephone">
  </div>
  <div class="element column2">
    <label for="gender">Gender</label>
    <select id="gender" name="gender">
      <option value="">Select Gender</option>
      <option value="m">Male</option>
      <option value="f">Female</option>
    </select>
  </div>
  <div class="element column1 new-row">
    <label for="day">Date of birth</label>
    <input id="day" type="text" name="day" value="dd">
    <input id="month" type="text" name="month" value="mm">
    <input id="year" type="text" name="year" value="yyyy">
  </div>
</div>