在诸如< dd>的块内.或者< td>或者< li>,我是否正确地说以下任何一个或两个都是正常的和正确的?
<td> An introductory sentence as a text node. <p>A further sentence as a paragraph.</p> </td>
和/或:
<td> <p>An introductory sentence as a paragraph.</p> <p>A further sentence as a paragraph.</p> </td>
第二个问题:
假设是这样,我可以使用什么CSS来确保在两种情况下两个句子之间有差距,而不是在第一句话之前?
我的问题是,如果我做的事情……
td > p { margin-top: 1em; }
…当第一个句子是文本节点时,这可以正常工作,但它在第一个句子和包含< 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>
第三个问题:
如果确实无法定义为两种HTML创建相同格式的CSS规则,那么我想网站作者必须小心,始终只使用一个HTML标记?
如果是这样,你认为这是正常的吗?
>永远不要用另一个块启动块,总是用文本节点启动它(然后你可以使用CSS规则,它说第一个块应该有一个margin-top);例如,这样做:
<td> An introductory sentence as a text node. <p>A further sentence as a paragraph.</p> </td>
这不起作用,例如,如果块中的第一件事是一个列表 – 列表将有不需要的margin-top:
<td> <ul> <li>List item</li> <li>List item</li> </ul> </td>
>永远不要用文本节点启动一个块,总是用一个块启动它(然后你可以使用CSS规则,它说第一个块不应该有一个margin-top);例如,这样做:
<td> <p>An introductory sentence as a paragraph.</p> <p>A further sentence as a paragraph.</p> </td>
这比我预期的更多.我想我已经习惯看到像< li> List item< / li>这样的标记了.而不是< li>< p>列出项目< / p>< / li>
>不要标准化,使用任何一种,但必要时可以在块中添加额外的class =或style =属性,以便根据具体情况添加或删除上边距.
解决方法
If it’s true that it’s not possible to define a CSS rule which creates the same format for both kinds of HTML…
事实并非如此,你总是可以渲染一个浮动:前面的伪元素,宽度为100%;设置,并设置兄弟的一半边缘< p>它上面的元素.
dd { border: 1px dashed lightblue; /* this line is for demonstration purposes only */ } dd:before { float: left; content: ""; width: 100%; margin: 0.5em; }
<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>
这引入了一个空的“虚拟”段落,它只影响< dd>的直接文本节点.作为< p>元素只会执行their automatic margin collapsing magic而不是向下移动.我认为这证明至少可以定义一个CSS规则,它为这两种HTML创建相同的格式.
这是如何工作的,或者至少我理解这是如何工作的. W3C在CSS规范中有一个例子,它告诉我们问题中的文本节点必须是anonymous block box,因为它是一个文本节点,在一个带有display:block的框内呈现;设置,< dd>,它有一个带display:block的兄弟;设置,< p>.
通过添加伪元素 – 在此匿名块框内呈现(它必须是,因为否则它将永远不会像内联元素一样,或者它可能呈现为两个anonymous inline boxes,没有包含块框) – 但无论如何,我们最终得到两个匿名内联框(伪元素和文本节点).
下一步是获取这些匿名内联框中的第一个,伪元素,并通过向左浮动将其从正常流中取出,然后将其宽度设置为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; }
<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>
这个“人工边缘”是一个左浮动的块框(在伪元素的情况下是匿名块框)在其包含元素内.如果他们需要,所有其他的块盒都将向下移动(因为它们是根据W3C floating spec假设浮动盒子没有为它们留下任何空间),这只发生在浮动盒开始超出它的边缘时隐藏,并且它不会在这个特定问题的解决方案中发生,因为我特意将人工边缘设置为与< p>的实际边缘一样高.
我认为秘密在于W3C浮动规范的这一部分,这有点难以理解:
Since a float is not in the flow,non-positioned block Boxes created
before and after the float Box flow vertically as if the float did not
exist. However,the current and subsequent line Boxes created next to
the float are shortened as necessary to make room for the margin Box
of the float.A line Box is next to a float when there exists a vertical position
that satisfies all of these four conditions: (a) at or below the top
of the line Box,(b) at or above the bottom of the line Box,(c) below
the top margin edge of the float,and (d) above the bottom margin edge
of the float.Note: this means that floats with zero outer height or negative outer
height do not shorten line Boxes.If a shortened line Box is too small to contain any content,then the
line Box is shifted downward (and its width recomputed) until either
some content fits or there are no more floats present. Any content in
the current line before a floated Box is reflowed in the same line on
the other side of the float. In other words,if inline-level Boxes are
placed on the line before a left float is encountered that fits in the
remaining line Box space,the left float is placed on that line,
aligned with the top of the line Box,and then the inline-level Boxes
already on the line are moved accordingly to the right of the float
(the right being the other side of the left float) and vice versa for
rtl and right floats.
我理解这是指“在浮动框垂直流动之前和之后创建的非定位块框,就像浮动不存在一样”,因此< 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; }
<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>
我认为回答第二个问题,至少对于< dd>和< li>元素,甚至允许前一个文本节点中的内联元素.
如果你想在< td>内进行此操作你必须开始管理< td>或< table>高度其他方式,因为你必须在< td>内使用绝对定位.并通过将表格单元格设置为display来阻止表格增长的默认表格行为:block; (或者通过在< td>中渲染一个额外的< div>并将其用作块级元素,但这也会破坏默认的单元格增长行为).
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 */ }
<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>