第一个问题:
里面的块如<dd>或<td>或者<li>,我是说得很对,下面的一个或两个是正常的,正确的吗?
<td>
An introductory sentence as a text node.
<p>A further sentence as a paragraph.</p>
</td>
Run Code Online (Sandbox Code Playgroud)
和/或:
<td>
<p>An introductory sentence as a paragraph.</p>
<p>A further sentence as a paragraph.</p>
</td>
Run Code Online (Sandbox Code Playgroud)
第二个问题:
假设是这样,我可以使用什么CSS来确保在两种情况下两个句子之间有差距,而不是在第一句话之前?
我的问题是,如果我做的事情......
td > p { margin-top: 1em; }
Run Code Online (Sandbox Code Playgroud)
...当第一个句子是文本节点时,这可以正常工作,但是<td>当第一个句子在段落内时,它会在第一个句子和包含之间放置不需要的边距.
我想要一个解决方案,即使第一个句子包含内联元素,如<strong>或<a href="...">.
总之CSS应该产生相同的布局,如下,供双方的两个HTML例子:
-- top of <td> here
-- no margin here
-- first sentence here (whether it's a text node and/or inside a <p>)
-- margin here, between the two sentences
-- second sentence here inside a <p>
Run Code Online (Sandbox Code Playgroud)
第三个问题:
如果确实无法定义为两种HTML创建相同格式的CSS规则,那么我想网站作者必须小心,始终只使用一个HTML标记?
如果是这样,你认为这是正常的吗?
永远不要用另一个块启动一个块,总是用一个文本节点启动它(然后你可以使用CSS规则,它说第一个块应该有一个margin-top); 例如,这样做:
<td>
An introductory sentence as a text node.
<p>A further sentence as a paragraph.</p>
</td>
Run Code Online (Sandbox Code Playgroud)
这不起作用,例如,如果块中的第一件事是一个列表 - 列表将不需要margin-top:
<td>
<ul>
<li>List item</li>
<li>List item</li>
</ul>
</td>
Run Code Online (Sandbox Code Playgroud)永远不要用文本节点启动一个块,总是用一个块启动它(然后你可以使用CSS规则,它说第一个块不应该有一个margin-top); 例如,这样做:
<td>
<p>An introductory sentence as a paragraph.</p>
<p>A further sentence as a paragraph.</p>
</td>
Run Code Online (Sandbox Code Playgroud)
这比我预期的更多.我想我习惯看到标记<li>List item</li>而不是<li><p>List item</p></li>
不要标准化,使用其中任何一个,但必要时向块添加额外的class=或style=属性,以在案例的基础上添加或删除上边距.
Mat*_*tra 12
我不确定你是否会认为这是对你的问题的完整答案,因为我知道你<td>在你的例子中使用了a ,<td>而且<dd>和<li>元素之间的一个区别是<td>元素无法抵消他们的周围元素没有打破他们的<table>具体行为 但至少我可以回答你的第三个问题的一部分:
如果确实无法定义为两种HTML创建相同格式的CSS规则......
这是不正确的,你总是可以呈现浮动:before与伪元素width的 100%;集合,并设置半margin同级的<p>元素就可以了.
dd {
border: 1px dashed lightblue; /* this line is for demonstration purposes only */
}
dd:before {
float: left;
content: "";
width: 100%;
margin: 0.5em;
}Run Code Online (Sandbox Code Playgroud)
<dd>
An introductory sentence as a text node.
<p>A further sentence as a paragraph.</p>
</dd>
<dd>
<p>An introductory sentence as a paragraph.</p>
<p>A further sentence as a paragraph.</p>
</dd>Run Code Online (Sandbox Code Playgroud)
这引入了一个空的"虚拟"段落,它只影响直接文本节点,<dd>因为<p>元素只会执行自动边距折叠魔术而不是向下移动.我认为这证明至少可以定义一个CSS规则,它为两种HTML创建相同的格式.
这是如何工作的,或者至少我理解这是如何工作的.W3C在CSS规范中有一个例子,它向我们展示了问题中的文本节点必须是一个匿名块框,因为它是一个在带有display: block;set 的框内渲染的文本节点<dd>,并且它有一个带有display: block;set 的兄弟节点,<p>.
通过添加伪元素 - 它在此匿名块框内呈现(它必须是,因为否则它将永远不能像内联元素一样运行,否则它可能会呈现为两个匿名内联框,没有包含块框) - 但无论如何,我们最终得到两个匿名内联框(伪元素和文本节点).
下一步是获取这些匿名内联框中的第一个,即伪元素,并将其从正常流中移出,将其向左浮动,然后将其设置width为100%,并使其占据与兄弟高度相匹配的高度<p>的保证金(我通过设定保证金的一半来完成<p>保证金,但你可以通过设置与保证金相匹配的高度或底部保证金来做同样的事情<p>).
现在前面的文本节点有一个人为的上边距.问题仍然存在,<p>如果没有前面的文本节点,为什么这不影响元素?我认为这是因为 - 因为没有前面的文本节点 - 伪元素本身被渲染为应用它的元素内的空匿名块框(作为伪元素,内容总是在应用它们的元素内部呈现) ,这与在渲染<span>之前渲染空元素基本相同<p>.
这是一个概念证明:
dd {
border: 1px dashed lightblue;
}
span {
float: left;
height: 1em;
width: 100%;
background-color: lightgray;
}
dd:not(:first-child)::before {
content: "";
float: left;
height: 1em;
width: 100%;
background-color: lightgray;
}Run Code Online (Sandbox Code Playgroud)
<dd>
<span></span>
<p>
The dashed light blue line marks the paragraphs margin box, the light grey box is the span.
</p>
</dd>
<dd>
<p>
The dashed light blue line marks the paragraphs margin box, the light grey box is the pseudo element.
</p>
</dd>Run Code Online (Sandbox Code Playgroud)
这个"人工边缘"是一个左浮动的块框(在伪元素的情况下是匿名块框)在其包含元素内.如果他们需要,所有其他块框将向下移动(因为它们是根据W3C浮动规格假设,当浮动框没有为它们留下任何空间时),这只发生在浮动框开始超出边缘时它是隐藏的,并且在这个特定问题的解决方案中没有发生,因为我特意将人工边缘设置为与实际边缘完全一样高<p>.
我认为秘密在于W3C浮点规范的这一部分,这有点难以理解:
由于浮动不在流中,因此在浮动框之前和之后创建的非定位块框垂直流动,就像浮动不存在一样.但是,根据需要缩短浮动旁边创建的当前和后续行框,以便为浮动的边距框腾出空间.
当存在满足所有这四个条件的垂直位置时,线框旁边是浮动:(a)在线框顶部或下方,(b)在线框底部或上方,(c) )在浮子的上边缘下方,以及(d)在浮子的下边缘上方.
注意:这意味着外部高度为零或外部高度为负的浮动不会缩短线框.
如果缩短的行框太小而不能包含任何内容,则行框向下移动(并重新计算其宽度),直到某些内容适合或不再存在浮动.浮动框之前的当前行中的任何内容都在浮动的另一侧的同一行中重排.换句话说,如果在遇到适合剩余行框空间的左浮动之前将内联级别框放置在该行上,则将左浮动放置在该行上,与行框顶部对齐,然后已经在线上的内联级别框相应地移动到浮动的右侧(右侧是左侧浮动的另一侧),反之亦然,用于rtl和右侧浮动.
我理解这是指"在浮动框垂直流动之前和之后创建的非定位块框,就像浮动不存在一样",因此<p>s,非定位块框不应受浮动框的影响.
但这并不意味着什么.相反,它指出,当盒子向左浮动时,在浮动盒子的右侧创建一个线框,填充浮动盒子右侧和容纳盒子右侧之间的空间.并且在该行框内部存在作为后续<p>元素的块框.如果该<p>元素可以适合满足上述四个条件的空间,它将位于行框中的浮点旁边.
由于浮点数被设置为宽度100%,因此<p>它不适合浮动框,并且它坐在其行框内,向下移动到下一行,在那里它以某种方式神奇地决定部分地尊重第一部分规则:"在浮动框垂直流动之前和之后创建的非定位块框,就像浮动不存在一样",这对于边距似乎是正确的,因为只要浮动框超出边距,块框就会出现确实开始向下移动,也许是因为它也坐在一个线盒中......
现在对于除<td>标签之外的任何东西,将顶部添加的空间消失是非常简单的,因为可以通过将包含内容的元素与其包含元素相抵消来轻松完成.
dd {
position: absolute;
margin-top: -1em;
}
dd:before {
float: left;
content: "";
width: 100%;
margin: 0.5em;
}
div {
position: relative;
/* everything below this line is for demonstration purposes only */
border-top: 1px dashed lightblue;
height: 80px;
}Run Code Online (Sandbox Code Playgroud)
<div>
<dd>
An introductory sentence as a text node.
<p>A further sentence as a paragraph.</p>
</dd>
</div>
<div>
<dd>
<p>An introductory sentence as a paragraph.</p>
<p>A further sentence as a paragraph.</p>
</dd>
</div>Run Code Online (Sandbox Code Playgroud)
我认为回答第二个问题,至少是<dd>和<li>元素,甚至允许前面的文本节点中的内联元素.
如果你想在内部执行此操作,则<td>必须以其他方式开始管理<td>或<table>高度,因为您必须在其中使用绝对定位<td>并通过设置表来破坏表随其内容增长的默认表行为单元格display: block;(或通过渲染其他<div>内部<td>并将其用作块级元素,但这也会破坏默认的单元格增长行为).
table
{
width: 100%;
min-height: 80px;
float: left;
}
dd {
position: absolute;
margin-top: -1em;
}
dd:before {
float: left;
content: "";
width: 100%;
margin: 0.5em;
}
td {
position: relative;
display: block;
border-top: 1px dashed lightblue; /* this line is for demonstration purposes only */
}Run Code Online (Sandbox Code Playgroud)
<table>
<tr>
<td>
<dd>
An introductory sentence as a text node.
<p>A further sentence as a paragraph.</p>
</dd>
</td>
</tr>
</table>
<table>
<tr>
<td>
<dd>
<p>An introductory sentence as a paragraph.</p>
<p>A further sentence as a paragraph.</p>
</dd>
</td>
</tr>
</table>Run Code Online (Sandbox Code Playgroud)