14

我准备了一个示例 jsfiddle 来展示我目前在布局中面临的问题:当我将内容动态插入到特定元素(砖块)中时,该元素会以一种超出我理解的方式与其父元素一起下沉的 HTML/CSS。当我删除内容时,原始布局会恢复,除非我使用的是 Chrome……然后它会保留其位置并在插入新内容时再次下降。

概念证明:http: //jsfiddle.net/GADk9/

示例中的复选框只是切换块内的文本,仅此而已。我想知道上面的边距(是吗?)来自哪里。

这是一个完整的 HTML5 文档:

<!DOCTYPE html>
<html lang='en'>
<head>
<meta charset='UTF-8'>
<title>HTML5 Falling Brick - What is this?</title>
<style>
#brick {
    background-color: lightgray;
    border: solid black medium;
    border-radius: 1em;
    color: red;
    font-size: 2em;
    height: 100%;
    text-align: center;
}
#contrail { background-color: lightblue; width: 20em; }
#pit { display: table; }
#pit>* { display: table-cell; }
#pit>*>* { height: 4em; }
</style>
</head>
<body>
    <div>
        <label>Click me twice
            <input onchange="document.getElementById('brick').innerHTML = this.checked ? 'FALL!!!' : ''" type='checkbox'></input>
        </label>
    </div>
    <div id='pit'>
        <div>
            <div>
            </div>
        </div>
        <div id='contrail'>
            <div>
                <div id='brick'></div>
            </div>
        </div>
    </div>
</body>
</html>

更新

再次阅读我的问题后,我意识到这可能暗示我真正想要完成的是修复一些 HTML 的错误印象。为了明确强调这一点,我不需要在这里更改任何内容。砖块的例子只是我正在观察的问题的一个有趣的演示。我真的很想了解在这样的排列中插入内容时导致元素改变位置的原因。

4

10 回答 10

4

你有

<div id='pit'>
    <div>
        <div>
        </div>
    </div>
    <div id='contrail'>
        <div>
            <div id='brick'></div>
        </div>
    </div>
</div>

你正在使用

#pit { display: table; }
#pit>* { display: table-cell; }
#pit>*>* { height: 4em; }

现在这是我们的问题,因为它说#pit的是表格,并且是一个表格单元,它每次都#pit>*在加起来。height: 4em;

现在这是我的解决方案。

#pit { display: block; }
#pit>* { display: table; }
#pit>*>* { height: 4em; display: table-cell;}

http://jsfiddle.net/AAbhishekk/GADk9/28/

于 2013-05-01T03:03:25.323 回答
4

在多次使用表格、表格行和表格单元格显示时,我已经看到浏览器之间的行为差​​异。首先,我从不使用它们,因为总会有更好的解决方案。但是,对于您的问题:

在处理旨在表现得像表格的 CSS 时,想想有点老派是有帮助的。

事实证明,让 Fiddle 中的 POC 正常运行的神奇 CSS 属性是垂直对齐。事实上,这解决了所有浏览器中奇怪的插入额外垂直空间的问题,而不仅仅是 Chrome,同时也解决了 Chrome 保留额外空间的问题。

看看这个小提琴的小修改:http: //jsfiddle.net/rtzeK/

#brick {
    background-color: lightgray;
    border: solid black medium;
    border-radius: 1em;
    color: red;
    font-size: 2em;
    height: 100%;
    text-align: center;
}
#contrail { background-color: lightblue; width: 20em; }
#pit { display: table; }
#pit>* { display: table-cell; vertical-align: top; }
#pit>*>* { height: 4em; }

在我链接的小提琴中,我只是将显示的子项设置为:table-cell 以具有附加属性,vertical-align:top。事实证明,您可以将其设置为中间或底部,都具有相同的效果。它阻止了不当行为 - 显然 Chrome 需要被告知在这种情况下如何表现。

我确实觉得 Chrome 的行为不端有点奇怪,而且它似乎是一个错误。也就是说,我回到我之前关于避免像瘟疫一样的显示属性值的声明。显示的组合:inline、inline-block、block,结合相对和绝对定位,在父母和孩子之间适当地使用,使得其他麻烦的 css 属性,例如浮动,变得不必要。

干杯

于 2013-05-02T05:43:58.287 回答
1

如果您将标记简化为仅包含一个 div 的几个单元格,这将更容易理解。

<div class="cell left">
  <div class="inner"></div>
</div>
<div class="cell middle">
  <div class="inner"></div>
</div>
<div class="cell right">
  <div class="inner"></div>
</div>

然后用一些像这样的 CSS 为每个 div 分配不同的高度。

.cell {
  display:table-cell;
  background-color:black;
  width:200px;
}

.inner {
  background-color:silver;
}

.left .inner {
  height:80px;
}
.middle .inner {
  height:140px;
}
.right .inner {
  height:100px;
} 

默认情况下,这些内部 div 与其基线垂直对齐。因此,没有任何文本,所有 div 都沿单元格底部对齐:

       +------+
       | |
       | +------+
+--------+ | |
| | | |
| | | |
+-----+------+------+

但是,如果您将文本添加到其中任何一个,则该 div 将被下推,以便第一行文本的基线与其他 div 的底部边缘对齐。

       +------+
       | |
       | |
+--------+ |      
| | +------+
| | |正文 |
+--------+------+ |
              | |
              +------+

正如其他人指出的那样,您可以通过设置不同的vertical-align属性来更改发生的情况。例如,添加vertical-align:top.cell选择器会给你这样的东西:

+-----+------+------+
| | |正文 |
| | | |
+--------+ | |
       | +------+
       | |
       +------+           

我发现在 codepen 中玩这种东西最容易,你可以在其中看到所做的更改。这是一个实验的例子。

