# 阿拉伯语右排布局

# 右排布局概述

在普通的网页里,阅读方向是从左往右,但阿拉伯语的阅读方向是从右往左。通过查看阿拉伯语网站和GoogleMaterial Design双向性文章 (opens new window),对比从左到右(LTR)语言网站,从右到左(RTL)语言的网站特点:

  • 排版是从右往左
  • 文本是向右对齐且从右往左阅读,文本方向始终和语言保持一致,比如数字(电话号码、时间)
  • 方向性图标和LTR相反,其他的图标和图片不会镜像

通过上面知道RTL布局的特点后,我们在现有的项目里支持RTL布局需要考虑:

  • 以低成本、代码入侵少、可兼容、可维护的改造线上的代码支持RTL布局
  • 对于未来新增的页面功能能快速支持LTR和RTL布局

# RTL布局两种方案

# 方案一: 基于transform镜像

通过transform的镜像翻转,使用CSS3transform属性,通过transform: scaleX(-1)可以使页面沿着X轴进行水平翻转,可以快速的解决布局镜像的问题,思路:

  • 在阿拉伯语页面上添加上全局翻转:
    /* xx/index.css */
    html[lang="ar"] {
      transform: scaleX(-1);
    }
    
  • 将页面中不需要翻转的内容进行包裹
    /* xx/index.css */
    html[lang="ar"] .not-flip {
      transform: scaleX(-1);
    }
    

处理后的效果如下:

transform方案优点是无需修改js逻辑,只需要处理css;缺点是我们有五个项目,PC端和移动端,代码入侵大,工作量大,所有涉及到文本和图片的地方都需要进行处理。

# 方案二: 基于direction属性

direction与在html标签上直接添加dir="rtl"的作用一样,可以改变我们网站的布局,CSS手册中对direction属性是这样描述的:该属性指定了块的基本书写方向,以及针对Unicode双向算法的嵌入和覆盖方向。通俗的讲,排版改成从右往左,文字和图片方向不变。 我们在github上找到postcss-rtl开源插件,它的原理就是对CSS文件进行处理,比如将 CSS属性中的left改为rightright改为left

[dir] .foo {
  text-align: right;
}
[dir="ltr"] .foo {
  text-align: right;
}
[dir="rtl"] .foo {
  text-align: left;
}

基于direction属性RTL布局方案:

  • webpack中引入插件postcss-rtl (opens new window)
    • vue-cli2脚手架配置: 安装依赖yarn add postcss-loader postcss-rtl -Dwebpack中(cloud/build/utils.js)文件里添加postcss-loader的插件postcss-rtl
      var postcssLoader = {
        loader: 'postcss-loader',
        options: {
          postcssOptions: {
            plugins: [
              [ 'postcss-rtl', {} ] // 添加阿拉伯语右排布局插件
            ]
          }
        }
      }
      
      // generate loader string to be used with extract text plugin
      function generateLoaders(loader, loaderOptions) {
        var loaders = [cssLoader, autoprefixerLoader, postcssLoader]
        if (loader) {
          loaders.push({
            loader: loader + '-loader',
            options: Object.assign({}, loaderOptions, {
              sourceMap: options.sourceMap
            })
          })
        }
        ...
      }
      
    • vue-cli3脚手架配置: 安装依赖yarn add postcss-rtl -Dwebpack中(apps-moblie-docs/vue.config.js)文件里添加postcss-rtl插件
      css: {
        sourceMap: !isProduction,
        loaderOptions: {
          postcss: {
            plugins: [
              require('postcss-rtl')() // 添加阿拉伯语右排布局插件
            ]
          }
        }
      }
      
  • html标签属性添加默认值dir="ltr", 比如: <html dir="ltr">
  • app.vue入口里添加根据语言判断修改html的dir属性,比如: document.documentElement.setAttribute('dir', this.$i18n.locale === 'ar' ? 'rtl' : 'ltr')
  • 方向的图标处理:
    // 适配右排布局图标方向
    [dir=rtl]{
      .components-icons{
        &.components-icons-back{
          &:before {
            display: inline-block;
            transform: scaleX(-1);
          }
        }
      }
    }
    
  • 元素拼接的语句的处理:
    // 适配右排布局
    [dir=rtl] {
      .yun-row__desc {
        direction: ltr;
        display: inline-flex;
        justify-content: flex-end;
      }
    }
    

处理后的效果如下:

direction方案优点是工作量减少,代码入侵减少;缺点是需要处理方向性的图标的方向和被元素拼接的语句(断句)。

# 结论

方案 优点 缺点
transform 无需修改js逻辑,只需要处理css 代码入侵大,工作量大
direction 工作量减少,代码入侵减少 处理方向性的图标的方向和被元素拼接的语句(断句)

综合transformdirection方案各方面比较,direction方案的工作量减少、代码入侵少,最后决定使用direction方案。