内部div浮动到下一行

3

我正在尝试使用div创建一个组合控件,其中包含:

  1. 标签
  2. 文本框

HTML

* {
  -webkit-box-sizing: border-box;
  -moz-box-sizing: border-box;
  box-sizing: border-box;
}
.form-control {
  background-color: yellow;
  margin: 0;
  padding: 0;
}
.form-control[data-layoutOrder=horizontal] div[data-section=title] {
  display: inline-block;
  background-color: red;
  width: 50%;
  margin: 0;
  padding: 0;
}
.form-control div[data-section=data] {
  background-color: green;
  display: inline-block;
  width: 50%;
  margin: 0;
  padding: 0;
}
<div class="form-control" data-layoutOrder="horizontal">
  <div data-section="title">
    <label for="firstName">First Name</label>
  </div>
  <div data-section="data">
    <input type="text" placeholder="First Name" id="firstName">
  </div>
</div>

上述代码的输出应该是标签和输入框相邻,但实际情况并非如此。包裹文本框的 div 实际上浮动到了下一行,尽管我已经使用 CSS 将标签 div 和文本框 div 的宽度都设置为了 50%。
我尝试将 padding、margin 等设置为 0,但都没有起作用。是什么原因导致文本框 div 浮动到了下一行呢?当我将其中一个 div 的宽度改为 49% 时,两个 div 就可以在同一行上对齐了。我不明白为什么会这样,是否真的需要使用 float 呢?或者我遗漏了些什么。
注意:我可以使用 float 属性让它们相邻 - 对于标签 div 使用 "float:left" & 对于文本框 div 使用 "float:right" 属性。但是我想知道为什么未使用 float 将宽度设置为 50% 不起作用。我真的需要使用 float 吗?还是我遗漏了什么。
编辑 1: 我发现另一个解决方案是使用 "white-space" 属性。
.form-control {
background-color: yellow;
margin:0;
padding:0;
white-space:nowrap;
}

.form-control div[data-section=data] {
background-color : green;
display: inline-block;
width: 50%;
margin:0;
padding:0;
white-space:normal;
}

EDIT 2: 使用 flex 样式也有预期效果。在搜索更多内容时,我还发现可以使用 flex 样式实现相同的效果。请注意,它不支持 IE 10 及以下版本。请参考 caniuse
.form-control {
  background-color: yellow;
  margin: 0;
  padding: 0;
  display: flex;
  display: -webkit-flex;
}
.form-control[data-layoutOrder=horizontal] div[data-section=title] {
  display: inline-block;
  background-color: red;
  width: 50%;
  margin: 0;
  padding: 0;
  flex:1;
}
.form-control div[data-section=data] {
  background-color: green;
  display: inline-block;
  width: 50%;
  margin: 0;
  padding: 0;
  flex:1;
}

我怀疑这是一个边框问题。尝试设置border: 0;和outline: 0;编辑:我现在注意到你有box-sizing,所以那不应该是问题。 - Jonas Grumann
4个回答

2

这是一个棘手的问题。Inline-block元素会将HTML中的新行视为空格,从而增加元素的总宽度。要解决此问题,请添加一个空的HTML注释,如下所示:

<div class="form-control" data-layoutOrder="horizontal">
    <div data-section="title">
        <label for="firstName">First Name</label>
    </div><!--
    --><div data-section="data">
    <input type="text" placeholder="First Name" id="firstName">
    </div>
</div>

示例:http://jsfiddle.net/humwrgnj/

我编辑了你的fiddle并删除了HTML注释。什么都没改变...奇怪的是:我使用了“整理”按钮,布局再次出错了。 - chiapa
@chiapa 这是因为_TidyUp_功能会在div之间添加空格。 - Hidden Hobbes
2
我可以向您保证,这就是问题所在。要么添加HTML注释,要么将标签写成内联形式。 - Jonas Grumann
哇,这些是一些很酷的忍者技巧。 - chiapa
代码会因为太多注释而变得臃肿。我认为这不合适。 - CuriousMind
这就是为什么我很少使用inline-blocks。我通常使用浮动,但这不是你的问题,所以我没有提到它。 - Jonas Grumann

