乐趣区

关于前端:超长溢出头部省略打点坑这么大技巧这么多

在业务中,有这么一种场景,表格下的某一列 ID 值,文本超长了,失常而言会是这样:

通常,这种状况都须要超长省略溢出打点,那么,就会变成这样:

然而,这种展现有个毛病,3 个 ID 看上去就完全一致了,因而,PM 心愿可能实现头部省略打点,尾部齐全展现,那么,最终心愿的成果就会是这样的:

OK,很有意思的一个需要,最开始我认为只是实现一个 头部超长溢出打点 性能,然而随着实际,发现事件并没有那么简略,上面咱们就一探到底。

利用 direction 实现头部超长溢出打点

失常而言,咱们的单行超长溢出打点,都是实现在尾部的,代码也非常简单,像是这样:

<p>Make CSS Ellipsis Beginning of String</p>
p {
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
}

这里,咱们能够通过 direction,将省略打点的地位,从尾部挪动至头部:

p {direction: rtl;}

后果如下:

简略介绍一下 direction

  • direction:CSS 中的 direction 用于设置文本排列的方向。rtl 示意从右到左 (相似希伯来语或阿拉伯语),ltr 示意从左到右。

另外两个与排版相干的属性还有:

  • writing-mode:定义了文本程度或垂直排布以及在块级元素中文本的前进方向。
  • unicode-bidi:它与 direction 十分相似,两个会常常一起呈现。在古代计算机利用中,最罕用来解决双向文字的算法是 Unicode 双向算法。而 unicode-bidi 这个属性是用来重写这个算法的。

OK,那么上述需要,是不是简略的增加一个 direction: rtl 就能解决问题呢?咱们尝试一下。

direction: rtl 会导致应用下划线 _ 连贯的数字内容排版谬误

咱们给上述的代码,增加一个简略的构造:

<div>
    13993199751_18037893546_4477657
</div>
<div>
    13993199751_18037893546_4477656
</div>
<div>
    13993199751_18037893546_4477655
</div>
div {
    width: 180px;
    overflow: hidden;
    text-overflow: ellipsis;
    direction: rtl;
    white-space: nowrap;
}

成果如下:

~ 胜利了!~ 看似如同胜利了,然而出了一点小问题!

尽管实现了头部打点,然而咱们的数字结尾如同不是咱们想要的后果,认真看一下数字的结尾状况:

这是什么状况呢?

这是因为 direction 在解决纯数字、非纯数字文本 上的规定不统一,咱们再来看这么一段测试代码:

<div>
    11111_22222_33333_44444
</div>
<div>
    11111 22222 33333 44444
</div>
<div>
    aaaaa bbbbb ccccc dddddd eeeeee
</div>
<div>
    aaaaa_11111_22222_33333_44444
</div>

CSS 层面不思考溢出状况,仅作用 direction: rtl

div {
    width: 240px;
    direction: rtl;
}

在批改书写方向后,成果如下:

能够看到,这里十分外围的一点在于,对于纯数字的文本内容,数字的排列程序也会跟着相应的书写程序,进行反向排列

而形如 11111_22222_33333_44444 这种用下划线连贯的文本,解决的形式也会与 11111 22222 33333 44444 一样,实现了从左往右的排列,扭转了原有的程序。

多计划解决

因为咱们的 ID 是由纯数字加下划线组成,所以无奈绕开这种展现。

那么,基于这个现状,咱们能够如何去解决这个问题呢?

计划一:两次 direction 反转

办法一,既然最终展现的文案被反转了,那么咱们能够尝试通过多一层的嵌套,进行二次反转能够解决问题。

代码如下:

<div class="g-twice-reverse">
    <span>13993199751_18037893546_4477657</span>
</div>
.g-twice-reverse {
    overflow: hidden;
    text-overflow: ellipsis;
    direction: rtl;
    white-space: nowrap;
    
    span {direction: ltr;};
}

尝试后的后果如下:

