企业级的阿拉伯市场适配方案

大家好,我是刘布斯。

这两年互联网产品出海比较火热,前端领域比较热门的国际化工具是 i18n,对于阿拉伯国家来说,他们的阅读习惯是从右往左,这种语言习惯的变化,大家又有什么好的适配方案呢?

今天就给大家分享的这篇文章,里面介绍的是企业级的解决方案,以下是正文:


背景

最近在公司接到一个需求,是对公司的一个产品进行阿拉伯适配。之前也接过类似的需求,什么西班牙语,俄罗斯语啦,这些无非就是对语言进行翻译,(因为公司原有的产品就已经使用了 i18n 进行了国际化适配了),但是仔细了解过后发现阿拉伯的适配和之前的方案有很大的不同。

这主要是由于阿拉伯国家的阅读习惯的不同导致的。大多数国家的阅读习惯都是是从左往右的,但阿拉伯的阅读习惯却是从右往左的。

这也就导致了阿拉伯国家的页面特点:

  • 排版是从右往左。

  • 文本是向右对齐且从右往左阅读,文本方向始终和语言保持一致,比如数字(电话号码、时间)

  • 方向性图标和我们的方向相反,但其他的图标和图片不会镜像

所以要适配阿拉伯国际,不仅仅在于它文案的适配,更多的是在于其语言习惯的变化。

如何适配页面呢?

目前市面上最常见的适配方案有两种,一种是"通过 transform进行镜像翻转",另一种是“在 html标签上直接添加 dir="rtl"来改变页面的排版方向”。下面我们来详细分析分析两种方案的利弊吧!

方案一:通过 transform进行镜像翻转

在阿拉伯语页面上,我们可以对全局应用 transform:scaleX(-1) 来实现页面的水平翻转。这样可以快速解决布局镜像的问题。然后,再对于不需要翻转的内容,进行二次翻转。这里我们可以使用一个特定的类(如 .not-flip)来包裹,并再次应用 transform:scaleX(-1) 来进行反向翻转,从而保持内容的正常显示。

在阿拉伯语页面上添加上全局翻转:

  1. /* 全局应用水平翻转 */

  2. html[lang="ar"] {

  3. transform: scaleX(-1);

  4. }

  5. /* 对不需要翻转的内容进行反向翻转 */

  6. html[lang="ar"] .not-flip {

  7. transform: scaleX(-1);

  8. }

我们可以将翻转相关的样式单独放在一个CSS文件中,并通过条件加载或动态添加CSS类的方式来应用,如果需要动态处理,可以使用JavaScript来检测语言并应用或移除翻转样式。

示例:

  1. // 等待整个文档内容完全加载后再执行

  2. document.addEventListener("DOMContentLoaded", function() {

  3. // 检查文档的根元素(html)的语言是否为阿拉伯语

  4. if (document.documentElement.lang === "ar") {

  5. // 如果是阿拉伯语,将根元素的水平缩放设置为-1,实现水平翻转

  6. document.documentElement.style.transform = "scaleX(-1)";

  7. // 选择所有带有类名 "not-flip" 的元素

  8. const notFlipElements = document.querySelectorAll(".not-flip");

  9. // 遍历所有选中的 "not-flip" 元素

  10. notFlipElements.forEach(function(element) {

  11. // 将每个 "not-flip" 元素的水平缩放设置为-1,恢复正常显示

  12. element.style.transform = "scaleX(-1)";

  13. });

  14. }

  15. });

处理后的效果如下:

如上图所示,通过翻转解决了布局问题,但文字和图像也被翻转。为了解决这个问题,对于不需要翻转的内容(如文字、非指向性图像),需要进行二次翻转。

优缺点

优点: 无需修改js逻辑,只需要处理css。

缺点: 首次翻转只需要处理根节点,而二次翻转则需要处理所有不需要翻转的元素,工作量较大。

方案二:在 html标签上直接添加 dir="rtl"

在html标签上直接添加dir="rtl"的作用和 direction:rtl样式的效果是一样,它可以改变我们网站的整体布局,实现从右到左(RTL)的页面布局,这种方式会改变文本、表格列和水平溢出的方向,但不会改变文字和图片的显示方向

html标签属性添加默认值dir="ltr", 例如如: <htmldir="rtl">

处理后的效果如下:

在设置页面为RTL(从右到左)布局后,我们可以发现UI并没有完全兼容RTL场景。具体观察到以下情况:

  1. 文本对齐:

    • 如果元素没有预先定义 text-align,那么该元素的文本会从左对齐变成右对齐。

    • 如果设置了 left 或 center,则 direction 的设置不会对其产生影响。

  2. 布局方向:

    • inline-block、 flex、 table、 grid 的布局方向会受到影响。

    • absolute、 fixed、 float、 margin、 padding 等属性不会受到影响。

为了确保页面在RTL布局时能够正常呈现,我们需要对未被影响的属性进行调整。目前有以下三种解决方案:

使用CSS逻辑属性与逻辑值

CSS逻辑属性和逻辑值使用抽象术语块向和行向描述其流向:

  • 块向尺度(block):垂直于文本流向的尺寸。

  • 行向尺度(inline):与行内文本流向平行的方向上的尺度。

在LTR(从左到右)布局时:(把css样式代码从物理特性修改成逻辑性质)

逻辑值

详细的对照可以看下面这两张图

Example: Logical Properties Mapping (codepen.io)

Physical Property(物理特性)

Logical Property (逻辑性质)

通过改写为逻辑属性,可以同时适配LTR和RTL布局,无需专门为RTL布局进行适配。例如:将 margin-left 改写成 margin-inline-startleft:0; 改写成 inline-start:0;我们只需要全局替换需要调整的行向尺度的CSS属性即可。

使用开源工具 postcss-rtl

