Web中向左向右
几米的绘本《向左走,向右走》自1999年出版,就一直是爱情的代名词。在Web的世界中有着同样的故事,即Web的向左向右,指的就是Web的排版方式(比如,左浮动、右浮动,Box Alignment中对齐方式等)、对齐方式(比如左对齐、右对齐)、书写方式(比如从左向右、从右向左)等。而Web中的向左向右和书写习惯(比如Writing Mode)有着紧密的关系,社区中很多开发者可能只习惯于自己的书写方式(比如从左向右),但事实上世界中还有很多其他语言,不同的语言其书写方式是不同,比如阿拉伯语,它就是从右向左。如果希望给用户提供一个更具体验的Web网站或应用,作为开发者就有必要掌握如何针对不同语言提供不同的呈现方式。这就是我和大家将要一起聊的Web中向左向右。
故事背景
世界上有很多种语言(简称世界语言),比如汉语、英语、印度斯坦语、西班牙语、阿拉伯语、俄语、葡萄牙语、德语和法语等。在互联中也有一些常用语言,比如英语、汉语、西班牙语、葡萄牙语、印尼语(马来语)、法语、日语、俄语和德语等。
在Web中,不同的语言在电子屏幕上有着不同的呈现方式,比如:
上图截取于“联合国教科文组织”官方,上图所列的语言也是联合国常用语言种类。
从上图可以看出,在互联网上有些语言是从左到右排列(查看),比如中文、英语、法语等,也有一些语言是从右到左排列(查看),比如阿拉伯语、波斯语、乌尔都语,维吾尔语,哈萨克语等(这些都是阿位伯语系)。
阿拉伯语系是互联网语言的第七大最常用的语言。阿拉伯语网站或应用的数量每天都在不断的增加。然而,奇怪的是,阿拉伯语系(大部分是在中东市场)要求的设计不仅要符合他们的需求和用户的舒适度,而且还要符合他们的语言标准,这使得开发者在开发相关应用的过程变得更为复杂。考虑到阿拉伯系都是从右到左书写和阅读的,开发人员在开发的时候常常会面临一系列问题。
注意:阿拉伯语不是唯一从右向左书写的语言。波斯语和希伯来语也是以同样的方式书写的。
虽然这看起来没什么大不了的,但是从右到左(RTL
)语言的开发需要注意很多相关的特性。而且这方面的资源也不多,所以开发者面对这样的业务场景使得情况变得更加复杂。对于开发者而言,仅从右向左(RTL
)和从左向右(LTR
)单方面而言,事情会更简单,但是如果两种方式混合在一起,事情就会变得更为复杂。
简单地说呢?就是按照书写模式来呈现不同的效果,就目前来看,主要的方式就是从左向右(LTR
)和从右向左(RTL
),在某些场景下也有垂直方向的书写模式,比如从上往下(古代的汉文就是这样的书写模式)。对于开发者而言,从左向右(LTR
)并不是件难事,因为我们平时做的,处理方式都是这种。但我们不能仅局限于以往,很有可能你面对的用户群体是阿拉伯语系,那你就要改变以往的处理方式。
接下来的内容,我们将会以
RTL
为主(即阿拉伯语系),因为这可能是大家更为感兴趣的部分。
面对不同语言场景,你可能会先想到,“界面必须翻转”。看上去很诡异,但这也是LTR
转换成RTL
要做的第一件事情。比如Facebook官网的首页:
如果你查看过其源码的话,你会发现在<body>
元素上设置了dir
属性,同时在CSS中设置了direction
属性:
从技术的角度上来说,HTML中的dir
属性和CSS中的direction
属性可以用来设置水平流的方向。有些语言是从左到右(LTR
)排列的(比如中文),而有些语言是从右向左(RTL
)排列的(比如阿拉伯语)。因此,采用这两种方式来控制文本水平流是至关重要的。但这也仅仅是其中的冰山一角。换言之,这两个属性对于CSS中排版布局的一些功能模块有着直接的影响。
和方向相关的CSS功能模块
在CSS世界中可以控制排版方向的特性有很多,比如我们熟悉的:
- 文本对齐:CSS Text Module Level 3或Level 4中的
text-align
,用来设置文本在水平方向的对齐方式 - 浮动:CSS Page Floats中的
float
属性,用来改变流的水平方向 - 定位:CSS Positioned Layout Module Level 3的
position
以及left
、right
也可以改变水平流的方向 - Flexbox布局:CSS Flexible Box Layout Module Level 1中的
flex-direction
- Grid布局:CSS Grid Layout Module Level 1中的
grid-template-columns
- CSS框对齐方式:CSS Box Alignment Module Level 3
- 书写模式:CSS Writing Modes Level 3
或许大家没有太强的体感,我们先来看看示例:
尝试着操作示例中的下拉选择项,你会发现我们熟悉的很多东西并没有完全按照dir
或direction
预期的那样进行改变。拿其中float
布局来说:
其中Flexbox和Grid在ltr
或rtl
中会显得好很多,但是碰到间距相关的属性比如*-right
、*-left
时,整个效果又将会差强人意。
上面我们看到的是现象,当然很多同学可能会说,我们只有 ltr
(Left-To-Right)的场景,没有必要花精力去了解和学习rtl
相关的东东。当然,很多同学会提到,针对不同的方式提供不同的CSS,比如:
.meida__object {
float: left;
margin-right: 20px;
}
[dir="trl"] .media__object {
float: right;
margin-left: 20px;
margin-right: 0;
}
如果仅从效果上来看,这样的方案的确是解决了dir
或direction
带来的差异性,但这同时也为开发者增加了不少的工作量,代码也变得更难维护。事实上呢?在Web中的RTL
还有很多事情需要做,甚至是很多技术细节,只有掌握这些,才能在RTL
这样的场景中游刃有余。
接下来,大部分内容会围绕着RTL
场景展开。
RTL的简介
RTL是“Right To Left”首字母的缩写,简单地说就是从右到左,在Web中主要是指布局和浏览方式。来看一个RTL
的Web示例图:
在CSS中页面排列的默认方向是 LTR
(“Left To Right”的简写),也是大家最为熟悉的方式。如果你使用浏览器开发者工具查看的话,你会发现客户端下的<html>
元素的dir
(或direction
)默认值也是ltr
。
W3C的 **CSS Writing Modes Level 3**规范中有专门对
direction
属性的阐述。在HTML相关的规范中也有对dir
属性相关的阐述。
比如下图就是LTR
(中文版本Facebook)和RTL
(阿拉伯语版本Facebook)对比效果:
注意,对于RTL
,文本是从右向左读取的,这正好与LTR
相反。幸运的是,客户端(比如浏览器)对这方面有较好的支持。如果我们希望切换文档语言的排列方向,最简单地的方式就是在文档根元素(即<html>
)显式的设置dir
属性:
<html dir="rtl">...</html>
当dir
属性的值被更改时,Web中的元素会自动切换(但有一个前提,这些元素没有设置其他的属性,比如float
、text-align
等)。不过有一点需要特别提出的是,dir
属性值要是为auto
时,它根据解析的内容自动切换方向。就这一点而言,HTML规范也有相关的描述:
当文本的排列方向确实未知时,建议开发者仅将此值(
dir="auto"
)作为最后的手段,并且不能应用于服务端。
另外,除了在<html>
根元素上之外的任何元素上我们都可以显式的设置dir
属性。当元素显式设置了dir
属性值时,客户端会根据dir
属性做出相应的客户端样式解析。比如:
<p dir="ltr">我是一个段落</p>
客户端对应的样式:
p[Attributes Style] {
direction: ltr;
unicode-bidi: isolate;
}
如果显式在元素上设置dir
的值为rtl
:
<p dir="rtl">أهلا وسهلا بك في المقال!</p>
客户端对应的样式则会变成:
p[Attributes Style] {
direction: rtl;
unicode-bidi: isolate;
}
上面我们看到的是HTML元素上dir
属性取值不同带来的差异。除此之外,在CSS中可以通过direction
属性来做相应的调整。如果你去查看Facebook的中文版本和阿拉伯语版本,就会发现他们之间的差异。先来看中文版本,通过浏览器开发者工具,你会看到像下图这样的结果:
可以看到,显式地在body
中设置了direction: ltr
(正好和<body>
中dir
的ltr
相匹配)。对于unicode-bidi
属性,这里暂且忽略,就当这个属性未显式地在样式中设置。接着继续看另外一种场景(切换到阿拉伯版本的Facebook),你会发现在阿拉伯语版本的时候,<body>
中的dir
属性的值变成了rtl
,同时浏览器默认的direction
和CSS中显式地在body
中设置的direction
都有所调整:
从最佳实践来看,更建议大
<html>
根元素上定义dir
属性的值,以确保在没有显式设置CSS的direction
样式的情况下也能较好的实现双向布局。
翻转设计的基本示例
如果从 LTR
过渡到 RTL
,首先是设计上的变化,简单地说就是一个翻转的设计。正如前面向大家展示的Facebook中文版(LTR
)和阿拉伯语版(RTL
):
为了更好的向大家展示LTR
和RTL
在翻转设计上的差异,我们把事情缩小一些,就拿最典型的一个模块来举例,即媒体对象(Media Object)。
针对于这样的一个模块,HTML结构可能像下面这样:
<div class="media">
<img src="https://s3-us-west-2.amazonaws.com/s.cdpn.io/182774/blueberry-cheesecake.jpg" alt="蓝莓芝士蛋糕" class="media__object">
<div class="media__body">
<h3 class="media__heading">蓝莓芝士蛋糕</h3>
<p>食谱描述的地方。</p>
</div>
</div>
添加一些样式,得到下图这样的一个效果:
上面的效果是我们常见的排版效果,也是大家熟悉的LTR
。接下来,我们换过一个角色,即你构建的是一个阿拉伯语版本的媒体对象。就HTML结构而言,和上面是一样的,不同的是内容换成了阿拉伯语。其中还有一个最大的不同之处,那就是在<div class="media">
元素上显式的设置了dir="rtl"
(如果整个网站是阿拉伯语网站的话,dir
可能会设置在<html>
或<body>
元素上)。如果样式不做任何调整的话,那么效果可能是像下面这样:
除了图像之外,所有东西都因为dir="rtl"
得到了翻转。造成这个现象的主要原因是.media__object
(<img>
元素)在CSS中显式设置了float:left
以及margin-right: 16px
。如果我们要真正的因为语言阅读方式不同,设计上也得到真正的翻转,那么就需要在dir="rtl"
下做样式上的差异化处理:
.media[dir="rtl"] {
.media__object {
float: right;
margin-right: 0;
margin-left: 2vw;
}
}
对于RTL
设计,一旦将.media
的dir
设置为rtl
时,就会镜像整个标记,.media__object
就将会放置在右侧,.media__body
就会放置在左侧。当然,要达到这样的效果,就需要在dir="rtl"
状态下,将.media__object
的float:left
置换成float:right
,以及相应的margin-right
置换成margin-left
。
在不同的方向下要调整部分CSS,主要因为我们使用的都是物理属性,如果将物理属性更换成逻辑属性,事情就会简单地多。有关于逻辑属性的运用,在后面的内容中将中详细的阐述。我们暂时先抛弃逻辑属性,回到HTML的dir
属性。
HTML的dir
属性会提定文本的方向和显式(从左到右或从右到左)。通常,浏览器可以识别方向,因为它是在Unicode字符集中分配的,但是使用dir
属性,你可以设置任何想要的方向。
前面也提到过,我们应该尽可能的使用dir
来设置方向,而不应该使用CSS的direction
属性,这主要是因为文本方向在语义上与内容相关,而不是与样式相关。
LTR和RTL的混合,让阅读变得更复杂
就LTR
或者RTL
单方面而言,都不是太难的事情,但是要将两者混合在一起使用,比如中文(或英文)与阿拉伯语系混合在一起排版,而且布局是LTR
,将会发生什么呢?他们混合在一起的排版效果可能看起来像下图这样:
就上图而言(默认是LTR
),对于一位阿拉伯语的用户来说,阅读起来是痛苦的,因为排版很混乱。它的读取顺序如下图所示:
为了避免这个现象,我们应该尽可能设置适当的语言方向。比如我们显式地在元素上设置dir="rtl"
,结果就会更符合预期的效果:
对于混合排版的场景,我们还可以显式的给dir
设置属性值为auto
。这样可以由用户代理(比如浏览器)来决定方向。它在解析元素中字符时会运用一个基本算法,直到发现一个具有强方向性的字符,然后将这一方向应用于整个元素。
最终效果可以查看下面这个DEMO:
Flexbox布局的LTR和RTL
Flexbox是现代Web布局中最受欢迎的模式之一。主要是因为有较大的灵活性,而且在大多数情况之下消除了为RTL
开发重新写样式。简单地说,LTR
和RTL
可以完美的融入到Flexbox布局中。
Flexbox具备这样的特性主要是因为它是基于文档的 书写模式,而书写模式又主要用于指定块在页面上的布局方式。在Flexbox布局中,Flex项目根据文档的书写模式来分配的。在英语和阿拉伯语中,书写模式(writing-mode
)的默认值是horizontal-tb
:
这里不对writing-mode
做过多的阐述,如果你从未接触过这方面的知识,建议你花点时间阅读下面相关的文章:
- CSS Writing Modes Level 3
- 使用
writing-mode
实现垂直排版 - CSS书写模式
- CSS Writing Modes
- Writing Modes And CSS Layout
- CSS Writing Mode
接下来假设你对writing-mode
有一定的了解(其实不了解也没关系,因为我们要聊的是Flexbox和LTR
以及RTL
)。了解Flexbox的同学都知道,在Flexbox容器中有一个flex-direction
属性,在主轴方向(Main Axis)有两个属性值row
(默认值)和row-reverse
。
从效果上看flex-direction
可以很轻易的实现类似LTR
和RTL
的效果。但事实上,它和dir
(或direction
)有着紧密的关系。如果dir
(或direction
)的值为ltr
时,则flex-direction
取值为row
时,Flex项目从左到右排列,如果取值为rtl
时,则Flex项目从右到左排列。而flex-direction
取值为row-reverse
时效果刚好与row
相反。具体可以看下面这个示例:
从上面示例我们可以得知,默认情况之下,flex-direction: row
就相当于dir="ltr"
,flex-direction:row-reverse
相当于dir="rtl"
。同样的,在Flexbox中使用flex-direction:row
和dir
结合起来就可以很好的实现LTR
和RTL
的布局效果:
利用上面说到的特性,重新来构造媒体对象的布局效果(中文版本和阿拉伯语版本):
刚才提到过,Flexbox是基于文档书写模式来布局的,试想一下,如果在Flexbox中加入了writing-mode
又将会发生什么呢?我们在上例的基础上加上相关的选项设置。
尝试着在上例中选择不同的writing-mode
。你将会看到书写模式对Flexbox以及dir
带来的相关变化。
从效果上来看,writing-mode
取值为horizontal-tb
时LTR
、RTL
和flex-direction: row
结合效果都是完美的。但是将writing-mode
更换为垂直排版(vertical-lr
和vertical-rl
)时,整理的效果就不是那么的理想了。针对这样的场景我们在布局时应该要注意些什么呢?这里暂且不表,把该话题留到后面的章节中一起探讨。
Grid布局中LTR和RTL
CSS Grid和Flexbox有点类似,也是基于writing-mode
(书写模式)来布局的。也就是说,CSS Grid布局中的LTR
和RTL
的使用和Flexbox相似。同样先看一个简单的示例,把上面的媒体对象更换成CSS Grid布局的方式:
用网格查看器,可以看到RTL
直接翻转了:
使用Grid和Flexbox还有一个较大的差异,不需要针对RTL
做一些样式的调整(至少在这个示例中是如此):
同样的,CSS Grid和writing-mode
有着密切的关系。在上面的示例基础上加上writing-mode
属性不同值的切换:
尝试着切换示例中的下拉选项,你会发现效果和前面的Flexbox类似。
CSS逻辑属性给LTR和RTL带来的变化
CSS逻辑属性(CSS Logical Properties and Values Level 1)是CSS的一个新特性。可能很多同学对该属性会感到陌生,这并不要紧。我们先来回忆一下,在以往的CSS中,我们有很多方向(比如*-right
、*-left
、*-top
和*-bottom
)、位置(比如top
、right
、bottom
和left
)等。这些属性被称为物理属性。在逻辑属性中有着和物理属性相对应的属性:
将这些属性放到CSS的盒模型中的话,会像下图这样:
如果你暂时对CSS逻辑属性不了解的话,建议你花点时间阅读一下下面这些文章:
时久以来(甚至是说自Web出现以来),开发者都习惯于用物理属性来处理元素的样式和位置等。但随着CSS的书写模式的出现,或者是我们今天聊的RTL
排版,这些物理属性就失去了它的意义。正如文章开头的示例,当ltr
切换到rtl
时,使用的CSS物理属性就失去它的意义,如下图所示:
虽然我们可以通过增加额外CSS来解决,但这总不是较好的方案。值得庆幸的是,CSS逻辑属性为些可以带来改变:
也可以说,CSS逻辑属性定义了一种新的布局方式。其主要目标就是帮助开发人员支持不同的书写系统,比如我们正在讨论的LTR
和RTL
(在writing-mode
也很有用)。这些新特性可以更好的帮助开发者控制布局。换句话说,逻辑属性允许开发者跨语言和书写模式维护布局的完整性。它们根据内容的语义顺序(而不是空间位置)进行动态更新。
在逻辑属性中,每个元素有两个维度,即块轴与行内轴:
在CSS逻辑中
*-start
替代了特理属性中*-left
;*-end
替代了特理属性中*-right
。
为了便于区分start
和end
,我们来看一个简单的示例:
尝试着在上面的示例中选择不同的writing-mode
,你会看到下图这样的效果:
如果你感兴趣的话,还可以看@Hussein Al Hammad提供的一个示例:
更多这方面的介绍还可以阅读:
- Bidirectional horizontal rules in CSS
- CSS Logical Properties
- Understanding positioning in CSS
- CSS 网格,逻辑值和书写模式
- How to Use CSS Logical Properties to Control Layout
- PostCSS Logical Properties and Values
LTR切换到RTL常见的错误
如果你能坚持阅读到这里,说明你对RTL
和LTR
,甚至是writing-mode
方面的布局感兴趣。也可能你了解到了LTR
和TRL
以及writing-mode
带来的变化。也知道了怎么通过CSS逻辑属性让RTL
(按writing-mode
)布局更灵活。
虽然Flexbox和Grid两个模块系统天生具备类似逻辑属性特性,甚至能很完美的匹配到
RTL
、LTR
和writing-mode
布局中,但要让其更完美就需要尽可能在避免在布局中使用物理属性。
即使如此,在RTL
中还是存在很多细节的问题。接下来,我们先来看看RTL
中常见的错误。
字间距
在CSS中我们可以通过letter-spacing
属性来给字母间增加间距(它也被称为活版印刷跟踪)。比如下图所示:
上图中的第二行使用了letter-spacing
给字母间增加了间距,它看起来是正常的。但是,如果将相同的letter-spacing
样式添加到阿拉伯语系的内容中,效果看起来就会令人感到非常的奇怪。比如下面这个示例:
正如上图所示,设置letter-spacing
的阿拉伯语中每个单词的字母看起来彼此不相连。这是不正确的。阿拉伯字母看起来应该是连在一起的(像上图红色虚线框中的那样),而保持英文字母之间的间距与之相反。因此,在阿拉伯语中(RTL
)中应该确保letter-spacing
的值为0
。
文本的透明度
在Web中给文本增加一定的透明度是常见的一种行为。但在阿位伯语中给文本增加透明度,给人的感觉会怪怪的。
你会发现字母之间有一些不同颜色的区域。看上去是有层叠区域造成的颜色不一致,就上图来说,看上去更白一些:
解决方案是“尽可能的不给文本添加透明度”。
不同语言之间字大小差异
不同语言中的字大小是有一定差异的。比如说英文翻译成阿拉伯文后有些单词就会变大或变小,因此元素的大小也会发生变化(内容容器)。比如:
从上图上你可能发现了这种现象。这样一来不同的语言运用同一套样式的时候就会产生很多问题。比如说,在div.menu_login_container
容器中设置了明确的容器宽度width: 393px
。对于英文版本来说,这可能是刚刚合适,但一旦切换到阿拉伯文时,就会造成内容被溢出,或者断行,如果容器被设置了overflow: hidden
等样式还会造成内容被裁剪等现象。我们来模拟一下:
面对这样的场景,很多同学可能会为不同的语言版本添加不同的样式。在CSS中也可以考虑使用min-width
给容器设置尺寸。或者 CSS Intrinsic & Extrinsic Sizing Module Level 3 规范中新特性:min-content
、max-content
和fit-content()
等。
文本截取
在项目中会遇到文本截取的需求(text-overflow:ellipsis
):
上面的效果应该是符合我们预期的。如果在中文版本和英文版本中设置了dir="rtl"
时,效果和我们阅读习惯就不同了,甚至是一种错误的表现行为:
要解决这个问题的话,dir
需要根据语言的正确阅读方式来设置正确的值。如果你不清楚语言的阅读方式或者无法预判用户会将应用切换到何种语言的话,建议将dir
的值设置为auto
。这样一来,浏览器会自动的根据语言的阅读方式来处理文本截取的效果:
不宜设置相同的line-height
如果需要一个更好的阅读体验,可能会为不同的布局(LTR
或RTL
)设置不同的语言。但是为不同的RTL
排版设置相同的line-height
的话,阅读体验就有可能达不到你预期所要的效果。比如给英文和阿拉伯文设置相同的line-height
,在阿拉伯文中看上去行与行的间距要更小:
如果想改变这样的一个状态的话,需要考虑为阿拉伯语的内容提供一个更适合的line-height
。另外不建议line-height
使用固定单位的值,这样在一些语言的切换状态下很容易造成文本展示不全(类似被截)。比如下图的效果:
CSS中的
line-height
是个很复杂的体系,有关于这方面更详细的介绍,可以阅读《深入了解CSS字体度量,行高和vertical-align
》一文。
不采用默认的文本下划线
有些文本会带有默认下划线的效果,比如<a>
链接。在阿拉伯语言的文本中,默认的文本下划线会让阅读变得很困难。造成这种现象的主要原因是阿拉伯语单词和字母的书写方式有关。如下图所示:
你会发现,文本下划线会和一些文本重叠,比如单词中的一些点:
另外,采用默认的文本下划线,不同的浏览器渲染出的效果也会有所差异:
很明显,Chrome和Firefox浏览器的效果不会出现我们上面所说的现象(在这方面可能做了一定的优化),但是在Safari浏览器中,就出现了上面所描述的现象。另外可能在一些UI效果上趋向于风格的统一。所以在给文本加下划线的时候,更建议采用自定义的下划线风格。在CSS中有很多种不同的方案来实现自定义下划线的效果,比如border-bottom
、box-shadow
、background-image
等,还可以给文本添加SVG的下划线。除此之外,CSS Text Decoration Module Level 4 提供的一系列text-decoration-*
属性也可以实现一些个性化的下划线效果:
a {
text-decoration-color: rgba(21, 132, 196, 0.2);
text-decoration-style: normal;
text-underline-offset: 4px;
text-decoration-thickness: 2px;
}
断行需要独立处理
如果在样式中使用断行处理的相关样式,比如word-break
,那么在阿拉伯语的应用中需要进行单独的测试,因为它可能会破坏阿拉伯语单词。如下图所示:
上图中圈出的部分是由于断句带来的影响。在阿拉伯语中,没有断字这回事。一个单词的字母是相互联系的,所以不可能打破一个单词。
尽量避免给文本加粗和使用斜体文本
在大多数RTL
语言(比如阿拉伯语)的应用中应该尽量避免使用粗体(font-weight
)和斜体(font-style: italic
)。因为大多数RTL
语言中,粗体文本会让应用的可读性变得更为困难,而斜体几乎是不被使用。同样的,在RTL
语言中,几乎会忽略大写字母。
双向语言的最佳用户体验
这里所谓的双向语言指的是LTR
和RTL
的输入顺序(语言)和文本显示布局的能力。前面我们花了一些时间和大家聊了聊双向语言在Web网站或应用中的差异以及开发者切入到RTL
中会碰到的一些问题。事实上除了开发者,对于设计师以及用户体验,双向语言都会有很多细节需要我们一起注意,或者说有很多问题需要我们一起面对。
在文章的开头也向大家展示了LTR
到RTL
最大的差异:UI布局上来看,双向语言的UI布局是一种镜向的布局效果。
双向语言的Web网站或应用为什么在UI上看上去是一个镜像的布局呢?这主要是不同的语言阅读习惯和方式有所不同,即LTR
和RTL
。好比我们熟悉的中文、英文是从左向右(LTR
)阅读,而对于阿拉伯语则是从右向左(TRL
)阅读。
表面上看上去是一种反向的切换,但事实上,这里面有很多细节是需要我们注意或者单独处理的。接下来,我们来看看需要注意的一些细节(主要围绕着UX来展开)。
图标
在现代Web中开发中,图标的应用是非常的广泛,正所谓“一图胜过千言万言”,对于图标(Icon图标)的使用也是如此,很多时候图标能很明确的告诉用户所代表的含义,比起文本的描述要更具效果。但在RTL
开发中图标的使用要比LTR
复杂的多,也麻烦的多。
在
RTL
语言中有很是具有较强的宗教信仰,民俗民风也较强,因此图标的使用也需要特别的注意,因为一不小心就可能会冒犯到你的用户。这是很复杂的事情,我们先抛开这个体系,只聊聊技术上实现的差异。
没有方向性的图标
很多Icon图标实际上是对称的而且没有任何方向性。那么在双向语言中,这些图标是不需要做任何的处理(翻转)。比如:
需要镜像的图标
在双向语言系统中有些图标是具有方向性的。也就是说在LTR
和RTL
中要改变它们的方向,而且这一点对于用户来说是非常重要的,因为这样做才能让用户更好的,更清楚地理解图标的具体含义。比如:
对于需要镜像的图标,仅仅使用dir
(或direction
)是无法达到所要的效果:
<div class="wrapper">
<h2>具有方向的(LTR)</h2>
<div class="box" dir="ltr">
<i class="fa fa-caret-right" aria-hidden="true"></i>
<i class="fa fa-fast-forward" aria-hidden="true"></i>
<i class="fab fa-accessible-icon" aria-hidden="true"></i>
<i class="fas fa-running" aria-hidden="true"></i>
</div>
</div>
<div class="wrapper">
<h2>具有方向的(RTL)</h2>
<div class="box" dir="rtl">
<i class="fa fa-caret-right" aria-hidden="true"></i>
<i class="fa fa-fast-forward" aria-hidden="true"></i>
<i class="fab fa-accessible-icon" aria-hidden="true"></i>
<i class="fas fa-running" aria-hidden="true"></i>
</div>
</div>
如果我们希望在RTL
语言中让图标实现镜像,则需要添加额外的CSS来处理。在CSS中,我们可以借助transform
的scaleX(-1)
来实现水平镜像的效果:
[dir="rtl"] i {
transform: scaleX(-1)
}
带图标的按钮和表单控件
通常有些按钮会带上相应的Icon图标。在这种情况下,在RTL
布局中,图标的位置也需要进行翻转:
对于表单控件也是如此,特别是对于输入型的input
表单控件,还应该保持输入的方向性:
导航菜单和面包屑
对于导航菜单以及页头,还有面包屑等UI的设计在双向语言中是UI的镜像。
数字顺序
在双向语言中,对于数字的顺序(比如电话号码,门牌号等),不需要做镜像的处理。但要是带有图标的话,对应的图标还是需要做镜像的处理。比如:
上面列出的仅仅是其中的一小部分而以,如果你对这方面感兴趣的话,可以花点时间阅读@Gilad Almosnino的《UX Best Practices for Bi-Directional Languages》一文。
RTL示例
如果你的业务不涉及中东地区或者应用阿拉伯语系的区域,可有不会有机会要单独处理RTL
的场景。不过这只是客观因素,如果你对这方面的知识或者想实战一把的话,还是有相应的机会。比如说,你可以徒手撸一个阿拉伯语的Facebook或者联合国教科文组织官网等,甚至你可以找任何一个你喜欢的阿拉伯语网站。
另外@Ahmad Shadeed在《RTL Styling 101》一文中的最后一节,专门向大家介绍了如何构建一个RTL
的应用。
小结
对于开发者而言,处理一个双向语言的Web网站或Web应用不是一件易事,特别是RTL
排版。除了要考虑技术因素之外,还需要考虑人文方面的因素。前面也提到过,RTL
布局一般都是阿拉伯语系,而使用这些语系的人群都有较强的宗教信仰。也就是说,要是开发一个阿拉伯语言的网站或应用,从人文到设计,从设计到开发,都有很多细节需要处理。文章中提到的仅仅是其中的一小部分而以,如果想彻底的掌握这方面的技术,最佳的方式还是实战。实战是检验的最佳方式。
如果你想掌握更多有关于RTL
的相关知识,还可以阅读下面这些文章:
- RTL Styling 101
- Right-To-Left Development In Mobile Design
- 5 Tips To Deal with Right-to-Left Projects
如果从CSS方面来考虑的话,那么CSS的Flexbox、Grid布局有着天然的特性 ,它们能较发了的融入RTL
布局需求,另外就是CSS的逻辑属性以及书写模式,它们是RTL
布局最佳的支持者。有关于这方面的特性,在文章中也有简单的提到过,感兴趣的可以针对性的深入学习。
最后感谢大家花时间阅读完这篇文章。如果你在这方面有更好的建议或经验,欢迎在下面的评论中与我们一起分享。