mcpField
C
css-i18n

css-i18n

github.com/globalize-now设计与 UI366 次安装2 天前更新
代码仓库

关于 css-i18n

CSS Internationalization 是用于适配从右向左布局的技能,帮助开发者识别方向性样式,在适用处改用逻辑属性,并检查 LTR 与 RTL 布局。

主要功能

  1. 01识别 CSS 样式方案
  2. 02将物理属性映射为逻辑属性
  3. 03逐项判断方向性样式
  4. 04验证 LTR 与 RTL 布局

适用场景

  1. 01为阿拉伯语或希伯来语适配布局
  2. 02检查 CSS Modules 或 Tailwind 样式
  3. 03转换方向相关的内联样式
  4. 04检查共享组件的 RTL 行为

安装

复制下面的命令,在终端中运行。

$npx skills add https://github.com/globalize-now/globalize-skills --skill css-i18n

安装后在 Claude Code 中输入/css-i18n确认已加载。

包含的文件

除 SKILL.md 外,安装时一起下载的参考资料和脚本。

metadata.json
references/
css-modules-and-vanilla.md
tailwind.md

详细介绍

CSS 国际化

将物理 CSS 属性(left、right、margin-left)转换为逻辑属性(inset-inline-start、margin-inline-start),让布局在 RTL 环境中自动翻转。

**为什么这很重要:**物理属性以视口为基准,而非文本方向。即使设置了 dir="rtl",margin-left: 16px 仍会留在左侧,破坏阿拉伯语、希伯来语及其他 RTL 文字的视觉流。逻辑属性会自动遵循文本方向。


第 1 步:检测样式方案

确定项目编写 CSS 的方式。这将决定要扫描哪些模式,以及要参考哪个文件。

按以下顺序检查:

  1. Tailwind CSS — 存在 tailwind.config.*,或 CSS 文件中出现 @tailwind / @import "tailwindcss"。参见 references/tailwind.md。
  2. CSS Modules — 文件名符合 *.module.css 或 *.module.scss。参见 references/css-modules-and-vanilla.md。
  3. CSS-in-JS — 从 styled-components、@emotion/styled、@emotion/css、stitches、vanilla-extract 导入。遵循与原生 CSS 相同的属性映射,但使用驼峰命名(参见第 2 步的内联样式部分)。
  4. 原生 CSS — 普通的 .css 或 .scss 文件。参见 references/css-modules-and-vanilla.md。
  5. 内联样式 — JSX/TSX 中的 style={{ marginLeft: ... }}。遵循第 2 步中的驼峰命名映射。

项目通常会采用多种方案。扫描所有适用的方案。


第 2 步:扫描并转换

逐个处理文件。对每个文件,查找物理方向属性并转换为对应的逻辑属性。

始终转换(高置信度)

在几乎所有情况下,转换以下属性都是安全的:

Margin 和 padding
物理属性逻辑属性
margin-leftmargin-inline-start
margin-rightmargin-inline-end
padding-leftpadding-inline-start
padding-rightpadding-inline-end

带有明确左右值的简写属性:

/* Before — 4-value shorthand: top right bottom left */
margin: 0 24px 0 16px;

/* After — use longhand logical properties */
margin-block: 0;
margin-inline-start: 16px;
margin-inline-end: 24px;

左右值相同时,使用 inline 简写:

/* Before */
padding-left: 16px;
padding-right: 16px;

/* After */
padding-inline: 16px;
定位
物理属性逻辑属性
leftinset-inline-start
rightinset-inline-end
topinset-block-start
bottominset-block-end

设置四边时,使用 inset 简写:

/* Before */
top: 0; right: 0; bottom: 0; left: 0;

/* After */
inset: 0;
文本对齐
物理属性逻辑属性
text-align: lefttext-align: start
text-align: righttext-align: end

text-align: center 已与方向无关,无需更改。

浮动和清除
物理属性逻辑属性
float: leftfloat: inline-start
float: rightfloat: inline-end
clear: leftclear: inline-start
clear: rightclear: inline-end
边框
物理属性逻辑属性
border-leftborder-inline-start
border-rightborder-inline-end
border-left-colorborder-inline-start-color
border-right-colorborder-inline-end-color
border-left-widthborder-inline-start-width
border-right-widthborder-inline-end-width
border-left-styleborder-inline-start-style
border-right-styleborder-inline-end-style
尺寸(较少见,但值得转换)
物理属性逻辑属性
widthinline-size
heightblock-size
min-widthmin-inline-size
max-widthmax-inline-size
min-heightmin-block-size
max-heightmax-block-size

尺寸说明:width/height 的转换是可选的,优先级较低。它们仅对竖排书写模式(CJK 竖排文本)有影响,对标准 RTL 布局没有影响。只有当项目明确支持竖排书写模式时才转换这些属性,否则可以留待以后处理。优先转换 left/right 属性。

溢出与过度滚动
物理属性逻辑属性
overflow-xoverflow-inline
overflow-yoverflow-block
overscroll-behavior-xoverscroll-behavior-inline
overscroll-behavior-yoverscroll-behavior-block
内联样式(JSX)

相同的转换也适用于驼峰命名:

// Before
<div style={{ marginLeft: 16, paddingRight: 8, textAlign: 'left' }}>

// After
<div style={{ marginInlineStart: 16, paddingInlineEnd: 8, textAlign: 'start' }}>
根据情况转换(中等置信度)

