<div class="Card">
<div class="Card-FullNameLabel">Gregg Sims</div>
<div class="Card-OrganizationNameLabel">Compubotics</div>
</div>
Run Code Online (Sandbox Code Playgroud)
.Card-FullNameLabel有font-size: 16px和line-height: 1。.Card-OrganizationNameLabel有font-size: 12px和line-height: 1。.Card-FullNameLabel和之间的垂直空间.Card-OrganizationNameLabel必须正好为6px。.Card-FullNameLabel + .Card-OrganizationNameLabel {
margin-top: 6px;
}
Run Code Online (Sandbox Code Playgroud)
.Card-FullNameLabel并.Card-OrganizationNameLabel必须有溢出公差(例如,如果该内容会像ÀÇ?jgpfhjklb?iEstosTreMalfaci等它不能从parrent突出)。line-height: 1。可以做什么:将 Pug 预处理器的功能用于标记,将 CSS 预处理器用于样式。
初始小提琴不满足条件编号5:目前该卡不支持溢出。
line-height: 1,不好的做法我一再被告知我必须设置line-height的价值超过1.
很明显,设置 line-height: 1 是一种不好的做法。我提醒你,无单位值是与字体大小相关的,而不是与内容区域相关的,处理比内容区域小的虚拟区域是我们许多问题的根源。
好吧,我不打算对此提出异议。我想要的只是达到我的目标(如上所述)的工作解决方案。它的使用是我的责任,如果您同意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现在是:
.Card-FullNameLabel(指定为l_b).Card-OrganizationNameLabel(指定为l_a)正如我上面说,心算是不允许的,因为它贬低编程(CSS中的情况下CSS预处理程序的能力),使灵活性/可维护性的影响(如果我们改变line-height或font-size或期望的标签之间的垂直空间,一切都需要在心理上重新计算)。
虽然预处理器的变量(今天在原生 CSS 中可用)可以解决这个问题,但维护它会太复杂。要计算上图中不相交的红色粉红色,我们需要:
font-size化.Card-FullNameLabelline-height化.Card-FullNameLabel.Card-FullNameLabel。font-size化.Card-OrganizationNameLabelline-height化.Card-OrganizationNameLabel.Card-OrganizationNameLabel.Card-FullNameLabel和.Card-OrganizationNameLabel(在该实施例6点的像素)。在此之后,我们可以最终计算margin-top规则.Card-FullNameLabel + .Card-OrganizationNameLabel。对于每对像.Card-FullNameLabel和这样的元素也是一样的.Card-OrganizationNameLabel!!2020 年代的 Web 开发技术太差。
在下面的示例中,日语符号非常适合与line-height: 1(16px) 对齐:
我想中文、韩文和许多其他具有非拉丁字符的语言也是如此。
但是:在少数情况下,外国符号可能会混合:
如果要谈高质量,必须支持这种情况。
我不想只为这个例外增加行高。线之间的垂直空间实际上变成了没有也没关系6px:尾部j或À具有较小的重量,不会破坏几何美学。
:before和:afterSASS-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;
}
Run Code Online (Sandbox Code Playgroud)
不幸的是,它不起作用:效果与没有定义边距和填充一样:
如果组合overflow-x: hidden和overflow-y: visible工程,这是解决方案。但它不起作用,这个问题已经在问题CSS overflow-x:visible; 中考虑过。和溢出-y:隐藏;导致滚动条问题。
我想尽可能使用包装器,但在这里看起来包装器将是最后的手段。为了避免每次都写两个标签,我创建了 Pug mixin:
mixin SingleLineLabel
span.SingleLineLabel&attributes(attributes)
span.SingleLineLabel-Text
block
Run Code Online (Sandbox Code Playgroud)
好吧,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;
}
}
}
Run Code Online (Sandbox Code Playgroud)
现在我们可以应用它:
.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;
}
Run Code Online (Sandbox Code Playgroud)
好像达到了目标:
不幸的是,它存在发生规律不清楚的错误。有时会出现小的垂直滚动条。
真不知道怎么复现,但是在过去的实验中也出现过,比如通过开发工具把浏览器切换到设备模拟模式,然后退出这个模式。如果在小提琴中重复相同的实验,很可能不会得到相同的效果。
基于您的出色答案的解决方案将包含在不断增长的@yamato-daiwa/frontend库中。
如果你有这样的问题的符号的完整列表g,p,À,?等等,请与大家共享-我会用它来测试,并把它们添加到的溢出容限测试未来哈巴狗功能。
我知道您明确指出您需要保留line-height: 1和margin-top: 6px,但是当您发现记录的溢出 CSS 问题时,您有点坚持当前的限制。
如果可以灵活地对待这些限制,我有一个在视觉上与您最初想要的解决方案相同的解决方案。
我从你的初始小提琴开始,并在 html 中添加了省略号截断 CSS 和有问题的文本。
.Card-FullNameLabel,
.Card-OrganizationNameLabel {
max-width: 100%;
overflow: hidden;
text-overflow: ellipsis;
white-space: nowrap;
}
Run Code Online (Sandbox Code Playgroud)
结果就是这种状态,我称之为“原始”,因为它使你的line-height和margin价值观保持不变。请注意,我添加了一条overflow: hidden规则来代替有问题的overflow-x和overflow-y规则混合。
我建议对 CSS 进行以下更改。这增加到line-height允许1.5所有字体的上升部分和下降部分可见。然后我添加了负偏移边距来补偿:
.Card-FullNameLabel,
.Card-OrganizationNameLabel {
max-width: 100%;
overflow: hidden;
text-overflow: ellipsis;
white-space: nowrap;
/* Shows all ascenders and descenders */
line-height: 1.5;
}
.Card-FullNameLabel {
font-size: 16px;
color: #707070;
/* Compensates for line-height */
margin: -4px 0;
}
.Card-OrganizationNameLabel {
font-size: 12px;
color: #A2A2A2;
/* Compensates for line-height */
margin: -3px 0;
}
.Card-FullNameLabel + .Card-OrganizationNameLabel {
/* 6px visually (minus 3px) */
margin-top: 3px;
}
Run Code Online (Sandbox Code Playgroud)
结果可以在这里看到,我将其称为“建议的修复”。我已经确认结果在最新的桌面 Chrome、Firefox 和 MacOS 上的 Safari 以及 iOS 上的移动 Safari 中是一致的。
我根据“之前”和“之后”的屏幕截图制作了一个简单的动画,表明输出在视觉上是相同的,只是建议的修复不会切断字体的上升部分和下降部分。
请注意,您可以单击动画查看全尺寸、1:1 像素精度的版本。
我对所谓的“中间元素”进行了一些额外的测试,以证明即使中间存在元素,建议的修复也会与原始修复相同。
正如评论中明确指出的,要求之一是 CSS 中没有“硬编码”或“魔术”数字。因此,虽然上述解决方案有效,但需要提前进行手动算术。
这是一个更新的Codepen,它可以通过使用一些 SCSS 逻辑自动生成与上面显示的类似的 CSS,这些逻辑将根据这些输入值计算偏移量:
| 多变的 | 当前值 |
|---|---|
$globalLineHeight |
1 |
$minLineHeight |
1.5 |
$fullNameFontSize |
16px |
$fullNameLineHeight |
$globalLineHeight |
$orgNameFontSize |
12px |
$orgNameLineHeight |
$globalLineHeight |
$orgNameMarginTop |
6px |
出于演示目的,我添加了一些额外的代码,这些代码将显示“之前”和“之后”悬停效果,以便您可以看到 SCSS 逻辑与原始 CSS 相比的行为方式。正如 HTML 和 CSS 中所示,您可以删除以 开头的行以下的任何内容#DELETE-ME。