首页 > 其他分享 >超长溢出头部省略打点,坑这么大,技巧这么多?

超长溢出头部省略打点,坑这么大,技巧这么多?

时间:2023-04-27 10:45:45浏览次数:51  
标签:这么 direction 省略 rtl 超长 bidi overflow 文本 排版

在业务中,有这么一种场景,表格下的某一列 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 个方案的思维与处理方式各有优劣。围绕多语言排版涉及了不同的知识,从一个很小的需求中,能够窥探到其中复杂的逻辑。是一个很好的业务实操案例。

最后

好了,本文到此结束,希望对你有帮助

标签:这么,direction,省略,rtl,超长,bidi,overflow,文本,排版
From: https://www.cnblogs.com/coco1s/p/17358258.html

相关文章

  • 网络安全之文件包含漏洞就是这么简单
    前言文件包含漏洞属于代码注入漏洞,为了减少重复代码的编写,引入了文件包含函数,通过文件包含函数将文件包含进来,直接使用包含文件的代码;简单来说就是一个文件里面包含另外一个或多个文件。但我们除了包含常规的代码文件外,包含的任意后缀文件都会被当作代码执行,因此,如果有允许用户控制......
  • Sentinel为什么这么强,我扒了扒背后的实现原理
    大家好,我是三友~~最近我在整理代码仓库的时候突然发现了被尘封了接近两年之久的Sentinel源码库两年前我出于好奇心扒了一下Sentinel的源码,但是由于Sentinel本身源码并不复杂,在简单扒了扒之后几乎就再没扒过了那么既然现在又让我看到了,所以我准备再来好好地扒一扒,然后顺带写篇文......
  • RHEL8常用命令-Linux就该这么学2
       首先介绍系统内核和Shell终端的关系与作用,然后介绍Bash解释器的4大优势并学习Linux命令的执行方法。经验丰富的运维人员能够通过合理地组合命令,来更精准地满足工作需求,还可以尽可能地降低系统资源消耗。   本章选出常用的数十个Linux命令,它们与系统工作......
  • 接入小程序订阅消息,就这么简单
    更新完服务号的模板消息之后,我又赶紧把微信小程序的订阅消息给实现了!之前我一直以为微信小程序也是要企业才能申请,没想到小程序个人就能申请。消息推送平台......
  • 可视化大屏的终极解决方案居然这么简单,vue-autofit一行全搞定!
    可视化大屏适配/自适应现状可视化大屏的适配是一个老生常谈的话题了,现在其实不乏一些大佬开源的自适应插件、工具但是我为什么还要重复造轮子呢?因为目前市面上适配工具每一个都无法做到完美的效果,做出来的东西都差不多,最终实现效果都逃不出白边的手掌心,可以解决白边问题的,要么太......
  • Spring中事务嵌套这么用一定得注意了!!
    前言最近项目上有一个使用事务相对复杂的业务场景报错了。在绝大多数情况下,都是风平浪静,没有问题。其实内在暗流涌动,在有些异常情况下就会报错,这种偶然性的问题很有可能就会在暴露到生产上造成事故,那究竟是怎么回事呢?问题描述我们用一个简单的例子模拟下,大家也可以看看下面这段......
  • Pandownload凉凉后,可能只有这么一个不花钱的百度网盘提速方法
    一、速度变化beforeafter二、提速设置百度网盘右上角的设置——>传输——>下载提速——>去开启——>开启下载提速——>应用——>确定应用后,速度如果没有提升。那么记得重启网盘,再看看。三、其他也试过KinhDown、6盘等,真没啥鸟用。开启这个提速后,正常速度能到1~2MB/s,也是够用了。......
  • linux 下 rm 为什么要这么写?
    在我们的培训课程改为长期课之后(易生信培训改为长周期模式),大家学习、练习、理解宏基因组、扩增子、转录组、全基因组各个分析流程的时间也多了,每次直播都能提出很多代码使用的问题,更加促进了代码的理解、培训知识的落地、应用于自己的分析。有时一次直播全用来回答最近一周练习......
  • Python操作MySQL就是这么简单
    Python操作MySQL就是这么简单下载MySQL8.0安装MySQL8.0步骤2:选择安装类型步骤3:选择安装位置步骤4:配置MySQL8.0步骤5:安装MySQL8.0步骤6:完成安装启动MySQL8.0MySQL8.0的常用命令python的pymysql库操作方法安装pymysql库安装pymysql库连接到MySQL数据库......
  • 提高职场效率,原来可以这么简单
    身为职场人,你是否也有过类似的经历·看上去忙的很,手头东西又杂又多,但是一天过去了,到点下班发现啥都没做好·当领导布置任务时,常常做了A后就忘记B,任务零碎不会安排·做一件事情总是容易拖延,导致时间分配不均,耽误了整体的进度.....为什么会这样呢?归根结底,还是办事效率不够的问题。......