为什么在使用direction:rtl时,尾部标点符号会出现在开头?

36

这更像是一种好奇心。在开发一个多语言网页应用程序时,我注意到某些字符(例如标点符号!?。,)在块级元素的末尾时,如果写入方向是从右往左(如某些我不会说的亚洲语言),它们将呈现为放置在开头。

换句话说,该字符串

Hello, World!

被渲染为

!Hello, World

当放置在一个具有direction: rtl属性的

块中时,这一点变得更加明显。

如果将文本分为两部分并分别给予不同的颜色,则末尾的连续文本块将被呈现为两个不相邻的区域:

http://jsfiddle.net/22Qk9/

这种行为的意义是什么?我猜这可能是(所有?)从右到左语言的特殊性质,由浏览器自动处理,所以我不需要关心它,或者应该吗?


2
我并不是RTL语言方面的专家,但我敢猜测"!"在RTL语言中的使用与其遵循RTL语言规则相同,而间隔的非RTL文本则以本地LTR方向呈现。例如,在前往阿拉伯维基百科时,您可以看到RTL和非RTL单词之间的来回切换。 - deceze
这与Unicode双向字符串有关。意思是在同一文本块中有RTL和LTR文本,浏览器试图找出如何显示它。有一个unicode-bidi CSS属性可以用来控制显示内容https://css-tricks.com/almanac/properties/u/unicode-bidi/ - 我认为它的使用是不鼓励的。 - Quang Van
3个回答

46

1
有史以来最好的解决方案! - tuxy42

34
原因是感叹号“!”具有BiDi类O.N.('Other Neutrals'),这有效地意味着它适应周围文本的方向性。在这个例子中,因此将其放置在前面的文本左侧是正确的。对于从右到左书写的语言来说,这是完全正确的:终止标点符号出现在末尾,即左侧。

通常,您只为从右到左书写的语言使用CSS代码direction: rtl或更好的是HTML属性dir = rtl,并仅为它们使用。对于它们来说,这种行为是一种解决方案,而不是问题。

如果您仅出于特殊效果而使用direction: rtldir = rtl,例如使表格列从右到左布局,则需要考虑其影响。例如,在表格情况下,您需要为表格的每个单元格设置方向为ltr(除非您希望它们呈现为主要从右到左的文本)。

如果您在阿拉伯文本块中引用英语句子,则需要将包含英语文本的元素的方向性设置为ltr,例如:

<blockquote dir=ltr>Hello, World!</blockquote>

在W3C文档关于双向算法和行内标记的必要知识中,讨论了一个类似的情况(只是英文文本中嵌入了阿拉伯语),作为用例6。该文档有一些奇怪之处,比如使用cite标记引用文本,违反了W3C的建议。

8
接受的答案https://dev59.com/W2Ii5IYBdhLWcg3w8AJy#20799360适用于您可以控制值的标记/CSS的情况,如果您无法控制HTML,则以下方法可能有效。
如果您不知道页面是否会呈现为RTL或LTR,但某些文本明确为LTR(即仅英语),则可以使用LRE/PDF标记将该值包装在LTR区域中。无论页面的LTR或RTL方向如何,文本都将以LTR方式呈现。
当您有一些代码尝试呈现文本而无法更改其准确显示在页面上的标记时,此方法可行。例如,在某个嵌套子组件(或服务器端)中呈现“歌曲标题”或“公司名称”字段的值,而无法控制周围的HTML元素。
此类方法的一个缺点是(例如在此问题中提出的LRM提案),添加到文本的标记的复制粘贴通常会保留标记,但它们不可见/零宽度。虽然对于大多数情况来说这样做没问题,但请考虑这是否对您造成了问题。
近似示例代码(某些公司最后带有“Inc.”,如果按原样呈现在RTL页面上,则末尾将带有句点):
 // comanyName = "Alphabet Inc." - really likes dot at the end including RTL
 if(stringIsDefinitelyAscii(companyName))
 {
     companyName = "\u202A" + companyName + "\u202C"
 }
 return companyName;

关于LRE/PDF符号的详情可以在https://unicode.org/reports/tr9/#Explicit_Directional_Embeddings中找到:

LRE U+202A 左至右嵌入 将下一个文本视为从左到右嵌入。

PDF U+202C 弹出方向格式化 结束上一个LRE、RLE、RLO或LRO的范围。

可以在以下链接中找到一些检测字符串是否含有RTL字符的方法:如何检测字符属于从右到左语言?JavaScript:如何检查字符是否为RTL?如何检测字符串是否包含任何从右到左的字符?


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接