CSS深度学习 - 文本方向 direction 和 dir

dir 与 direction

在 HTML 中,指示元素中文本方向有如下几种方式。

第一种是直接使用 dir 属性去描述,详情 - dir

<div dir="rtl">
  <span>test1</span>
  <div dir="ltr">test2
    <div dir="auto">test3</div>
  </div>
</div>

第二种方式是使用 style 内联样式去实现,属性为 direction,常用的值有 ltrrtl,详情 - direction

<div style="direction: rtl;">
  <span>test1</span>
  <div style="direction: ltr;">test2
    <div>test3</div>
  </div>
</div>

还有一种方法是使用 writing-mode 去修改,这里不讨论这种情况,感兴趣的可以去了解
张鑫旭 - 改变CSS世界纵横规则的writing-mode属性
【CSS深入】设置不同块级流方向时的属性百分比计算

我们这里讨论前两种情况
上面代码的效果如下
在这里插入图片描述

dir 的取值有如下几种

  • ltr, 指从左到右,用于那种从左向右书写的语言(比如英语)。
  • rtl, 指从右到左,用于那种从右向左书写的语言(比如阿拉伯语)。
  • auto, 指由用户代理决定方向。它在解析元素中字符时会运用一个基本算法,直到发现一个具有强方向性的字符,然后将这一方向应用于整个元素。

这个属性可以被 CSS 属性 directionunicode-bidi 覆盖,如果 CSS 网页有效且该元素支持这些属性的话。

direction 则是一个 CSS 属性,用来设置文本、表列水平溢出的方向,与 dir 功能类似。
unicode-bididirection 是仅有的两个不受 all 简写影响的属性。unicode-bidi 是用来描述双书写方向文本的,如果一块内容同时包含有从左到右书写和从右到左书写的文本,那么用户代理(the user-agent)会使用复杂的 Unicode 算法来决定如何显示文本。unicode-bidi 属性会覆盖此算法,允许开发人员控制文本嵌入(text embedding)。

与 HTML 中的 dir 属性不同,direction 属性不会从表列继承到表单元格, 因为 CSS 继承遵从文档流, 而表单元格位于行内部, 但不在列内部。

二者的另一个区别体现在选择器的匹配上,相应的选择器有两种,类选择器 :dir() 和属性选择器 [dir=ltr]

  • [dir=ltr] 只能匹配有 dir 属性的元素,如果是用内联样式去实现的话就匹配不到。
  • :dir() 用来匹配特定书写方向的元素,他可以匹配使用样式实现后的元素。详情 :dir()

例如给上面的代码加上如下样式

[dir=ltr] {
  color: blueviolet;
}

在这里插入图片描述
这里只有使用了 dir 属性的元素会被匹配,匹配简单元素就需要使用类选择器
添加如下代码

div:dir(rtl) {
  color: red;
}
div:dir(ltr) {
  color: orange;
}
[dir=ltr] {
  color: blueviolet;
}

这里需要注意的是,类选择器只有火狐实现了支持,其他浏览器都是不支持的。
在这里插入图片描述
下面为 chrome 和 firefox 中的效果图
在这里插入图片描述
在这里插入图片描述

基本显示规则

我们看如下代码,其中一个 div 包含纯文本,一个 div 包含一个 span 包裹的文本

<h2>example 2</h2>
<hr>
<div dir="rtl">hello CSS test</div>
<div dir="rtl">
  hello 
  <span>CSS </span>
  <span>test</span>
</div>

他们的显示效果是一致的
在这里插入图片描述
因为这里会改变的只是内联元素块的左右顺序,所有的内联内容,都被算作一个同质内联盒子,是当作一个整体处理的,因此,只有近似右对齐效果,而具体每个文字都没有左右顺序的变化。

内联元素块,包括替换元素(replaced element),如 imgbuttoninputvideoobject等。因此,上面的例子,而当里面的 inline 元素设置 display: inline-block;,则会看到左右顺序的变化。如下

<h2>example 2</h2>
<hr>
<div dir="rtl">hello CSS test</div>
<div dir="rtl">
  hello 
  <span style="display: inline-block;">CSS </span>
  <span style="display: inline-block;">test</span>
</div>
<div dir="rtl">
  hello 
  <p style="display: inline-block;">CSS </p>
  <p style="display: inline-block;">test</p>
</div>

在这里插入图片描述
对块级元素,只有类似 text-align: right; 的效果。

<div dir="rtl">
  hello 
  <p>CSS </p>
  <p>test</p>
</div>
<div style="text-align: right;">
  hello 
  <p>CSS </p>
  <p>test</p>
</div>

在这里插入图片描述

扩展

到这里,基本的用法都已经介绍完了,但是看下面这些示例