在GitHub上可以找到 postcss-rtl 开源插件,它的原理是对CSS文件进行处理,将CSS属性中的 left 改为 right,right 改为 left,从而自动适配RTL布局。

我们需要注意的是

  • 浏览器兼容性:

使用逻辑属性时需要考虑浏览器的兼容性问题。对于B端项目,可以考虑使用逻辑属性,因为这些项目通常在兼容性较好的环境中运行。

  • 代码处理范围:

开发者只能处理本地代码,无法处理npm包中的代码。因此,使用 postcss-rtl 插件可以自动处理所有CSS文件,包括本地代码和第三方库的样式。

vue引入示例

webpack中引入插件postcss-rtl(opens new window)

vue-cli2脚手架配置: 安装依赖 npm install postcss-loader postcss-rtl--save-dev

webpack 配置文件(例如 cloud/build/utils.js)中添加 postcss-loaderpostcss-rtl 插件。

  1. // 定义一个 postcssLoader 对象,用于配置 postcss-loader

  2. var postcssLoader = {

  3. loader: 'postcss-loader', // 指定使用 postcss-loader

  4. options: {

  5. postcssOptions: { // 配置 postcss 的选项

  6. plugins: [

  7. [ 'postcss-rtl', {} ] // 添加阿拉伯语右排布局插件 postcss-rtl

  8. ]

  9. }

  10. }

  11. }

  12. // 生成用于 extract text plugin 的加载器字符串的函数

  13. function generateLoaders(loader, loaderOptions) {

  14. // 初始化一个包含 cssLoader、autoprefixerLoader 和 postcssLoader 的加载器数组

  15. var loaders = [cssLoader, autoprefixerLoader, postcssLoader]

  16. // 如果传入了 loader 参数,则将相应的 loader 配置添加到加载器数组中

  17. if (loader) {

  18. loaders.push({

  19. loader: loader + '-loader', // 动态指定 loader 名称,例如 'sass-loader'

  20. options: Object.assign({}, loaderOptions, { // 合并传入的 loaderOptions 和 sourceMap 选项

  21. sourceMap: options.sourceMap // 将 sourceMap 选项添加到 loader 配置中

  22. })

  23. })

  24. }

  25. // 省略其他代码...

  26. ...

  27. }

vue-cli3脚手架配置: 安装依赖 yarn add postcss-rtl-D 

webpack中( apps-moblie-docs/vue.config.js)文件里添加 postcss-rtl插件

  1. css: {

  2. // 是否启用 sourceMap,根据 isProduction 变量确定

  3. sourceMap: !isProduction,

  4. // 加载器选项

  5. loaderOptions: {

  6. // PostCSS 相关配置

  7. postcss: {

  8. // PostCSS 插件列表

  9. plugins: [

  10. // 添加阿拉伯语右排布局插件 postcss-rtl

  11. require('postcss-rtl')()

  12. ]

  13. }

  14. }

  15. }

app.vue入口里添加根据语言判断修改html的dir属性,比如: document.documentElement.setAttribute('dir',this.$i18n.locale==='ar'?'rtl':'ltr')

方向的图标处理:

  1. // 适配右排布局图标方向

  2. [dir=rtl]{

  3. .components-icons{

  4. &.components-icons-back{

  5. &:before {

  6. display: inline-block;

  7. transform: scaleX(-1);

  8. }

  9. }

  10. }

  11. }

  • 元素拼接的语句的处理:

  1. // 适配右排布局

  2. [dir=rtl] {

  3. .yun-row__desc {

  4. direction: ltr;

  5. display: inline-flex;

  6. justify-content: flex-end;

  7. }

  8. }

使用[dir="rtl"]和[dir="ltr"]对不能自动适配的属性进行适配

示例:

  1. [dir="rtl"].box {

  2. //选择所有具有 dir="rtl" 属性并且类名为 .box 的元素。

  3. float: right;

  4. margin-right: 0;

  5. margin-left: 16px;

  6. }

  7. [dir="ltr"] .box {

  8. float: left;

  9. margin-right: 16px;

  10. margin-left: 0;

  11. }

优点:是工作量减少,代码入侵减少;

缺点:是需要处理方向性的图标的方向和被元素拼接的语句(断句)。

这里推荐几个自动将 CSS 从 LTR 转换为 RTL 的工具

  • CSS 转换包

    • CSS FLIP :这是一个由 Twitter 开源的项目,可以帮助你将 LTR CSS 转换为 RTL 格式。你可以通过 npm 包管理器安装它( npm install css-flip),安装完成后,可以使用命令行界面 (CLI) 将 LTR 的 CSS 文件转换为 RTL 格式。

    • RTL CSS :它类似于 CSS FLIP,同样可以通过 npm 包管理器进行安装,RTL CSS 可以配合 PostCSS 等工具链使用,也可以单独使用其命令行界面。

  • 在线转换工具

    • CSSJanus : 这是一个在线的 LTR 到 RTL CSS 转换工具。他可以免去我们安装依赖包的过程,你只需要将 LTR 的 CSS 代码复制粘贴到该网站,就可以得到转换后的 RTL 代码。

    • Rastchin : 和CSSJanus类类似,不同的是它除了基本的转换功能之外,Rastchin 还提供了一些额外的选项,例如生成压缩的 RTL CSS 代码,以及检查 LTR CSS 代码的语法错误等。

    • <

结论

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

原文作者:zayyo

原文地址:https://juejin.cn/post/7382987557544099840

最后

还没有使用过我们的刷题网站(https://fe.ecool.fun/)或者小程序 前端面试题宝典 的同学,如果近期准备或者正在找工作,千万不要错过,题库主打题全和更新快哦~。

有会员购买、辅导咨询的小伙伴,可以通过下面的二维码,联系我们的小助手。

图片