【问题标题】:Is this a bug in CSS? [duplicate]这是CSS中的错误吗? [复制]
【发布时间】:2019-01-22 01:45:27
【问题描述】:

这听起来可能是一个过时的话题,因为由于 flex-box 和 grid 没有人仍然使用 inline-block 属性,但我想知道它,我想询问一下。

当创建两个 div 并将它们都分配为显示为 inline-block 然后在其中一个中添加任何元素时,结果很奇怪,其中包含该元素的 div 会滑到另一个 div 的底部减去添加元素的高度。

div {
    display: inline-block;
    width: 100px;
    height: 150px;
    background: gray;
}
<div id="left">
  <span>Text</span>
</div>
<div id="right"></div>

要解决这个问题,只需将 div 垂直对齐到顶部就足够了,但奇怪的是,即使我们对齐另一个不受影响的 div 而不对齐受影响的 div,我们也会得到相同的结果,那又如何呢?这里到底发生了什么?

div {
    display: inline-block;
    width: 100px;
    height: 150px;
    background: gray;
}

#left{
     vertical-align: baseline;
}

#right{
      vertical-align: top;
}
<div id="left">
  <span>text</span>
</div>
<div id="right"></div>

更新:

为了进一步澄清,我删除了子元素并在两个 div 之外添加了一个文本,并添加了另外两个 div,现在所有 div 都没有流内容,但前两个都有一个 top 属性,而最后一个两个是不同的,一个是top,一个是baseline:

div {
  display: inline-block;
  width: 100px;
  height: 150px;
  background: gray;
}
.right{
  vertical-align:baseline;
}
.left{
  vertical-align:top;
}
Text
<div class="right"></div>
<div class="left"></div>

<br>

Text
<div class="left"></div>
<div class="left"></div>

在第一种情况下,文本与顶部对齐,下一个与 div 的基线对齐,即使它们没有流内容。

【问题讨论】:

  • 尝试将 max-width 和 max-height 添加到 textarea textarea { margin: 0;填充:0;宽度:50px;高度:50px;边框:0;最大宽度:100%;最大高度:100%; }
  • 因为 IE 还没有死掉(还)inline-block 仍然有它的位置,因为即使在最新版本的 IE(不是边缘)中,gridflex 也有问题(充其量)
  • 这不是错误,它是垂直对齐,默认为baseline
  • 我并没有完全偏离主题,这正是您需要的答案。您的行为是由于基线对齐,这解释了一切。我添加了更多重复项,以便您了解这种逻辑行为
  • 阅读重复项,您会明白 :) 关闭为重复项的目的.. 我无法在 cmets 中解释这种行为

标签: html css


【解决方案1】:

发生这种情况的原因是,内联元素的默认vertical-align 值为baseline

那么问题就变成了:inline-block 元素的基线是什么?在这里,我们要区分有无flow content的元素:

  • 对于带有流动内容的元素,例如您问题中的left div,基线与最后一个内容元素的基线相同。(*) 对于left div,这对应于内部span 的基线。
    (*) 在设置元素的溢出时还有一些额外的注意事项,但我将把它排除在范围之外。
  • 对于没有流动内容的元素,例如您问题中的right div,基线是元素边距框的底部。对于right div,这对应于 div 本身的底部。

因此,总结一下:您看到垂直偏移的原因是元素根据它们的基线垂直对齐,并且有内容和没有内容的元素的基线计算方式不同。

要对此进行测试,只需尝试在 right div 中添加一些文本,您就会发现两个基线现在是相同的。

div {
  display: inline-block;
  width: 100px;
  height: 100px;
  background: gray;
}
<div id="left">Text</div>
<div id="right">Other text</div>

通过动画字体大小,下面的示例更清楚地展示了基线的变化如何影响垂直定位:

div {
  display: inline-block;
  width: 100px;
  height: 100px;
  background: gray;
}

#left {
  transition: all 2s ease;
  animation: anim 2s infinite linear alternate;
}

@keyframes anim {
  0% {font-size: 100%;}
  100% {font-size: 300%;}
}
<div id="left">Text</div>
<div id="right"></div>

【讨论】:

  • 这解释了当两个 div 都在基线上时的初始状态。我不相信它回答了 OP 的问题,这就是为什么将 either div 设置为 vertical-align:top 会删除偏移量。
  • @TemaniAfif - 实际上,我认为要完整回答这个问题,尤其是最新形式,需要解释线框是如何构造的。未对齐顶部和底部框边缘的项目首先相互对齐,然后添加顶部和底部项目。我不确定是否有任何重复项实际上是这样做的。不过,我目前没有时间写一个正确的答案。
  • @Alohci 如果我没记错的话你已经在这里做了stackoverflow.com/questions/43305825/…
  • @TemaniAfif - 所以我做到了。谢谢。
  • 好吧,我承认,我错了,这让我觉得我在重新学习CSS,我曾经认为CSS要简单得多,但现在我明白了背后的原理逻辑这个,谢谢你们的解释,给您带来的不便,我们深表歉意。
【解决方案2】:

显示:inline-block 值

与 display:inline 相比,主要区别在于 display:inline-block 允许在元素上设置宽度和高度。

此外,使用 display: inline-block,尊重顶部和底部边距/填充,但使用 display: inline 则不考虑。

与 display:block 相比,主要区别在于 display:inline-block 不会在元素后添加换行符,因此该元素可以与其他元素相邻。

请问 textarea 是 inline-block,但是哪一行是正确的, 浏览器认为 第二个内联块的底部是行的位置 所以 当他去画孩子时,他看到 textarea 必须是内联的,并将它的位置更改为 第二个内联块的底部是行的位置,因为它是任何填充并且它的位置是相对的,所以导致将父 div 移到底部只是为了 textarea 内联

【讨论】:

猜你喜欢
  • 1970-01-01
  • 2019-08-09
  • 1970-01-01
  • 1970-01-01
  • 2018-01-16
  • 2013-08-09
  • 2020-03-07
  • 1970-01-01
  • 2017-02-02
相关资源
最近更新 更多