背景:
由于我们做的是沙特业务,日常开发跟阿语(RTL语言)打交道比较多,在此记录一下如何高效开发镜像语言的样式。
如果你是一个全新的项目,首推肯定是用 CSS 的逻辑属性
CSS 逻辑属性(Logical Properties & Values)
-
概念
CSS 逻辑属性(Logical Properties & Values) 是为了解决 LTR / RTL / 纵向书写 等多书写模式问题而设计的。你可以把它理解为:
不再关心 left / right / top / bottom,而是关心 start / end / block / inline
| 物理方向 | 逻辑方向 |
|---|---|
| left / right | inline-start / inline-end |
| top / bottom | block-start / block-end |
- inline:文字流方向(LTR / RTL 会变)
- block:垂直方向(通常是上 → 下)
<html dir="rtl">
浏览器会自动把 inline-start 映射到 right
-
最常用的逻辑属性清单(🔥必会)
1️⃣ margin / padding
margin-inline-start
margin-inline-end
margin-block-start
margin-block-end
padding-inline-start
padding-inline-end
padding-block-start
padding-block-end
👉 等价替代:
| 传统 | 逻辑 |
|---|---|
| margin-left | margin-inline-start |
| margin-right | margin-inline-end |
| margin-top | margin-block-start |
| margin-bottom | margin-block-end |
2️⃣ border
border-inline-start
border-inline-end
border-block-start
border-block-end
border-inline-start-width
border-inline-start-style
border-inline-start-color
3️⃣ inset(替代 top / right / bottom / left)
inset-inline-start
inset-inline-end
inset-block-start
inset-block-end
/* 代替 left: 0 */
inset-inline-start: 0;
4️⃣ size(width / height)
inline-size /* ≈ width */
block-size /* ≈ height */
min-inline-size
max-inline-size
min-block-size
max-block-size
5️⃣ text / alignment
text-align: start | end;
float: inline-start | inline-end;
clear: inline-start | inline-end;
其他属性可以到 CSS MDN 查询
-
简写属性(非常实用)
margin-inline: 8px 16px;
padding-block: 12px;
border-inline: 1px solid #ddd;
inset: 0; /* 全逻辑版 top/right/bottom/left */
-
书写模式相关(进阶)
writing-mode
writing-mode: horizontal-tb; /* 默认 */
writing-mode: vertical-rl;
writing-mode: vertical-lr;
direction
direction: ltr | rtl;
⚠️ direction 只影响 inline 方向
-
浏览器兼容性(重点)
总体结论
主流浏览器已全面可用,可直接上生产
详细支持情况(2025)
| 属性类别 | Chrome | Firefox | Safari | Edge |
|---|---|---|---|---|
| margin / padding 逻辑 | 69+ | 66+ | 12.1+ | 79+ |
| border 逻辑 | 69+ | 66+ | 14+ | 79+ |
| inset-* | 87+ | 66+ | 14.1+ | 87+ |
| inline-size / block-size | 69+ | 66+ | 12+ | 79+ |
| text-align: start/end | 1+ | 1+ | 1+ | 1+ |
| float: inline-* | 87+ | 66+ | 14+ | 87+ |
📌 移动端:
- Android Chrome ✅
- iOS Safari 12+ ✅
-
是否需要 PostCSS / Polyfill?
结论
- ❌ 不需要 polyfill
- ❌ 不需要 postcss-rtlcss
👉 除非:
- 你要兼容 IE11(已淘汰)
- 或维护大量 legacy CSS
-
真实项目推荐写法(你可以直接用)
.card {
padding-inline: 16px;
padding-block: 12px;
border-inline-start: 4px solid var(--primary);
inset-inline-start: 0;
inline-size: 100%;
}
<html dir="ltr">
<html dir="rtl">
零 JS,零构建成本。
-
什么时候“不要”用逻辑属性?
❌ 如果你要:
- 精确控制某一侧(永远是左)
- Canvas / 绝对定位坐标
- 老组件库未适配
这种情况下可以 物理属性 + rtlcss
如果你是老项目,使用大量
left / right,且短期内无法全面改成逻辑属性,则可以考虑使用 postcss-rtlcss
postcss-rtlcss
-
概念
postcss-rtlcss 是一个 PostCSS 插件,用于在构建阶段自动生成 RTL(Right-to-Left)样式,常见于支持 阿拉伯语 / 希伯来语 等从右到左书写的语言场景。
一句话理解
把 LTR 的 CSS 自动转换成 RTL 版本,不用你手写两套样式。
它解决什么问题?
在国际化(i18n)项目中:
- LTR(英文 / 中文)
.box {
margin-left: 16px;
text-align: left;
}
- RTL(阿拉伯语)
.box {
margin-right: 16px;
text-align: right;
}
👉 postcss-rtlcss 可以 自动完成这种转换。
能自动转换哪些东西?
| LTR | RTL |
|---|---|
| margin-left | margin-right |
| padding-left | padding-right |
| left | right |
| float: left | float: right |
| text-align: left | text-align: right |
| border-left | border-right |
| background-position: left | right |
⚠️ 不会动逻辑属性(如 margin-inline-start),因为它们本身就是方向无关的。
-
基本使用方式
1️⃣ 安装
npm install postcss postcss-rtlcss --save-dev
2️⃣ PostCSS 配置
postcss.config.js
module.exports = {
plugins: [
require('postcss-rtlcss')()
]
}
3️⃣ 生成 RTL CSS(常见做法)
方式一:输出两份 CSS
style.css // LTR
style.rtl.css // RTL
require('postcss-rtlcss')({
// 生成 .rtl.css
addPrefixToSelector: (selector) => `[dir="rtl"] ${selector}`
})
-
在 Vite / Webpack 中使用
Vite 示例
// vite.config.ts
import rtlcss from 'postcss-rtlcss'
export default {css: {postcss: {plugins: [rtlcss()]
}
}
}
Webpack 示例
{
loader: 'postcss-loader',
options: {
postcssOptions: {
plugins: [
require('postcss-rtlcss')()
]
}
}
}
-
控制哪些规则“不要翻转”
使用注释
/* rtl:ignore */
.box {
margin-left: 20px;
}
或
/* rtl:begin:ignore */
.box {
left: 0;
}
/* rtl:end:ignore */
和 CSS 逻辑属性的关系(很重要)
❌ 传统方式(需要 RTL CSS)
margin-left: 16px;
✅ 现代推荐(不需要 rtlcss)
margin-inline-start: 16px;
👉 如果你全面使用逻辑属性:
- 不需要
postcss-rtlcss - 浏览器会自动适配
dir="rtl"