逐项检查。判断方向是语义性的(随文本流向变化)还是装饰性的(始终位于同一侧)。

  • 包含 4 个物理角的边框圆角:

    /* Physical corners */
    border-top-left-radius: 8px;
    border-top-right-radius: 0;
    
    /* Logical corners */
    border-start-start-radius: 8px;
    border-start-end-radius: 0;
    

    角映射:top-left = start-start,top-right = start-end,bottom-left = end-start,bottom-right = end-end。

  • transform: translateX():不会自动翻转。如果位移方向随文本方向变化(例如从起始边缘滑入),则需要使用条件判断或 CSS 自定义属性:

    /* Option 1: custom property set by dir attribute */
    :root { --dir: 1; }
    :root[dir="rtl"] { --dir: -1; }
    .slide-in { transform: translateX(calc(var(--dir) * 100%)); }
    
    /* Option 2: dir-aware selectors */
    .slide-in { transform: translateX(100%); }
    [dir="rtl"] .slide-in { transform: translateX(-100%); }
    
  • background-position: left/right:仅当位置具有语义意义时才转换(例如,图标位于输入框的起始侧)。如果只是装饰用途,则保持不变。

  • 值不同的 4 值简写属性:margin: 8px 24px 8px 16px — 左侧(16px)和右侧(24px)数值不同,因此需要使用逻辑属性的长写形式。

  • scroll-margin-left/right → scroll-margin-inline-start/end

  • scroll-padding-left/right → scroll-padding-inline-start/end

绝不转换
  • 有意固定的方向:始终指向左侧、不随地区设置变化的“后退”箭头,必须位于特定侧的滚动条,画布或游戏元素的绝对像素定位。
  • 动画关键帧:带有方向性变换的 @keyframes 通常用于装饰。只有当动画方向随文本方向变化时才进行转换。
  • writing-mode:此属性控制轴向本身,不属于转换范围。
  • SVG 属性:SVG 中的 x、y、width、height 是坐标系属性,而非布局属性。
  • 打印样式表:@media print 规则通常无需进行 RTL 转换。

第 3 步:Flexbox 和 Grid

Flexbox 和 Grid 布局会自动遵循 dir="rtl" — 主轴无需任何 CSS 更改即可翻转。这意味着:

  • justify-content: flex-start 在 RTL 中已经会向右对齐
  • 在 RTL 中,order 值已经会反转视觉顺序
  • grid-template-columns 中的列顺序已经会翻转

仍需注意的事项:

  • 值不对称的 gap:column-gap 和 row-gap 与方向无关,可以安全使用。无需转换。
  • Flex 项中的方向性图标:表示“向前”的图标在 RTL 中应翻转。使用带有方向感知选择器的 transform: scaleX(-1),或提供单独的 RTL 图标资源。
  • flex-direction: row-reverse:在 RTL 中,row-reverse 会反转已经反转的方向(恢复为 LTR 视觉顺序)。如果使用 row-reverse 是为了在 LTR 中创建从右到左的流向,那么它在 RTL 中可能不正确。请检查其用途。

第 4 步:工作流

按以下优先顺序处理文件(与转换技能的模式一致):

  1. 布局组件(应用外壳、侧边栏、导航栏、页脚)— 影响每个页面
  2. 共享组件(按钮、卡片、模态框、表单字段)— 在各处重复使用
  3. 页面级样式 — 仅适用于某个视图
  4. 工具类/全局 CSS — 重置文件、基础样式、CSS 自定义属性

在每个文件中:

  1. 找出所有物理方向属性
  2. 将每项归类为高/中/绝不转换
  3. 应用转换
  4. 进行视觉验证(第 5 步)

步骤 5:验证

转换后,验证布局在从左到右和从右到左的方向下都能正常工作:

  1. 切换方向:在浏览器 DevTools 中设置 <html dir="rtl">,或使用应用的语言区域切换器
  2. 目视检查:检查以下内容:
    • 文本是否与右边缘对齐
    • 边距和内边距是否正确镜像
    • 定位元素(工具提示、下拉菜单、侧边栏)是否出现在正确的一侧
    • 需要翻转的图标(导航箭头、“前进”/“后退”)是否翻转
    • 不应翻转的图标(复选标记、通用符号、徽标)是否保持不变
  3. 运行现有测试:确认没有回归问题。CSS 更改可能会影响快照测试。
  4. 检查边缘情况:
    • 重叠元素(绝对定位/固定定位)
    • 滚动容器
    • 水平溢出

常见问题

  • CSS 中的 direction: rtl 与 HTML 中的 dir="rtl":始终使用 HTML 的 dir 属性,而不要使用 CSS 的 direction 属性。HTML 属性具有语义,会影响表单行为、键盘导航和双向算法。CSS 属性只影响视觉呈现。
  • 混合内容:同时包含从左到右和从右到左内容的页面(例如,使用阿拉伯语用户输入的英文 UI)需要设置 dir="auto",或在内容块上显式设置 dir 属性。逻辑属性在嵌套方向上下文中也能正常工作。
  • 水平滚动:overflow-x: auto 并不会在所有浏览器中翻转滚动条的位置。请明确测试。
  • 第三方组件:UI 库中的组件内部可能使用物理属性。请检查该库是否提供 RTL 支持或 RTL 主题。
  • 包含两个值的 px 简写:margin: 8px 16px 会设置上下边距和左右边距——但由于左右边距值相同,因此无需转换。只有不对称的四值简写才需要转换。

评论

支持 Markdown