【问题标题】:Spacing between text with line-height具有行高的文本之间的间距
【发布时间】:2018-01-13 13:08:34
【问题描述】:

我想在h1span 之间留一个间距,应该是30px。从h1的字母底部到span的字母顶部应该是30px,在h1的下方,这里是30px的间距应该是(蓝色框显示间距):

我的h1span 有一些line-height。我在它周围做了一个border,所以line-height 是可见的。如果我现在将30pxmargin-bottom 设置为h1,它看起来像这样:

间距从h1 元素的末尾开始,到span 元素的开头结束。 line-height 位于元素的开始/结束和字母之间。所以间距也包括line-height,它不完全是30px。解决这个问题的最佳方法是什么?我知道,我可以像这样设置margin-bottommargin-bottom: 30px - [LINE-HEIGHT]; 但是我怎么知道两个红色框(行高)是多少,正确减去它以使间距正好变成30px

h1 {
  font-family: Arial;
  font-size: 45px;
  line-height: 54px;
  letter-spacing: 0;
  color: darkred;
  border: 1px solid black;
  margin: 0 0 30px;
}

span {
  font-family: Arial;
  font-size: 30px;
  line-height: 39px;
  letter-spacing: 0;
  color: gray;
  border: 1px solid black;
}
<h1>Default main title</h1>
<span>Proin eget tortor risus. Vivamus magna justo, lacinia</span>

这是我的代码笔示例:https://codepen.io/STWebtastic/pen/QarjJO

我希望这已经足够清楚了。

【问题讨论】:

  • @DavidThomas 感谢您的意见,现在可以了吗?干杯
  • 非常感谢!
  • @DavidThomas 哦,当然,对不起。过去我只使用stackoverflow sn-p,它会在问题中自动生成代码。最近我开始使用 codepen 并且出于习惯忘记了问题中的代码丢失了。现在应该好了。
  • @MrBuggy h1 下面的空格是 g 和 y 之类的字母 - 添加其中一个会发生什么?您的空间将不再是 30 像素;
  • @Pete 是的,我知道。但是,如果我能得到这个空间的高度并从我的边距底部减去它,它会起作用,就像我写的那样。因此,例如,如果 h1 内的空间是 10 像素,而跨度内的另一个空间是 5 像素,这将是 15 像素 + 我的边距底部 30 像素 = 45 像素,而不是 30 像素。因此,如果我能找出空格并将其从我的边距中减去,如下所示: margin-bottom: 30px - calc(10px + 5px);我会得到一个 15px 的边距底部,这将用空格“生成” 30px 的空间。但我不知道如何让空间高度减去它,这将是我的解决方案。

标签: html css margin


【解决方案1】:

嗯,这并不是互联网排版的工作原理。

设置line-height:100%; margin:0; padding:0;box-sizing:border-box;(因此边框不会添加到高度)将使您稍微更接近。

但真正的问题是,在浏览器中,行高包括为下降线(想想 q、j、g 的底部)和上升线保留的间距。加上一些我无法真正解释的额外内容。我不是设计师,更不是字体专家。

因此,您真正实现所需内容的唯一方法是使用幻数(通过反复试验获得的值)将行高调整为低于实际字体大小的值。正确的值通常在 68-70% 的范围内,但没有适用于任何字体大小的公式,更不用说任何字体了。

body {
  font-family: Arial;
}
*{
box-sizing:border-box;
}


h1 {
  font-size: 45px;
  line-height:31px;
  letter-spacing: 0;
  color: darkred;
  border: 1px solid black;
  margin: 0 0 30px;
}

p {
  font-size: 30px;
  line-height:21px;
  color: gray;
}


h1, p{
  padding:0;
  margin:30px 0;
  border: 1px solid black;
}
<h1>Default qgj main Title</h1>

<p>Proin eget tortor risus. Vivamus magna justo, </p>

当然,这是极其脆弱且容易出现问题的。因此,实现有点相似的最佳选择是在页边空白处继续使用幻数。

有一些公式可以让您更轻松地猜测,但它们实际上取决于您选择的字体、字体大小等。再说一遍,魔术数字。

【讨论】:

  • 在更简化的情况下,OP 可能比“有点相似”更接近。有ex这个单位,表示小写字母的高度。所以...如果所有字母都正好是那个高度,并且字体大小没有变化,那么通过将高度设置为1ex + 30px,你可以在行之间有正好 30px 的空间。 jsfiddle.net/kj01qgmr(当然,如果你也有大写字母,如果元素有不同的字体大小,这将不起作用。)
  • @MrLister 很棒的贡献!可能不是他真正需要的,因为他的 sn-p 已经有大写字母了,但我完全忘记了前单位的存在
【解决方案2】:

我认为您应该先阅读此内容:https://iamvdo.me/en/blog/css-font-metrics-line-height-and-vertical-align

如您所见,字体本身具有一定的行高(字符和底部边框之间的空白)。所以如果你设置了font-size: 45pxline-height:45px 仍然会有一个空格(在你的小提琴中尝试它并检查元素以获取证据)。它必须做字体是如何被em-square渲染的,这是不成比例的。

您可以选择具有使用整个 em-square 的字符的字体。但我不知道找到这个有多容易......

据我所知,您能做的最好的事情确实是已经建议的:反复试验,直到找到 30 像素。

【讨论】:

    【解决方案3】:

    一些字符,例如小写的 j 或 g 有一个“降序”。因此,您的问题一开始就有缺陷,因为您似乎没有考虑那些属于字体高度的下降部分。

    【讨论】:

      【解决方案4】:

      为了简化问题,您要问:我如何确保在h1 元素的baseline 和它下方的cap line 元素之间有30px 的空间?

      看起来 GitHub 上有一个名为 cap-height 的漂亮项目,只要您使用 Web Font Loader 加载字体,它就可以帮助您解决这个问题。

      您可以计算h1span 的大写高度,设置它们各自的line-height 以匹配它们的大写高度,然后将padding-bottom: 30px 添加到您的h1。您还需要设置margin: 0,以便消除两个元素之间的任何垂直空间。

      这是我手动完成的 fiddle 示例。

      【讨论】: