我正在重写一个从 HTML4 Transitional 到 HTML5 的网页,我希望重写后它看起来相同。但是,我无法制作包含多行文本的
<div>
来将每行的高度自动调整为该行文本的最大字体大小。
为了说明,与过渡 (1) 和现代严格 (2) 文档类型相同的内容:
<iframe width="100" src='data:text/html,
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<style>
.box {
width: 20em;
border: 1px solid black;
margin: 5px;
}
.text-big {
font-size: 12px;
}
.text-small {
font-size: 9px;
}
</style>
</head>
<body>
<div id="div-1" class="box">
<span class="text-big">Aaaa</span>
<span class="text-small">Bbbb bbbbb bbbbbbbbbbb bbbbbbbbbbb bbbbbbbbbbb bbbbbbbbbbb bbbbbbbbbbbb bbbbbbbbbbb bbbbbbbbb bbbbbbbbbb bbbbbbbbbbb bbbbbbbb bbb</span>
</div>
<div id="div-2" class="box">
<span class="text-small">Bbbb bbbb bbb bbbb</span>
<span class="text-big">Aaaaaa aaaaaaaaa aaaaaa aaaaaa aaaaaaaaaa aaaaaaaaaa aaaaaaaa aaaaaaaaa aaaaaaaaaa aaaaaaaa aaaaaaaa aaaaaaa</span>
</div>
</body>
</html>
'></iframe>
<iframe width="100" src='data:text/html,
<!DOCTYPE HTML>
<html>
<head>
<style>
.box {
width: 20em;
border: 1px solid black;
margin: 5px;
}
.text-big {
font-size: 12px;
}
.text-small {
font-size: 9px;
}
</style>
</head>
<body>
<div id="div-1" class="box">
<span class="text-big">Aaaa</span>
<span class="text-small">Bbbb bbbbb bbbbbbbbbbb bbbbbbbbbbb bbbbbbbbbbb bbbbbbbbbbb bbbbbbbbbbbb bbbbbbbbbbb bbbbbbbbb bbbbbbbbbb bbbbbbbbbbb bbbbbbbb bbb</span>
</div>
<div id="div-2" class="box">
<span class="text-small">Bbbb bbbb bbb bbbb</span>
<span class="text-big">Aaaaaa aaaaaaaaa aaaaaa aaaaaa aaaaaaaaaa aaaaaaaaaa aaaaaaaa aaaaaaaaa aaaaaaaaaa aaaaaaaa aaaaaaaa aaaaaaa</span>
</div>
</body>
</html>
'></iframe>
当上述网站具有 HTML4 DOCTYPE 时,它是由网络浏览器(Firefox)以有限的怪癖模式显示的,因此,文本每行的高度被调整为文本的最大字体大小在那一行:
。
但是,当网站在每个
<div>
中具有 HTML5 DOCTYPE(因此它以无怪癖模式显示)时,所有文本行都具有相同的高度,无论它们包含的文本的字体大小如何:
。
我为
line-height:
和font-size:
尝试了各种CSS选项(display:
、<div>
、<span>
等),以及将文本包装在额外的<p>
、<div>
等中,但在 HTML5 中,<div>
的所有行仍然具有相同的高度。我希望网站看起来像 HTML4 中的样子:仅包含小文本的行应具有较小的行高,而同时包含小文本和大文本或仅包含大文本的行应具有较大的行高。
文本差异很大。有时有一个短的大文本和一个长的小文本(如示例的第 1 个
<div>
),有时有一个短的小文本和一个长的大文本(如示例的第 2 个<div>
),等等,所以我无法手动将文本分成行并单独设置它们的行高。
对抗怪癖模式可能看起来是徒劳的,显然,如果有任何其他选择,我们应该尽可能坚持符合标准的模式,但总的来说,这不应该是不可能的,只是可能很困难和/或乏味。老实说我不知道它有什么特殊之处,但它毕竟不可能是黑魔法。它让我想起了遥远的过去的一个常见的肮脏技巧,用于消除包装器上不需要的
font-size
到零的间距,这实际上减少了行框的行和字间距。在进行“内联布局”时,这通常是可取的。
由于您的示例(幸运的是)不直接在
.box
包装器内包含任何文本内容,并且所有文本内容都在 span
中,因此它可能适用于您的情况,至少从我站的地方看来是这样。经过一番摆弄,似乎添加了
.box {
width: 20rem; /* or calc() with former inherited font-size */
font-size: 0; /* nuke whitespace */
word-spacing: 4px; /* remedy spacing between spans with extra spacing */
}
.box * {
word-spacing: 0; /* no extra spacing here */
line-height: 1.18; /* "works on my machine" */
}
“HTML5 变体”在某种程度上起到了作用。使用这个探索性测试珠和减少的测试用例:
function setContent(str) {
for( const f of document.querySelectorAll('[data-prefix]') ) {
f.src = f.getAttribute('data-prefix') + str +
document.getElementById('x0').value +
document.getElementById(f.getAttribute('data-extra')).value
}
}
t.oninput()
iframe,
textarea {
width: 300px;
height: 165px;
border: none;
}
<!doctype html>
<table border>
<tr>
<th>Shared code
<th>Quirk
<th>HTML5
<tr>
<td>
<textarea id="t" oninput="setContent(value)">
<body>
<div>
<span>aaaa aaaa aaaa aaaa</span>
<b>ha!</b>
<span>aaaa aaaa aaaa aaaa</span>
</div>
</textarea>
<td>
<iframe data-extra="x1"
data-prefix='data:text/html,<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">'
></iframe>
<td>
<iframe data-extra="x2"
data-prefix='data:text/html,<!DOCTYPE HTML>'
></iframe>
<tr>
<td>
<textarea id="x0" oninput="t.oninput()">
<!-- For both -->
<style>
div { border: solid; width: 60px; }
div span { font-size: 10px; }
div b {font-size: 20px; }
</style>
<style>
</style>
</textarea>
<td>
<textarea id="x1" oninput="t.oninput()">
<!-- For Quirk -->
<style>
</style>
</textarea>
<td>
<textarea id="x2" oninput="t.oninput()">
<!-- For HTML5 -->
<style>
div {
font-size: 0;
word-spacing: 4px;
}
div * {
word-spacing: 0;
line-height: 1.18;
}
</style>
</textarea>
</table>