<h2>example 3</h2>
 <hr>
 <div style="direction: rtl;">
   <span>1</span>
   <span>2</span>
   <span>
     4555
     <span>432</span>
   </span>
 </div>

 <p style="direction: rtl;">
   <span>span1</span>
   <span>span2</span>
   <span>span3</span>
 </p>

 <div style="direction: rtl;">
   <span>,</span>
   <span>。</span>
   <span>
     !
     <span>~!@</span>
   </span>
 </div>

在这里插入图片描述
what? 有没有一种,明明代码一毛一样,就是显示不一样的既视感。显示结果让你怀疑人生,粘贴复制不相信自己。
然并卵,不管在什么浏览器,怎么粘贴复制,显示结果还是这样。
数字、符号、字母 的显示结果完全不一样。

可以看在其他浏览器中的显示结果

firefox
在这里插入图片描述
IE
在这里插入图片描述
这说明,他们的显示是按照一定规则去显示的。

划重点!这里涉及到一个概念 Unicode 双向算法

我们要知道的是,字符在内存中存放的逻辑顺序,和在页面显示的顺序是不一样的。最常用来处理双向文字的算法是 Unicode 双向算法Unicode 定义了它其中每个字符的方向属性,浏览器应用的一组规则(通过这个来进行自动判断文本 Unicode方向属性应该使用哪种方向)在显示时产生正确的顺序由 Unicode 双向算法进行描述,也可以简称为 bidi算法

Unicode 方向属性包含三种类型:强字符弱字符中性字符
首先,文字方向分为 Left To right,例如,英文、汉字等。Right To Left,例如,阿拉伯文字、希伯来文字等。

字符方向显示包含
强字符Left or Right方向性确定,Left or Right,和上下文无关,且可能影响其前后字符的方向性英文、汉字、阿拉伯文字等
弱字符Left or Right方向性确定,但是不会影响前后字符的方向性数字、数字相关的字符
中性字符Neutral方向性不确定,由上下文环境决定其方向大部分标点符号、空格

看到这里,相信很多人已经大致可以猜到为什么会有上面的显示结果了。

页面上有一个文本显示的基础方向(全局方向),定义的是一个区域的总体方向。他决定从哪个位置开始书写文字。例如 HTML 的 dir 就可以控制一个区域的文本方向。

而一段文本中具有相同方向性的连续字符,称为方向串,例如一段文本中,有多个字符,包含阿拉伯文字和英文字符,这里英文字符和阿拉伯字符就属于不同的方向串

例如下面这段文字

ولدت (+86)176-1234-0000

对他进行删除,移动光标等操作,就会发现位置变换和你的预期是不一样的,因为这段文本包含了不同的方向串

他的方向如下,分为 7 个方向串
数字是弱字符,有自己的方向性,向右
阿拉伯文字为强字符,向左
符号为中性字符,受到强字符的影响,向左

ولدت (+86)176-1234-0000
0000       | >
-          | <
1234       | >
-          | <
176        | >
(          | <
86         | >
+)  ولدت   | <

而我们把其中的阿拉伯文字删掉后,自动会变为我们熟悉的样子。

(+86)176-1234-0000

我们还可以强制转换字符的方向性,使用如下的编码
第一类是隐式双向控制字符,使用他们可以影响被包裹起来的中性字符方向

名称Unicode CodeHTML Code描述
LEFT-TO-RIGHT MARK (LRM)U+200E&#8206;&lrm;左到右
Right-To-Left Mark(RLM)U+200F&#8207;&rlm;右到左
<!-- 使用隐式实体 -->
<p>ولدت &lrm;(+&lrm;86&lrm;)&lrm;176&lrm;-&lrm;1234&lrm;-&lrm;0000</p>
<p>ولدت &lrm;(+86)176-1234-0000&lrm;</p>

<!-- 使用一个内联元素区分开强字符并设置中性字符的方向 -->
<p>ولدت <span dir="ltr">(+86)176-1234-0000</span></p>
<p><span dir="ltr">ولدت</span> (+86)176-1234-0000</p>

<!-- bdi标签能隔离外面的方向,默认值为auto,自动判断文本应该使用哪种方向 -->
<p>ولدت <bdi dir="auto">(+86)176-1234-0000</bdi></p>
<p><bdi dir="auto">ولدت</bdi> (+86)176-1234-0000</p>

在这里插入图片描述

显示标记如下,需成对使用,使用一个开始标记和结束标记包裹

LEFT-TO-RIGHT EMBEDDING (LRE) | U+202A | &#8234; or dir="ltr"
RIGHT-TO-LEFT EMBEDDING (RLE) | U+202B | &#8235; or dir="rtl"
LEFT-TO-RIGHT OVERRIDE (LRO) | U+202D | &#8237; or <bdo dir="ltr">
RIGHT-TO-LEFT OVERRIDE (RLO) | U+202E | &#8238; or <bdo dir="rtl">
POP DIRECTIONAL FORMATTING (PDF) | U+202C | &#8236; or </bdo>

例如这样去使用
在这里插入图片描述
就会发现后面的电话号码是正常显示的,符号方向也正常。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值