CSS世界中方位与顺序的规则与演进之路

在 CSS 中,我们经常会与各种方向方位打交道。

譬如 margin、padding,它们就会有 margin-left、margin-right 或者是 padding-left、padding-right。还有定位中的 left、top、right、bottom,它们表示了上下左右不同的方位。

还有一种情况是从x方位到x方位,譬如 writing-mode、direction,它代表了一种顺序,表示块流动方向,或者文字书写的方向等。

本文将捋一捋 CSS 世界中的方位与顺序,探寻其中一些有意思的点。

writing-mode & direction & unicode-bidi

在 CSS 世界中,这 3 个属性都与排版顺序相关,互有关联但作用各异。

  • writing-mode:定义了文本水平或垂直排布以及在块级元素中文本的行进方向。
  • direction:设置文本排列的方向。rtl 表示从右到左 (类似希伯来语或阿拉伯语), ltr 表示从左到右。
  • unicode-bidi:它与 direction 非常类似,两个会经常一起出现。在现代计算机应用中,最常用来处理双向文字的算法是Unicode 双向算法。而 unicode-bidi 这个属性是用来重写这个算法的。

单纯看定义有点懵逼,我们简单的看几个应用示意图:

writing-mode 示意

writing-mode 基本只需要留意最常见的 horizontal-tb、vertical-lr、vertical-rl 。表示文本的行进方向,下图表示浏览器对 writing-mode 的支持完整的情况下输出的外观:

direction 示意

OK,那 direction 又为何呢?它表示文本排列的方向。

  • direction: ltr:默认属性。可设置文本和其他元素的默认方向是从左到右。
  • direction: rtl:可设置文本和其他元素的默认方向是从右到左。

有点绕,所以上 Demo 最为直观。假设,我们有如下结构:

 
 
 
 
  1.  
  2.     
  3. 1
  4.  
  5.     
  6. 2
  7.  
  8.     
  9. 3
  10.  
  11.     
  12. 4
  13.  
  14.  
  15. 这是一段正常顺序的文本

     