于 2013-05-03T13:53:13.303 回答
1

这是我能想到的最好的主意,我希望我能做到,或者它至少接近它。
在您的 CSS 规则中,您有:

#pit { display: table; }
#pit>* { display: table-cell; }
#pit>*>* { height: 4em; }

它告诉浏览器这#pit是一个表格,并且它的所有子元素都是单元格(而孙子元素是它们的样子,因为 CSS 没有强制显示)

在这里,我看到了 2 个问题:

问题 1

里面#pit你有:

<div>
    <div>
    </div>
</div>
<div id='contrail'>
    <div>
        <div id='brick'></div>
    </div>
</div>

注意孩子,因为你有 2 个,选择器#pit>*每个#pit孩子 我都会为此更改 CSS 规则:

#pit { display: table; }
#pit>#contrail { display: table-cell; }
#pit>#contrail>* { height: 4em; }

但是要小心你想要什么,因为这会让#pit>#contrail4em高的孩子,而不是内在的孩子#brick,也许这就是你想要的,但要注意它。

问题 2 @ Chrome(如果您“解决”第一个问题,则不存在)

我不确定我在这里说什么,但是......这可能是一个 webkit 错误吗?Opera也会发生这种情况吗?
编辑:Opera 的行为不像 Chrome,它返回到正常布局,所以也许它毕竟不是 webkit 错误:/

所以你有一个表格和表格单元格,但是浏览器然后认为“等等……如果这是一个表格,这是一个单元格……行在哪里!?” ,所以它创造了一个“鬼排”,所以它可以快乐。但是,我不确定当您删除文本时“它”会怎么想,因为它“正常工作”。如果您查看开发人员工具,您会发现没有实际的行元素或类似的东西。
当您“重新添加”文本时,浏览器会介意=打击,因为表格布局。所以它再次重新创建行(拉伸#pit),可能是因为“幽灵行”没有被清除,或者因为#pit' 的高度永远不会再次重新计算,它只会在幽灵行产生时增加。

如果您想保留相同的 CSS 规则,则必须执行以下操作:

#pit { display: table; }
#pit>* { display: table-row; }
#pit>*>* { height: 4em; display: table-cell; }
于 2013-04-24T01:38:16.917 回答
1

有时,最简单的答案会被忽略。无需将内容重置为空(例如“”),只需将空内容作为非中断空间开始,然后将其重置回非中断空间。表格单元格在没有内容时不会呈现。不间断的空间被单元格视为内容,因此它可以正确呈现。

JSFiddle在这里

这是摩擦:

您需要将此规则添加到您的#brick 块中:

vertical-align: top;

并且您需要为应该呈现内容的空表格单元格提供一些内容,以这种方式完成:

<div id='contrail'>
    <div>
        <div id='brick'>&nbsp;</div>
    </div>
</div>

瞧,它已在 Chrome 中修复,并且在其他任何地方都以相同的方式显示。这是一个老式的表问题。看来 Chrome 决定忠实于他们在过去糟糕的日子里最初的行为方式。

或者,对于纯 CSS 解决方案,您也可以将内容规则添加到 #brick 块:

vertical-align: top;
content: '&nbsp;';

这以完全相同的方式工作。享受!

于 2013-05-02T17:19:09.727 回答
0
#pit { display: table; }
#pit>* { display: table-cell; }

以上导致它膨胀(而不是收缩)。这是预期的行为吗?不,因为它不会发生在 IE 或 Firefox 上,我相信这是一个误解display: tabledisplay: table-cell行为的 Chrome 错误。<div id="contrail">在您删除文本的情况下,它似乎不会重新计算表格单元格的高度。

看看这个小提琴- 我已经用实际的表格替换了 div。每次填充文本时,表格单元格的高度都会扩大,但在清除文本时会收缩回原始大小。我会得出结论,这是一个 Chrome 错误,因为这种 CSS 显示模式的目的是模仿<table><td>.

于 2013-04-30T02:17:01.893 回答
0

看起来 chrome 不满意 display:table-cell 里面 display:table 没有 display:table-row 介于两者之间。

如果你添加它(并给砖一些宽度),它会停止下降:

#brick {
    background-color: lightgray;
    border: solid black medium;
    border-radius: 1em;
    color: red;
    font-size: 2em;
    height: 100%;
    width: 200px;
    text-align: center;
}
#contrail { background-color: lightblue; width: 20em; }
#pit { display: table; }
#pit>* { display: table-row; }
#pit>*>* { display: table-cell; }
#pit>*>* { height: 4em; }
于 2013-04-24T01:38:21.610 回答
0

我相信有一个奇怪的规则:

#brick {
    background-color: lightgray;
    border: solid black medium;
    border-radius: 1em;
    color: red;
    font-size: 2em;
    line-height:2em;
    height: 100%;
    text-align: center;
    margin:0;
    padding:0;
    height:2em;
}
#contrail { background-color: lightblue; width: 20em; }
#pit { display: table; }
#pit>* { display: table-cell; }

http://jsfiddle.net/GADk9/77/

于 2013-05-02T21:25:08.170 回答
0

答:浏览器不理解你的 html/css 布局组合,因为它没有按照官方规范格式化。格式不正确的 HTML 会使浏览器不正确地显示元素。

表格单元格必须有一个父表格行:

http://www.whatwg.org/specs/web-apps/current-work/multipage/tabular-data.html#the-td-element

不允许将表格单元格作为表格元素的直接子元素:

http://www.whatwg.org/specs/web-apps/current-work/multipage/tabular-data.html#the-table-element

于 2013-05-03T15:16:21.663 回答
0

我注意到只是添加了一个

   <p> around your text </p>

解决了问题

这是一个工作的jsfiddle

于 2013-05-03T09:32:48.723 回答