尽管有“line-height:1”和“overflow:hidden”,但仍然保持悬挂字符可见
目标
<div class="Card">
<div class="Card-FullNameLabel">Gregg Sims</div>
<div class="Card-OrganizationNameLabel">Compubotics</div>
</div>
- 在
.Card-FullNameLabel有font-size: 16px和line-height: 1。 - 在
.Card-OrganizationNameLabel有font-size: 12px和line-height: 1。 .Card-FullNameLabel和之间的垂直空间.Card-OrganizationNameLabel必须正好为6px。- 以下 CSS 规则必须有效且不得更改。
.Card-FullNameLabel + .Card-OrganizationNameLabel {
margin-top: 6px;
}
- 双方
.Card-FullNameLabel并.Card-OrganizationNameLabel必须有溢出公差(例如,如果该内容会像ÀÇ?jgpfhjklb?iEstosTreMalfaci等它不能从parrent突出)。 - 尽管 to ,所有字母都必须完全可见
line-height: 1。 - 不允许在 CSS 代码中使用心算(幻数和/或硬编码偏移量和其他必须预先计算的值)。
可以做什么:将 Pug 预处理器的功能用于标记,将 CSS 预处理器用于样式。
初始小提琴不满足条件编号5:目前该卡不支持溢出。
关于line-height: 1,不好的做法
我一再被告知我必须设置line-height的价值超过1.
很明显,设置 line-height: 1 是一种不好的做法。我提醒你,无单位值是与字体大小相关的,而不是与内容区域相关的,处理比内容区域小的虚拟区域是我们许多问题的根源。
深入研究 CSS:字体度量、行高和垂直对齐
好吧,我不打算对此提出异议。我想要的只是达到我的目标(如上所述)的工作解决方案。它的使用是我的责任,如果您同意line-height必须超过,我不会推荐这个解决方案1。
但是为什么我不想line-height这么坚持地增加呢?
原因一:精确定义两个元素之间的垂直空间会变得过于复杂
该规则.Card-FullNameLabel + .Card-OrganizationNameLabel { margin-top: 6px; }清晰、直观,并通过 CSS 表达了准则(如上图所示)。“.Card-OrganizationNameLabel必须退出.Card-FullNameLabel6 个像素”,仅此而已。
但是,如果我们需要的定义之间的相同的垂直空间.Card-FullNameLabel,并.Card-OrganizationNameLabel在线路高度大于1(或它们的顶部和底部填充)?规则的值margin-top(下图中未覆盖的粉红色区域可视化).Card-FullNameLabel + .Card-OrganizationNameLabel现在是:
- 所需的范围(6px)
- 下面的额外垂直空间
.Card-FullNameLabel(指定为l_b) - 上方额外的垂直空间
.Card-OrganizationNameLabel(指定为l_a)
正如我上面说,心算是不允许的,因为它贬低编程(CSS中的情况下CSS预处理程序的能力),使灵活性/可维护性的影响(如果我们改变line-height或font-size或期望的标签之间的垂直空间,一切都需要在心理上重新计算)。
虽然预处理器的变量(今天在原生 CSS 中可用)可以解决这个问题,但维护它会太复杂。要计算上图中不相交的红色粉红色,我们需要:
- 变量
font-size化.Card-FullNameLabel - 变量
line-height化.Card-FullNameLabel - 计算下面的额外空间
.Card-FullNameLabel。 - 变量
font-size化.Card-OrganizationNameLabel - 变量
line-height化.Card-OrganizationNameLabel - 计算下面的额外空间
.Card-OrganizationNameLabel - Variablelize之间的期望范围
.Card-FullNameLabel和.Card-OrganizationNameLabel(在该实施例6点的像素)。
在此之后,我们可以最终计算margin-top规则.Card-FullNameLabel + .Card-OrganizationNameLabel。对于每对像.Card-FullNameLabel和这样的元素也是一样的.Card-OrganizationNameLabel!!2020 年代的 Web 开发技术太差。
原因2:不需要每种语言
在下面的示例中,日语符号非常适合与line-height: 1(16px) 对齐:
我想中文、韩文和许多其他具有非拉丁字符的语言也是如此。
但是:在少数情况下,外国符号可能会混合:
如果要谈高质量,必须支持这种情况。
我不想只为这个例外增加行高。线之间的垂直空间实际上变成了没有也没关系6px:尾部j或À具有较小的重量,不会破坏几何美学。
我的努力
尝试 1:使用:before和:after
SASS-mixinTextTruncation接受$extraSpace添加顶部和底部填充的参数。在:before和:after伪元素补偿这种垫衬负利润。
@mixin TextTruncation($extraSpace, $displayEllipsis: false) {
overflow: hidden;
white-space: nowrap;
@if ($displayEllipsis) {
text-overflow: ellipsis;
} @else {
text-overflow: clip;
}
padding-top: $extraSpace;
padding-bottom: $extraSpace;
&:before,
&:after {
content: "";
display: block;
}
&:before {
margin-top: -$extraSpace;
}
&:after {
margin-bottom: -$extraSpace;
}
}
body {
padding: 12px;
}
* {
line-height: 1;
font-family: Arial, sans-serif;
}
.Card {
display: flex;
flex-direction: column;
align-items: center;
width: 240px;
height: 320px;
padding: 6px 12px 12px;
background: white;
box-shadow: 0 0 3px rgba(0, 0, 0, 0.5);
}
.Card-FullNameLabel {
max-width: 100%; /* Required when the flex parent has `align-items: center` */
@include TextTruncation($extraSpace: 2px, $displayEllipsis: true);
font-size: 16px;
color: #707070;
}
.Card-OrganizationNameLabel {
max-width: 100%; /* Required when the flex parent has `align-items: center` */
@include TextTruncation($extraSpace: 2px, $displayEllipsis: true);
font-size: 12px;
color: #A2A2A2;
}
.Card-FullNameLabel + .Card-OrganizationNameLabel {
margin-top: 6px;
}
不幸的是,它不起作用:效果与没有定义边距和填充一样:
代码笔
尝试 2:使用包装器
如果组合overflow-x: hidden和overflow-y: visible工程,这是解决方案。但它不起作用,这个问题已经在问题CSS overflow-x:visible; 中考虑过。和溢出-y:隐藏;导致滚动条问题。
我想尽可能使用包装器,但在这里看起来包装器将是最后的手段。为了避免每次都写两个标签,我创建了 Pug mixin:
mixin SingleLineLabel
span.SingleLineLabel&attributes(attributes)
span.SingleLineLabel-Text
block
好吧,SingleLineLabel现在是一个组件。除了 Pug mixin 之外,还需要定义基本样式,SASS mixin 允许单独自定义标签:
// Constant styles
.SingleLineLabel {
overflow-y: visible;
&:before,
&:after {
content: "";
display: block;
}
&-Text {
display: block;
overflow-x: hidden;
white-space: nowrap;
}
}
// Variable styles
@mixin SingleLineLabel($truncatedVerticalSpaceCompensation, $displayEllipsis: false) {
&:before {
margin-top: -$truncatedVerticalSpaceCompensation
}
&:after {
margin-bottom: -$truncatedVerticalSpaceCompensation
}
.SingleLineLabel-Text {
padding-top: $truncatedVerticalSpaceCompensation;
padding-bottom: $truncatedVerticalSpaceCompensation;
@if ($displayEllipsis) {
text-overflow: ellipsis;
} @else {
text-overflow: clip;
}
}
}
现在我们可以应用它:
.Card-FullNameLabel {
max-width: 100%; /* Required when the flex parent has `align-items: center` */
@include SingleLineLabel($truncatedVerticalSpaceCompensation: 1px, $displayEllipsis: true);
font-size: 16px;
color: #707070;
}
.Card-OrganizationNameLabel {
max-width: 100%; /* Required when the flex parent has `align-items: center` */
@include SingleLineLabel($truncatedVerticalSpaceCompensation: 2px, $displayEllipsis: true);
font-size: 12px;
color: #A2A2A2;
}
.Card-FullNameLabel + .Card-OrganizationNameLabel {
margin-top: 6px;
}
好像达到了目标:
代码笔
不幸的是,它存在发生规律不清楚的错误。有时会出现小的垂直滚动条。
真不知道怎么复现,但是在过去的实验中也出现过,比如通过开发工具把浏览器切换到设备模拟模式,然后退出这个模式。如果在小提琴中重复相同的实验,很可能不会得到相同的效果。
最后
基于您的出色答案的解决方案将包含在不断增长的@yamato-daiwa/frontend库中。
如果你有这样的问题的符号的完整列表g,p,À,?等等,请与大家共享-我会用它来测试,并把它们添加到的溢出容限测试未来哈巴狗功能。