简单的 CSS 如下:

 
 
 
 
  1. p, ul { 
  2.     background: #ff00ff50; 
  3.     padding: 10px; 
  4. ul { 
  5.     display: flex; 
  6.     justify-content: space-between; 
  7.      
  8.     & > li { 
  9.         border: 1px solid #333; 
  10.     } 

正常情况下的样式如下:

我们分别给两组元素的父容器

    加上 direction: ltr 及 direction: rtl,则最终效果如下:

    可以看到,direction 可以改变子元素的排列方向,但是它确无法改变单段文本内(或是内联元素内),每一个文字的书写顺序。

    那如果,我希望 这是一段正常顺序的文本 这段文字,不是从左向右进行书写,而是反过来,从右到左进行书写,又该如何设置呢?

    unicode-bidi 示意

    这就需要请出 unicode-bidi 了。

    单独使用 direction: rtl 无法使单段文本内(或是内联元素内),文字的书写顺序改为从右至左。需要配合 unicode-bidi。

    CSS 中的 unicode-bidi 属性,和 direction 属性,共同决定如何处理文档中的双书写方向文本。

    还是上述的代码,我们改造一下:

     
     
     
     
    1. 这是一段正常顺序的文本

       
     
     
     
     
    1. p { 
    2.     direction: rtl; 
    3.     unicode-bidi: bidi-override; 

    结果如下:

    放到一起比较:

    这里除了 unicode-bidi: bidi-override,unicode-bidi: isolate-override 也能得到同样的效果。

    这里涉及了一个非常重要的知识 -- Unicode 双向算法。

    Unicode 双向算法

    双向文字就是一个字符串中包含了两种文字,既包含从左到右的文字又包含从右到左的文字。

    对于文字书写习惯,分为:

    1. 大多数文字都是从左到右的书写习惯:比如拉丁文字(英文字母)和汉字;
    2. 少数文字是从右到左的书写方式比如阿拉伯文(ar)跟希伯来文(he)。

    在现代计算机应用中,最常用来处理双向文字的算法是 Unicode 双向算法(Unicode Bidirectional Algorithm)。

    一个区域内有总体方向,决定从这个区域的哪边开始书写文字,通常称为基础方向。浏览器会根据你的默认语言来设置默认的基础方向,如英语、汉语的基础方向为从左到右,阿拉伯语的基础方向为从右到左。

    在 Web 中,我们有 3 种方式可以控制文字方向:

    1. html实体 - ‎ 与 ‏)
    2. 标签 与 dir 属性
    3. CSS 属性 direction + unicode-bidi

    本文介绍的就是 CSS 中的 direction + unicode-bidi 方式控制文字的书写方向。关于 Unicode 双向算法(Unicode Bidirectional Algorithm)本身还是非常复杂的,本文也仅仅只是简单提及,更为详尽的内容,你可以参考 UNICODE BIDIRECTIONAL ALGORITHM[1]

    writing-mode & direction & unicode-bidi 的一些应用

    除去本身的功能,下面我们来看看它们其它的一些应用场景。

    使用 writing-mode 进行创意排布布局

    writing-mode 非常适合用于进行一些创意排版。

    基础的类似中国古诗词的一些竖向展示:

     
     
     
     
    1.  
    2.     

      凉州词

       
    3.     

      葡萄美酒夜光杯,

       
    4.     

      欲饮琵琶马上催。

       
    5.     

      醉卧沙场君莫笑,

       
    6.     

      古来征战几人回。

       
 

给 .g-wrap 分别添加 writing-mode: vertical-rl 或者 writing-mode: vertical-lr 得到不同的效果:

 
 
 
 
  1. .rl { 
  2.     writing-mode: vertical-rl; 
  3. .lr { 
  4.     writing-mode: vertical-lr; 

CodePen Demo -- display poems by writing-mode[2]

又或者像是这样,利用 writing-mode:vertical-rl 实现标题的竖向排列,搭配内容形成有意思的报纸排版:

 
 
 
 
  1.  
  2.   

    Title Loomings

     
  3.   

    Call me Ishmael. Some years ago- never mind ho.... 

  4.   

     
 
 
 
 
 
  1. div { 
  2.   width: 750px; 
  3.   padding-left: 150px; 
  4. h2 { 
  5.   position: absolute; 
  6.   writing-mode: vertical-rl; 

得到这样的排版布局:

CodePen Demo -- writing-mode Layout Demo[3]

改变文本溢出省略位置,使之在头部进行省略

我们都知道,本文超长溢出的省略,通过都是在文本的最末尾。像是这样:

 
 
 
 
  1. Make CSS Ellipsis Beginning of String

     
 
 
 
 
  1. p { 
  2.     overflow: hidden; 
  3.     text-overflow: ellipsis; 
  4.     white-space: nowrap; 

这里,我们可以通过 direction,将省略打点的位置,从尾部移动至头部:

 
 
 
 
  1. p { 
  2.     direction: rtl; 

结果如下:

尝试了下运用在多行省略中,多行省略的打点会出现在最后一行的左侧,不符合需求。

CodePen Demo -- CSS Ellipsis Beginning of String[4]

使用 writing-mode 改变元素方位

这个小技巧是在张老师的博客中学到的:改变CSS世界纵横规则的writing-mode属性[5]

我们可以通过 writing-mode: vertical-rl,将元素转一个 90° 角:

 
 
 
 
  1.  
 
 
 
 
  1. div:hover { 
  2.     writing-mode: vertical-rl; 

看看效果,当 hover 的时候,将箭头从向右️改为向下 :

当然,现在这个功能完全可以用 transform 替代,但是在之前需要兼容 IE 系列的时候,不失为一个有意思的小技巧。

CSS 中的逻辑属性

下面一个章节,我们聊聊 CSS 中的逻辑位置。

我们知道,在我们使用类似 margin 和 padding 的时候,可以单独控制每个方向,例如 margin-top、padding-left。

然而,这种使用了 top/left/bottom/right 物理方向维度定义的属性,在不同的排版规则下,就非常容易出问题。

思考如下这样一个 DEMO,我们希望给古诗的题目的上方,添加一个 padding 值:

 
 
 
 
  1.  
  2.     

    凉州词

     
  3.     

    葡萄美酒夜光杯,

     
  4.     

    欲饮琵琶马上催。

     
  5.     

    醉卧沙场君莫笑,

     
  6.     

    古来征战几人回。

     
 
  •  
  •     

    凉州词

     
  •     

    葡萄美酒夜光杯,

     
  •     

    欲饮琵琶马上催。

     
  •     

    醉卧沙场君莫笑,

     
  •     

    古来征战几人回。

     
  •  
  •  
     
     
     
    1. .pt { 
    2.     padding-top: 100px; 
    3. .rl { 
    4.     writing-mode: vertical-rl; 

    可以看到,无论 writing-mode 如何,padding-top 始终指代物理方向的上方。

    基于这种不同排版规则,物理方向可能会带来一定的困扰这个问题,CSS 在 CSS Logical Properties and Values Level 1[6] 规范中,推出了 CSS 逻辑属性。

    CSS 逻辑属性与值是 CSS 的一个新的模块,其引入的属性与值能做到从逻辑角度控制布局,而不是从物理、方向或维度来控制。

    还是上述的 DEMO,我们可以使用 padding-block-start 替代 padding-top。

    重点:使用 padding-block-start 替代 padding-top:

     
     
     
     
    1. .pt { 
    2. -   padding-top: 100px; 
    3. +   padding-block-start: 100px; 
    4. .rl { 
    5.     writing-mode: vertical-rl; 

    这次再看看效果:

    padding 的位置由物理上的上方,变成了逻辑上的上方。

    完整的 Demo 你可以戳这里:CodePen Demo-- 物理方向与逻辑方向展示[7]

    margin、padding、border、relative 物理属性到逻辑属性的映射

    类似这样的属性,在规范中定义了挺多的,简单罗列一下具体的映射规则:

    margin 物理属性到逻辑属性的映射:

    padding 物理属性到逻辑属性的映射:

    border 物理属性到逻辑属性的映射:

    relative 物理属性到逻辑属性的映射:

    等等...(完整的列表,你可以戳这里:MDN - CSS 逻辑属性与值[8])

    在逻辑属性中没有方向性的概念,只有开始(start)和结束(end)、块(block)和内联(inline)的概念。比如说,在从左到右(LTR)中,start 是 left,但在从右到左(RTL),它是 right。

    逻辑属性下的盒子模型

    考虑到不同排版带来的逻辑问题,整个盒子模型也可以随之进行改变。

    下图,左边是物理盒子模型,右边是逻辑属性下的盒子模型。

    左:物理盒子 | 右:逻辑盒子

    物理方向与逻辑方向重叠

    当然,还有这样一种情况,就是设置的逻辑方向和物理方向重叠,譬如我们给一个正常从左往右,从上至下的元素同时设置 padding-top 和 padding-block-start,看看会发生什么:

     
     
     
     
    1. div { 
    2.     padding-top: 120px; 
    3.     padding-block-start: 100px; 

    这里如果物理方向与逻辑方向设置的 padding 重叠,将会取两个值中后面定义的那个。这里由于 padding-block-start 后于 padding-top 定义,所以 padding 的值为 100px。

    margin 和 border 同理。这里我的理解是,同个方向上还是只能存在一个 margin\padding\border,无论是逻辑方向还是物理方向,取后定义的值为准。

    CodePen Demo-- 物理方向与逻辑方向重叠 DEMO 展示[9]

    总结一下

    总结一下,当项目开始国际化,当国内更多的业务开始出海,国际化兼容适配也会越来越重要。好在 CSS 也一直在紧跟时代,推陈出新,当你的排版布局需要考虑不同的 writing-mode 的时,你需要开始考虑使用逻辑属性替代物理属性!

    最后

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

    如果还有什么疑问或者建议,可以多多交流,原创文章,文笔有限,才疏学浅,文中若有不正之处,万望告知。

    参考文章

    参考资料

    [1]UNICODE BIDIRECTIONAL ALGORITHM:

    https://unicode.org/reports/tr9/

    [2]CodePen Demo -- display poems by writing-mode:

    https://codepen.io/Chokcoco/pen/ExmmbeY

    [3]CodePen Demo -- writing-mode Layout Demo:

    https://codepen.io/Chokcoco/pen/OJmmJmj

    [4]CodePen Demo -- CSS Ellipsis Beginning of String:

    https://codepen.io/Chokcoco/pen/BaWBELx

    [5]改变CSS世界纵横规则的writing-mode属性:

    https://www.zhangxinxu.com/wordpress/2016/04/css-writing-mode/

    [6]CSS Logical Properties and Values Level 1:

    https://drafts.csswg.org/css-logical/

    [7]CodePen Demo-- 物理方向与逻辑方向展示:

    https://codepen.io/Chokcoco/pen/BaRRmgx

    [8]MDN - CSS 逻辑属性与值:

    https://developer.mozilla.org/zh-CN/docs/Web/CSS/CSS_Logical_Properties

    [9]CodePen Demo-- 物理方向与逻辑方向重叠 DEMO 展示:

    https://codepen.io/Chokcoco/pen/dyWReQV

    [10]改变CSS世界纵横规则的writing-mode属性:

    https://www.zhangxinxu.com/wordpress/2016/04/css-writing-mode/

    [11]CSS Logical Properties and Values Level 1:

    https://drafts.csswg.org/css-logical/

    [12]图解CSS:CSS逻辑属性:

    https://www.w3cplus.com/css/css-logical-properties.html

    [13]CSS Logical Properties Are the Future of the Web & I18N:

    https://dev.to/yuschick/css-logical-properties-are-the-future-of-the-web-i18n-11i1

    文章题目:CSS世界中方位与顺序的规则与演进之路
    文章路径:http://www.csdahua.cn/qtweb/news37/375737.html

    网站建设、网络推广公司-快上网,是专注品牌与效果的网站制作,网络营销seo公司;服务项目有等

    广告

    声明:本网站发布的内容(图片、视频和文字)以用户投稿、用户转载内容为主,如果涉及侵权请尽快告知,我们将会在第一时间删除。文章观点不代表本网站立场,如需处理请联系客服。电话:028-86922220;邮箱:631063699@qq.com。内容未经允许不得转载,或转载时需注明来源: 快上网

    成都快上网为您推荐相关内容

    服务器托管知识

    分类信息网