能够看到,内容还是被反转了,咱们心愿的后果是 ...037893546_4477657。不过不必焦急,能够尝试再配合 unicode-bidi 属性试一下。最终发现,配合 unicode-bidi: bidi-override 能够实现咱们想要的最终成果:

.g-twice-reverse {
    overflow: hidden;
    text-overflow: ellipsis;
    direction: rtl;
    white-space: nowrap;
    
    span {
       direction: ltr; 
       unicode-bidi: bidi-override;
    };
}

最终后果如下:

完满!这里,咱们利用了两层构造:

  1. 外层的 g-twice-reverse 失常设置从右向左的溢出省略打点
  2. 内容增加一层 span,利用 direction: ltrunicode-bidi: bidi-override 的配合,在外部再反向反转排版规定。

当然,这里须要解释一下 unicode-bidi

bidi-override 的作用是对文本进行笼罩,使得其中的内联元素(inline element)依照咱们想要的书写方向展现。而 unicode-bidi: bidi-override 取值的作用是用于笼罩默认的 Unicode 双向算法以管制文本的显示方向。

这里,bidi-overridedirection<span> 中的组合,实现了更细粒度的文本方向解决。

计划二:通过伪元素毁坏其纯数字的性质

上述的计划须要齐全了解其思路还是有比拟高的老本的,比拟烧脑。

有没有更好了解的计划呢?咱们持续尝试。

既然下面被反转排版的内容是纯数字或者由下划线连接成的数字,那么咱们能不能尝试毁坏其纯数字的个性

譬如,给数组的头部增加一个看不见字母,尝试一下,这里结构两组数据比照一下:

<div class="g-add-letter">
    <span>a</span>
    <span>546_4477657</span>
</div>
<div class="g-add-letter">
    <span>a</span>
    <span>13993199751_18037893546_4477657</span>
</div>
.g-twice-reverse {
    overflow: hidden;
    text-overflow: ellipsis;
    direction: rtl;
    white-space: nowrap;
}

看看成果:

嘿,别说,这个计划看上去真的可行。只是增加一个 <span>a</span> 必定是不适合的,前面保护的同学必定一脸懵逼。并且这个 a 字母须要暗藏起来。思来想去,这不是和以前革除浮动的场景十分相似吗?这里应用伪元素再贴切不过,咱们再革新下代码:

<div class="g-add-letter">
    <span>546_4477657</span>
</div>
<div class="g-add-letter">
    <span>13993199751_18037893546_4477657</span>
</div>
.g-add-letter {
    overflow: hidden;
    text-overflow: ellipsis;
    direction: rtl;
    white-space: nowrap;
    
    span::before {
      content: "a";
      opacity: 0;
      font-size: 0;
    }
}

咱们通过伪元素,应用在元素后面增加了一个字母 a,并且设置伪元素的 font-size: 0opacity: 0,从外观上,齐全看不出有这么个元素,十分好的暗藏了起来,同时,起到了毁坏内容其纯数字的性质。

成果如下:

计划三:通过 \200e LRM 标记位

咱们持续优化咱们的计划。

下面通过伪元素的形式,曾经可能实现在对业务构造影响最小化及代码增量较少的前提下,实现想要的后果。

问题还是在于插入的这个字母 a,一来是不够优雅,二是这种解决方案更像是一种 HACK 的解决形式,随着工夫长河的推动,这种代码即使留下了正文,也容易造成可读性上困扰。

所以,咱们须要尝试替换掉这个 a 字母。

这里,通过查阅材料,最终找到了这样一个字符 — \200e

\200e:是左到右标记(Left-to-Right Mark,LRM)的 Unicode 码点。它是 Unicode 字符方向管制工具之一,用于强制将文本的浏览方向指定为从左到右。在前端排版中,特地是解决多语言文本时,因为不同语言书写时有不同的书写方向,因而能够应用 LRM 来指定文本的书写方向,以确保文本可能正确地显示。