2

只需在一行中编写标签

<div class="form-control" data-layoutOrder="horizontal">
    <div data-section="title">
    <label for="firstName">First Name</label>
    </div><div data-section="data">
    <input type="text" placeholder="First Name" id="firstName">
    </div>
    </div>

* {
  -webkit-box-sizing: border-box;
  -moz-box-sizing: border-box;
  box-sizing: border-box;
}

.form-control {
 background-color: yellow;
 margin:0;
 padding:0;
}

.form-control[data-layoutOrder=horizontal] div[data-section=title]{
 display:inline-block;
 background-color : red;
 width: 50%;
 margin:0;
 padding:0;
}

.form-control div[data-section=data] {
 background-color : green;
 display: inline-block;
 width: 50%;
 margin:0;
 padding:0;
<div class="form-control" data-layoutOrder="horizontal">
<div data-section="title">
<label for="firstName">First Name</label>
</div><div data-section="data">
<input type="text" placeholder="First Name" id="firstName">
</div>
</div>


不能用那个,代码格式化程序会重新排列一切。 - CuriousMind

2

这是一个关于inline-block元素的众所周知的问题。解决方法是在容器元素上使用font-size:0;,然后在子元素中使用font-size:initial;来覆盖它。

这里有一个快速演示:

* {
  -webkit-box-sizing: border-box;
  -moz-box-sizing: border-box;
  box-sizing: border-box;
}
.form-control {
  background-color: yellow;
  margin: 0;
  padding: 0;
  font-size:0;
}
.form-control[data-layoutOrder=horizontal] div[data-section=title] {
  display: inline-block;
  background-color: red;
  width: 50%;
  margin: 0;
  padding: 0;
  font-size:initial;
}
.form-control div[data-section=data] {
  background-color: green;
  display: inline-block;
  width: 50%;
  margin: 0;
  padding: 0;
  font-size:initial;
}
<div class="form-control" data-layoutOrder="horizontal">
  <div data-section="title">
    <label for="firstName">First Name</label>
  </div>
  <div data-section="data">
    <input type="text" placeholder="First Name" id="firstName">
  </div>
</div>

如果元素的宽度始终为50%,则另一种选择是使用定位:

html,
body {
  margin: 0;
  padding: 0;
}
.parent {
  position: relative;
  min-height: 50px;
  width: 100%;
  background: rgba(0, 0, 0, 0.2);
}
.child {
  position: absolute;
  top: 0;
  width: 50%;
  height: 100%;
  background: tomato;
}
.childone {
  left: 0;
}
.childtwo {
  lefT: 50%;
  background: cornflowerblue;
<div class="parent">
  <div class="child childone"></div>
  <div class="child childtwo"></div>
</div>


这与IE和Chrome一致。那么你是说这是两个浏览器的问题吗?还是W3C规范有任何强制要求?您能否提供在线参考支持该声明。 - CuriousMind
@CuriousMind:已经有许多答案说明了这一点。再次说明,这是由于空格引起的。这不是错误,这就是它的表现方式。 - jbutler483
将字体大小设置为“0”是可怕的黑客行为。这会使内部元素无法设置字体大小百分比。百分比相对于父元素的字体大小。 - CuriousMind
我绝不会赞成使用%字体大小。请改用em单位。 - jbutler483
我找到了另一种方法,它不需要太多改变代码(请查看编辑1)。 - CuriousMind
显示剩余3条评论

0
在这个类 .form-control[data-layoutOrder=horizontal] div[data-section=title] 中添加 CSS float: left; 属性。

我已经在我的问题注释中指定了。 - CuriousMind

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接