import styled, { StyleSheetManager } from "styled-components";
import rtlPlugin from "stylis-plugin-rtl";
const Box = styled.div`
padding-left: 10px;
`;
function MakeItRTL() {
return (
<StyleSheetManager stylisPlugins={[rtlPlugin]}>
<Box>My padding will be on the right!</Box>
</StyleSheetManager>
);
}
网页RTL布局适配方案和rtlcss插件在项目中实践
前言
bigo作为全球化的互联网企业,产品体验要求国际化,本地化,所面向的用户来自世界各地,他们在产品使用习惯各有不同。尤其对于使用诸如阿拉伯语、乌尔都语、希伯来语等用户,拥有着庞大的数量群体,他们的阅读习惯与中、英文大为不同,是从右到左的顺序进行阅读,从产品使用上需要兼顾这部分用户需求。为了更好地符合用户习惯,作为一名前端开发,我们更应该在页面针对不同语言进行布局适配,努力地提高用户使用体验。
何为RTL布局
RTL布局通常称为LTR的镜像布局,整体上是与我们日常看到的页面布局对称,从右往左显示内容。例如显示的文字右侧排列,从右向左阅读,导航顺序相反布局,带有方向性的图标镜像显示等。
LTR和RTL布局的主要区别
虽然RTL大体上是镜像布局,但并不是所有地方都需要这样处理,其中有些细节需要注意:
页面交互操作方向同样需要改变方向,例如跑马灯、tab组件,向左滑动代表后退,向右滑动代表前进
某些图标依然按照原来的方向显示,对于不传递方向性的图标、环形流逝方向、代表右手持有的物体和带有斜杠的图标按原有图案展示即可,无需处理。
媒体播放按钮和进度指示器反映的是播放方向,依然按LTR方向展示
总而言之,页面用户体验和界面设计在RTL布局下需要以RTL阅读思维为核心进行设计,了解了RTL布局的特点后接下来总结下现在比较流行常用的页面适配方案
RTL适配方案
direction
最常用的适配方法是在标签中添加
dir
属性或使用css的属性direction
,指定值为rtl
设置后,你能够看到页面的文字从右往左的顺序显示。但某些地方会看上去觉得奇怪,这个css属性对于带有左右方向调整的样式例如
left
,magin-left
等属性无效,需要额外的处理,在RTL里将left
修改成right
,margin-left
修改成margin-rigtht
。例如:你需要额外添加样式,并进行样式覆盖:
以下这些css属性在RTL布局需要重新正确地设置:
另外,direction改变flex和inline-block元素的方向,flex布局适配RTL,在遇到RTL布局的场景下,请尽可能地使用flexbox布局。
transform
另一个简单粗暴的方法是使页面水平翻转,实现水平镜像对称,用到了
transform: scaleX(-1)
属性。从上图可以看出,使用
scaleX(-1)
,页面整体上实现了镜像对称,我们无需在css层面上做过多的细节处理,但相应地文字和图像也翻转了,文字显示上会变得非常奇怪,对于文字要再进行翻转处理一次,涉及文字和非对称的图片也要重新设计。css逻辑属性
CSS逻辑属性定义:是CSS的一个模块,其引入的属性与值能做从逻辑角度控制布局,而不是从物理、方向或维度来控制。
简单地说,CSS逻辑属性没有左右物理方向性的概念,基于参照物来描述起点和终点,如LTR布局下
start
代表left
方向,end
代表right
方向,RTL布局下start
代表right
方向,end
代表left
方向,从而提供原生能力去适配LTR和RTL布局,前端样式开发无需考虑布局适配问题如使用
margin-inline-start
来代替margin-left
,在RTL布局里相当于设置了margin-right
的效果,我们无需额外兼容,类似的属性还有:在某些css属性没有对应的逻辑属性的时候,我们还是要单独对RTL布局定义
在LTR布局中显示
在RTL布局时,添加如下样式进行覆盖
然而这些css逻辑属性具有兼容性的问题,大部分的浏览器版本部分属性不支持、IE浏览器完全不支持
查看网站
css in js
该方案是基于css in js的思想,即是使用js来编写css样式,将css和js代码合并在js文件里,常用于jsx组件语法里面。在React组件里,通过定义样式对象来赋予元素样式,实现组件样式,目前比较流行的css in js库有
styled-components
。使用js操作样式的好处是能够在运行时判断是否在rtl语言环境,并相应地修改css样式代码。可以用到
styled-components
的一个插件stylis-plugin-rtl
来处理RTL布局,其背后原理是使用cssjanus
库通过js进行rtl样式转换。less/sass预处理语言
利用css预处理语言的mixin混合指令功能,预先写好混合指令,额外生成RTL布局代码。
引入公共mixin指令scss文件,在需要的时候使用
@inlcude
方法生成后的代码分别适配LTR和RTL布局:
使用rtlcss、css-flip转换工具
可以通过css转换工具如rtlcss/css-flip,无需提前写好混合指令,即可输出RTL样式布局代码。它能够根据所写的css代码自动转编译成带有rtl布局的css代码,无需额外大量添加rtl布局的css代码,编译过程中自动帮我们处理,省时省力,提高我们项目开发效率。
原来的样式
编译后会转换成
rtlcss提供丰富的特性来满足适配需求:
1、 Control Directives(控制指令)
控制指令放置在css声明或css语句之间,它能作用于单个或多个节点
忽略属性
添加额外的样式
去除属性
重命名选择器
//转换后 .float-left { float: left; }
更详尽的使用方法可查看官网:https://rtlcss.com/
这里编译后的文件会将LTR相关的属性转换成RTL样式,只保留RTL布局的代码,假如想在一份css文件都存在LTR和RTL布局的样式呢,我们需要用到postcss的插件
postcss-rtlcss
,结合webpack构建工具,实现自动化添加RTL布局样式方案比较
background-position
rtlcss插件在项目开发中实践
rtlcss方案虽然会增加样式代码,但是不用另外额外增加工作量,构建工具帮我们完成了脏活,也不失为较优方案,下面是使用
postcss-rtlcss
插件在项目开发中的实践,基于此工具的应用,比平时正常开发项目至少节省了0.5天工作量来处理多语言适配。首先安装需要的插件
然后在
.postcssrc.js
文件中添加配置基于用户所使用的语言,在html标签设置属性
dir
为ltr
或rtl
这样在webpack打包时就会使用
postcss-rtlcss
插件进行处理,项目样式无需过多改动在bigo内部前端旧项目里直接使用
postcss-rtlcss
插件,可能会遇到以下问题,有可能是postcss-loader
版本不兼容造成的:1、报
Error: true is not a PostCSS plugin
错误解决方法:尝试升级
postcss-loader
到4.2.0版本2、报
this.getOptions is not a function
错误解决方法:尝试降级
postcss-loader
到4.2.0版本或降级sass-loader
版本https://stackoverflow.com/questions/66082397/typeerror-this-getoptions-is-not-a-function
使用该插件其中遇到另一个问题是,假如在项目中使用sass或less语言,直接使用rtlcss的指令注释写法是不生效的 https://rtlcss.com/learn/usage-guide/value-directives/#Tip
https://sass-lang.com/documentation/syntax/comments#in-scss
对于
Control Directives
语法,需要/*!
开头对于
Value Directives
语法,需要使用插值语法SASS/SCSS会忽略放置在声明里的注释,为了确保Value Directives有效需要使用SASS的插值语法
该postcss插件是基于
rtlcss
插件的基础上封装的,具体的使用方法可以阅读官方文档 https://github.com/elchininet/postcss-rtlcss总结
RTL的适配方案众多,开发者需要结合项目的需求特点来选取和组合方案,以达到最优选型,因地制宜,目的是最大程度上在提高开发效率,节省开发周期的基础上提高可维护性
相关资料:
https://developer.mozilla.org/en-US/docs/Mozilla/Developer_guide/RTL_Guidelines
https://developer.mozilla.org/zh-CN/docs/Web/CSS/CSS_Logical_Properties
https://www.mdui.org/design/usability/bidirectionality.html#bidirectionality-ui-mirroring-overview
https://hacks.mozilla.org/2015/09/building-rtl-aware-web-apps-and-websites-part-1/
https://hacks.mozilla.org/2015/10/building-rtl-aware-web-apps-websites-part-2/