这里,通过 \200e 替换掉 a,这里用 \200e 的目标与 a 的目标其实是不一样的:

  1. 在字符串后面通过伪元素增加一个 a,目标是毁坏其纯数字的个性
  2. 在字符串后面通过伪元素增加一个 \200e,目标是强制管制接下来文本的排版程序

增加 a 的计划相似于一种 Hack 技巧,而 \200e 能够了解为就是专门解决这种场景而诞生的特殊字符。

好,看看革新后的代码:

<div class="g-add-letter">
    <span>13993199751_18037893546_4477657</span>
</div>
.g-add-letter {
    overflow: hidden;
    text-overflow: ellipsis;
    direction: rtl;
    white-space: nowrap;
    
    span::before {
    content: "\200e";
    opacity: 0;
    font-size: 0;
  }
}

成果如下:

这样,咱们算是比拟完满的解决了这个问题。

计划四:通过 <bdi> 标签

那么,上述的计划曾经是最佳计划了吗?或者说,还有没有不须要增加伪元素的形式?

在查找解法的过程中,还发现了一个十分有意思的标签 — <bdi>

<bdi>:是一个 HTML 标签,示意“双向的隔离器”(Bidirectional Isolation)。它是一个比拟新的标签,次要用于解决混合显示多个语言文本时的排版问题。

在多语言文本中,因为不同语言之间的书写方向和文本组织形式可能有所不同,如果间接拼合在一起显示,容易导致排版凌乱,甚至呈现不非法的语言混排景象。而 <bdi> 标签则提供了一种简略的解决方案,能够隔离不同的语言文本,确保它们依照正确的程序出现,并防止凌乱的语言混排景象。

具体来说,<bdi> 标签能够将一段文本从四周文本隔离开来,创立一个独立的文本环境,使得文本可能依照正确的书写方向出现。在应用该标签时,能够应用 dir 属性来指定文本的书写方向,能够是从左到右(dir=”ltr”)或者从右到左(dir=”rtl”)等。

综上所述,<bdi> 标签的作用是提供一种简略的解决方案来排版混合显示多个语言文本,通过隔离不同的语言文本,确保它们依照正确的程序出现,并防止凌乱的语言混排景象。

因而,利用 <bdi> 标签,咱们能够再进一步省略掉伪元素的局部:

<div class="g-bdi">
    <bdi dir="ltr">13993199751_18037893546_4477657</bdi>
</div>
.g-bdi {
    overflow: hidden;
    text-overflow: ellipsis;
    direction: rtl;
    white-space: nowrap;
}

此种计划就比拟纯正,回归了最后的代码,只是多了一层 <bdi> 并且设置了其外部语言排版方向。

最终,后果如下:

上述四种计划的残缺代码,你也能够戳这里:CodePen Demo — 多种形式解决下划线数字的头部溢出省略打点排版问题

总结一下

本文,咱们介绍了一种在头部省略溢出的情境下,对于形如 11111_22222_33333_44444 这种用下划线连贯的文本,解决的形式会被看待成 11111 22222 33333 44444 一样的状况,导致了最终排版后果与咱们的预期不符。

为了解决这种问题,咱们介绍了 4 种不同的解决方案:

  1. 计划一:两次 direction 反转
  2. 计划二:通过伪元素增加字母,毁坏其纯数字的性质
  3. 计划三:通过 \200e LRM 标记位
  4. 计划四:通过 <bdi> 标签

上述 4 个计划的思维与解决形式各有优劣。围绕多语言排版波及了不同的常识,从一个很小的需要中,可能窥探到其中简单的逻辑。是一个很好的业务实操案例。

最初

好了,本文到此结束,心愿对你有帮忙 :)

更多精彩 CSS 技术文章汇总在我的 Github — iCSS,继续更新,欢送点个 star 订阅珍藏。

如果还有什么疑难或者倡议,能够多多交换,原创文章,文笔无限,满腹经纶,文中若有不正之处,万望告知。

退出移动版