关于 israeli-ui-design-system
Israeli UI Design System 是一项设计技能,提供支持希伯来语界面的 RTL 行为、排版建议和设计令牌。内容适用于 React、Vue、Angular 和原生 HTML/CSS,也涵盖机构及政府网站模式。
主要功能
- 01希伯来语与拉丁字体搭配建议
- 02针对希伯来语调整的字号体系
- 03RTL 优先的组件模式
- 04浅色与深色主题令牌
- 05WCAG 对比度与颜色令牌指南
- 06机构及 IGDS 设计参考
适用场景
- 01设计希伯来语网页界面
- 02将组件适配为 RTL 布局
- 03构建无障碍颜色和排版体系
- 04制作机构或政府相关网站
安装
复制下面的命令,在终端中运行。
npx skills add https:/ / github.com/ skills-il/ localization --skill israeli-ui-design-system安装后在 Claude Code 中输入/israeli-ui-design-system确认已加载。
包含的文件
除 SKILL.md 外,安装时一起下载的参考资料和脚本。
evidence.jsonmetadata.jsonoptimization-log.jsonSKILL_HE.mdreferences/domain-checklist.mdhebrew-typography.md详细介绍
以色列 UI 设计系统
适用于 React、Vue、Angular 和原生 HTML/CSS。核心模式无需网络。建议配合 Storybook 进行组件开发。
说明
第 1 步:选择希伯来语字体搭配
选择针对希伯来语可读性和拉丁字母兼容性优化的字体组合:
| 搭配 | 希伯来语字体 | 拉丁字母字体 | 最适合 | 风格 |
|---|---|---|---|---|
| 现代商务 | Heebo | Inter | SaaS、仪表盘、管理面板 | 简洁、中性 |
| 友好初创 | Rubik | Source Sans 3 | 消费类应用、营销网站 | 圆润、亲和 |
| 政府/正式 | Assistant | Roboto | 政府网站、机构页面 | 专业、清晰 |
| 编辑出版 | Frank Ruhl Libre | Merriweather | 博客、新闻、内容网站 | 衬线、文学 |
| 极简 | Secular One | Montserrat | 落地页、作品集 | 醒目标题 |
完整的字体度量和加载策略请参见 references/hebrew-typography.md。
字体加载配置:
/* Primary: Heebo + Inter pairing */
@import url('https://fonts.googleapis.com/css2?family=Heebo:wght@300;400;500;700&family=Inter:wght@300;400;500;700&display=swap');
:root {
/* Latin face FIRST: Inter has no Hebrew glyphs, so Hebrew characters
fall through to Heebo per glyph. Heebo ships Latin glyphs too, so
listing it first would render English in Heebo and Inter never loads. */
--font-sans: 'Inter', 'Heebo', 'Noto Sans Hebrew', Arial, sans-serif;
--font-mono: 'Fira Code', 'Source Code Pro', monospace;
}
body {
font-family: var(--font-sans);
}
通用字体族(sans-serif)始终会匹配,因此其后面列出的任何内容都不会被使用:把它放在最后、只出现一次,并置于一个包含希伯来语字形的系统字体(此处为 Arial)之后,这样在网络字体加载期间文本仍保持可读。如果你想要 Heebo 自身的拉丁字母而非搭配字体,请只列出 Heebo。此处的等宽字体不含希伯来语,因此代码中的希伯来语会回退到系统字体。
Next.js(next/font)。 列出要预加载的子集,包括 hebrew;next/font 没有默认子集,在开启 preload 的情况下省略 subsets 只会产生一条警告:
import { Heebo, Inter } from 'next/font/google';
const heebo = Heebo({ subsets: ['hebrew', 'latin'], variable: '--font-heebo', display: 'swap' });
const inter = Inter({ subsets: ['latin'], variable: '--font-inter', display: 'swap' });
// <html lang="he" dir="rtl" className={`${inter.variable} ${heebo.variable}`}>
使用 Tailwind v4 时,在 CSS 中通过 @theme inline { --font-sans: var(--font-inter), var(--font-heebo), sans-serif; } 进行映射(当主题变量引用另一个变量时,inline 是必需的)。
第 2 步:希伯来语排版比例
希伯来语字母绘制在拉丁字母的 x 高度与大写高度之间,没有大写字母,也没有高耸的上伸部,因此在相同字号下希伯来语看起来比拉丁字母更小。请按希伯来语而非拉丁字母来设定比例(各字体的实测高度见 references/hebrew-typography.md):
:root {
/* Hebrew-adjusted type scale */
--text-xs: 0.8125rem; /* 13px -- minimum readable Hebrew */
--text-sm: 0.875rem; /* 14px */
--text-base: 1rem; /* 16px -- Hebrew body text minimum */
--text-lg: 1.125rem; /* 18px */
--text-xl: 1.25rem; /* 20px */
--text-2xl: 1.5rem; /* 24px */
--text-3xl: 1.875rem; /* 30px */
--text-4xl: 2.25rem; /* 36px */
/* Hebrew-specific line heights (taller than Latin) */
--leading-tight: 1.4;
--leading-normal: 1.7;
--leading-relaxed: 1.9;
/* NEVER use letter-spacing for Hebrew */
--tracking-hebrew: normal;
/* Slight word spacing improves Hebrew readability */
--word-spacing-hebrew: 0.05em;
}
/* Hebrew body text: dir usually sits on <html>, so match either element */
html[dir="rtl"] body,
body[dir="rtl"] {
font-size: var(--text-base);
line-height: var(--leading-normal);
letter-spacing: var(--tracking-hebrew);
word-spacing: var(--word-spacing-hebrew);
}
第 3 步:RTL 优先的组件架构
将 RTL 作为默认来设计组件,而不是事后才考虑:
/* RTL-first button component */
.btn {
display: inline-flex;
align-items: center;
gap: 0.5rem;
padding-inline: 1.5rem;
padding-block: 0.75rem;
border-radius: 0.375rem;
font-family: var(--font-sans);
font-weight: 500;
text-align: start;
/* Icon automatically flips in RTL */
}
.btn-icon-start {
flex-direction: row;
/* In RTL: icon appears on the right (start side) */
}
.btn-icon-end {
flex-direction: row-reverse;
/* In RTL: icon appears on the left (end side) */
}
/* RTL-first card component */
.card {
border-radius: 0.5rem;
padding: 1.5rem;
text-align: start;
}
.card-header {
display: flex;
justify-content: space-between;
align-items: center;
margin-block-end: 1rem;
padding-block-end: 1rem;
border-block-end: 1px solid var(--border-color);
}
/* RTL-first sidebar layout */
.layout {
display: grid;
grid-template-columns: 280px 1fr;
/* In RTL: sidebar appears on the right automatically */
}
.layout-sidebar {
border-inline-end: 1px solid var(--border-color);
padding-inline-end: 1.5rem;
}
其余组件集的 RTL 行为。 按钮、卡片和侧边栏并不是全部——要镜像每一个有方向性的组件:
| 组件 | RTL 行为 |
|---|---|
| 面包屑 | 从右到左排列;分隔符(/、>、chevron)指向左侧(朝向下一级)。文本分隔符(>、›)是双向镜像字符,浏览器在 RTL 下已经会自动翻转它,因此不要对它添加 scaleX(-1)(那会把它翻回去)。只有 SVG 或图标字体的 chevron 需要 transform: scaleX(-1),而 transform 对行内元素无效,所以给图标字体的字形设置 display: inline-block。 |
| 模态框 / 对话框 | 居中的模态框无需改动。关闭(X)按钮位于行内结束侧(RTL 中为左上角)。底部操作按钮:一种常见的团队惯例是将主操作放在行内起始侧,因此在 RTL 中它会落在右侧;选定一种顺序并保持一致。 |
| 下拉菜单 / 菜单 | 与触发器的行内起始边缘对齐展开;子菜单飞出层朝向行内起始侧展开(RTL 中为向左)。插入符 / chevron 镜像。 |
| 滑块 / 范围输入 | 轨道从行内起始侧开始填充——在 RTL 中最小值在右侧,最大值在左侧。原生 <input type="range"> 配合 dir="rtl" 可处理此问题;自定义滑块必须翻转填充方向。 |
| 进度条 | 填充从行内起始侧增长,因此在 RTL 中进度从右向左推进。使用 transform-origin / 逻辑属性,而不是硬编码的 left: 0 原点。 |
| 轻提示 / snackbar | 从视口的行内结束侧边缘滑入——RTL 中为左上角或左下角(镜像自 LTR 的右上角惯例)。使用 inset-inline-end 锚定,而不是 right。 |
/* Toast anchored to the inline-end edge -- flips sides automatically in RTL */
.toast {
position: fixed;
inset-block-start: 1rem;
inset-inline-end: 1rem;
}
/* Progress bar fill grows from the inline-start */
.progress-fill {
block-size: 100%;
inline-size: var(--progress, 0%);
/* fill starts at the inline-start edge: right in RTL, left in LTR */
}
Tailwind v4。 使用逻辑工具类,让同一份类名列表在两种方向下都可用:ps-*/pe-* 和 ms-*/me-*(行内内边距和外边距)、border-s/border-e、rounded-s-*/rounded-e-*、text-start/text-end,以及自 v4.2.0 起的 inset-s-*/inset-e-* 和块轴方向的 pbs-*/pbe-*/mbs-*/mbe-*。v4.2.0 已弃用 start-*/end-*,改用 inset-s-*/inset-e-*。将 rtl:/ltr: 变体保留给真正的例外情况,例如翻转有方向性的图标(rtl:-scale-x-100),而不是用于间距。
shadcn/ui。 在 components.json 中设置 rtl: true 会让 CLI 将 left-*/right-* 转换为逻辑类,并用 rtl:rotate-180 翻转受支持的图标,但仅适用于在较新样式(base-nova、radix-nova)下通过 shadcn create 创建的项目;其他项目请遵循其迁移指南。添加其 DirectionProvider(shadcn add direction)。其文档还提到,目前应将 dir 传递给 portal 元素(如 popover 和 tooltip 内容),作为针对 tw-animate-css 中逻辑滑动工具类已知问题的变通方案。
哪些图标需要镜像。 镜像那些表示沿阅读线方向的图标;其余保持不变:
| 在 RTL 中镜像 | 不镜像 |
|---|---|
| 后退 / 前进箭头、面包屑和步骤条中的 chevron、“下一个”和“发送” | 媒体播放、暂停和快进快退控件(它们遵循磁带方向) |
| 回复、列表缩进、文本对齐图标 | 时钟、刷新和历史图标(时间在任何地方都顺时针运行) |
| 进度和滑块填充、线性时间线 | 对勾、搜索、相机及其他无方向性的对象 |
| 表示物体向前移动的图标 | 图表和图形、数字、logo、斜杠 |
撤销和重做同时隐含水平和环形两个方向:在 RTL 中选择一种并一致应用。将每个选择一次性编码(例如一个 data-mirror 属性或图标注册表标志),而不是按每次使用单独处理。
第 4 步:以色列配色方案与设计令牌
:root {
/* Israeli-appropriate color tokens */
--color-primary-50: #eff6ff;
--color-primary-100: #dbeafe;
--color-primary-500: #3b82f6;
--color-primary-600: #2563eb;
--color-primary-700: #1d4ed8;
/* Status colors (universal) */
--color-success: #16a34a;
--color-warning: #d97706;
--color-error: #dc2626;
--color-info: #2563eb;
/* Neutral palette */
--color-gray-50: #f9fafb;
--color-gray-100: #f3f4f6;
--color-gray-200: #e5e7eb;
--color-gray-500: #6b7280;
--color-gray-700: #374151;
--color-gray-900: #111827;
/* Spacing scale */
--space-1: 0.25rem;
--space-2: 0.5rem;
--space-3: 0.75rem;
--space-4: 1rem;
--space-6: 1.5rem;
--space-8: 2rem;
--space-12: 3rem;
/* Border radius */
--radius-sm: 0.25rem;
--radius-md: 0.375rem;
--radius-lg: 0.5rem;
--radius-full: 9999px;
}
深色模式(colors-dark 令牌层)。 定义一组并行的深色令牌,而不是把深色值硬编码进组件。保持相同的令牌名称,这样组件引用 var(--color-bg) / var(--color-text),永远不需要根据主题分支。书写方向与主题是正交的 —— RTL 和深色模式是相互独立的轴,因此 [data-theme="dark"][dir="rtl"] 组合必须能够直接正常工作。
:root {
/* light (default) */
--color-bg: #ffffff;
--color-surface: #f9fafb;
--color-text: #111827;
--color-border: #e5e7eb;
}
:root[data-theme="dark"] {
/* colors-dark tier -- same token names, dark values */
--color-bg: #0b0f19;
--color-surface: #151b2b;
--color-text: #e5e7eb;
--color-border: #2a3346;
}
注意:由于希伯来字母的字形特点,深色背景上的希伯来文本看起来可能更细 —— 请验证对比度仍然满足 WCAG AA,并考虑为深色模式的正文文本使用稍微更粗的字重。
把对比度编码进令牌。 设计系统的令牌层应当保证 WCAG 对比度,而不是把它留给组件作者。将每个文本令牌与其所在表面配对并检查比值:--color-bg / --color-surface 上的正文文本必须至少达到 4.5:1,大号文本、图标和 UI 边框至少达到 3:1。特别要审查状态令牌:--color-warning: #d97706 在白色上的对比度为 3.19:1(在 --color-surface 上为 3.05:1),--color-primary-500: #3b82f6 为 3.68:1。这达到了大号文本、图标和 UI 边框所需的 3:1 标准(因此用作焦点轮廓或填充色没问题),但未达到普通字号正文文本所需的 4.5:1 标准。不要在浅色背景上把这些颜色用于小号文本;当你需要将该颜色用作文本时,引入一个更深的色阶(600/700 色阶)。
色阶优先使用 oklch。 用 oklch()(自 2023 年起为 Baseline)定义色阶,并提供 hex 回退值。感知均匀的明度使生成无障碍色阶和深色模式变体比手工调校的 hex 值容易得多。
对令牌分层。 组件永远不应引用原始色阶,例如 --color-primary-500。使用三个层级:基础原语(blue.600)、指向它们的语义角色(color.action.primary),以及指向角色的组件令牌(button.bg)。这样,品牌重塑或新增深色主题只需改动一层。
只编写一次令牌,采用 W3C Design Tokens Community Group(DTCG)格式,其 Format Module 2025.10 是最终社区组报告(2025 年 10 月 28 日)。别名使用 {group.token},而 2025.10 的颜色值是一个对象:
{
"color": {
"blue": { "600": { "$type": "color", "$value": { "colorSpace": "srgb", "components": [0.145, 0.388, 0.922], "hex": "#2563eb" } } },
"action": { "primary": { "$type": "color", "$value": "{color.blue.600}" } }
},
"button": { "bg": { "$type": "color", "$value": "{color.action.primary}" } }
}
Style Dictionary 自 v4 起支持 DTCG,但其文档称 2025.10 尚未完全支持(v5 中仍在进行中),因此在采用对象颜色语法前请检查你的版本。其 css/variables 格式配合 outputReferences: true 会在生成的 CSS 中保留别名链(--button-bg: var(--color-action-primary)),因此各层级能延续到代码中。
行长。 添加一个测量令牌,并用 max-inline-size 应用它,例如 --measure-prose: 65ch。ch 单位是拉丁字母 “0” 的宽度,因此请在浏览器中检查真实的希伯来语行长,而不要轻信这个数字。
第 5 步:Gov.il 设计模式
对于政府和机构类以色列网站,权威参考是 以色列政府设计系统(IGDS)——用于统一 gov.il 各站点用户体验的正式原子化设计系统。它以 Figma Community 文件形式发布,采用 CC BY 4.0 许可。当前版本是 "Israeli Government DS 3.0"(https://www.figma.com/community/file/1637743894870099523/israeli-government-ds-3-0,支持邮箱为 digital.gov.il);较早的 "IGDS Design System File 2.0"(https://www.figma.com/community/file/1426262348206342909/igds-design-system-file-2-0)仍被列出,因此要确认项目是基于哪个版本构建的。如果你正在构建一个真正与 gov.il 相邻的产品,请直接从 IGDS Figma 文件中提取 token、组件和 RTL 希伯来语插画风格,而不是近似模仿——IGDS 定义了自己的色阶、间距和组件结构,近似实现会与线上 gov.il 页面产生明显差异。
下面的 CSS 是通用机构风格模式,并非官方 IGDS。当你没有 IGDS 访问权限时,可将其作为机构风格的起始脚手架;一旦获得访问权限,请将其中数值替换为 IGDS token。
/* Generic institutional header pattern (NOT official IGDS tokens) */
.gov-header {
background-color: #1a3a5c;
color: #ffffff;
padding-block: var(--space-4);
padding-inline: var(--space-6);
}
.gov-header-logo {
display: flex;
align-items: center;
gap: var(--space-3);
/* Logo + Hebrew site name, right-aligned in RTL */
}
/* Gov.il form patterns */
.gov-form-group {
margin-block-end: var(--space-6);
}
.gov-label {
display: block;
font-weight: 500;
margin-block-end: var(--space-2);
color: var(--color-gray-700);
}
.gov-input {
inline-size: 100%;
padding: var(--space-3);
border: 1px solid var(--color-gray-200);
border-radius: var(--radius-md);
font-family: var(--font-sans);
font-size: var(--text-base);
}
.gov-input:focus {
outline: 2px solid var(--color-primary-500);
outline-offset: 2px;
}
/* Gov.il step indicator */
.gov-steps {
display: flex;
gap: var(--space-4);
padding: 0;
list-style: none;
/* In RTL: steps flow right-to-left */
}
.gov-step {
display: flex;
align-items: center;
gap: var(--space-2);
}
.gov-step-number {
display: flex;
align-items: center;
justify-content: center;
inline-size: 2rem;
block-size: 2rem;
border-radius: var(--radius-full);
background-color: var(--color-primary-500);
color: #ffffff;
font-weight: 700;
}
第 6 步:RTL 优先的表单模式
<form dir="rtl" lang="he">
<fieldset>
<legend>כתובת</legend>
<div class="form-group">
<label for="street">רחוב</label>
<input id="street" type="text" dir="rtl">
</div>
<div class="form-row">
<div class="form-group">
<label for="house-num">מספר בית</label>
<input id="house-num" type="text" dir="ltr"
inputmode="numeric" size="6">
</div>
<div class="form-group">
<label for="apartment">דירה</label>
<input id="apartment" type="text" dir="ltr"
inputmode="numeric" size="4">
</div>
</div>
<div class="form-group">
<label for="city">יישוב</label>
<input id="city" type="text" dir="rtl">
</div>
<div class="form-group">
<label for="postal">מיקוד</label>
<input id="postal" type="text" dir="ltr"
inputmode="numeric" pattern="[0-9]{7}"
maxlength="7" size="10">
</div>
</fieldset>
</form>
以色列身份与联系方式字段。 拉丁语优先的设计系统容易弄错的三种输入类型:
<input id="tz" type="text" dir="ltr" inputmode="numeric"
maxlength="9" autocomplete="off">
<input id="phone" type="tel" dir="ltr" inputmode="tel"
autocomplete="tel">
<input id="email" type="email" dir="ltr" autocomplete="email">
teudat zehut 的第九位是校验位,较短的数字会在左侧补零至九位。先补零,再校验:
function isValidTz(raw) {
const digits = String(raw ?? '').trim();
if (!/^\d{1,9}$/.test(digits) || /^0+$/.test(digits)) return false; // no empty, all-zero or non-digit input
const id = digits.padStart(9, '0');
let sum = 0;
for (let i = 0; i < 9; i++) {
const n = Number(id[i]) * ((i % 2) + 1); // weights 1,2,1,2,...
sum += n > 9 ? n - 9 : n; // add the digits of a two-digit product
}
return sum % 10 === 0;
}
isValidTz('50012343'); // => true (padded to 050012343)
带性别的微文案(实践)。 希伯来语动词和形容词带有性别,因此仅用阳性祈使式("לחץ"、"הירשם")会错误地称呼一半用户。常见的内部风格会使用复数祈使式("לחצו"、"הירשמו")或不定式("ללחוץ כאן"),或改写为名词("הרשמה")。选择一种风格,并将其与 token 一起写入内容规范。
混合方向的用户内容。 用户输入的任何内容,以及来自 API 的任何内容,都可能是希伯来语或拉丁语。不要在其上硬编码方向:dir="auto" 会按元素让第一个强方向字符决定方向。
<textarea dir="auto"></textarea>
<li dir="auto">{{ comment.body }}</li>
请为每个条目设置 dir="auto",绝不要在列表容器上只设置一次:单个容器会采用第一个条目的方向,并使其他所有条目错位。
第 7 步:以色列格式约定(货币、数字、日期)
设计令牌和组件必须编码以色列特有的格式,而不是照搬拉丁/美国默认值。
货币:谢克尔符号(₪)
在以色列金融语境中,谢克尔符号 ₪(U+20AA)通常置于金额之后(例如 1,234.50 ₪),不过在零售场景中 ₪ 1,234.50 也很常见。无论你选择哪种约定,都要一致地应用它。由于数字本质上是 LTR,希伯来语 RTL 文本中内联的任何金额都需要显式的双向隔离,否则周围的标点可能会重新排序。
<p>המחיר הוא <bdi>1,234.50 ₪</bdi> בלבד.</p>
// Prefer Intl.NumberFormat over hand-formatting -- it handles symbol placement,
// grouping separators, and invisible RTL marks correctly across browsers.
new Intl.NumberFormat('he-IL', {
style: 'currency',
currency: 'ILS',
}).format(1234.5);
// => "1,234.50 ₪" (renders as "1,234.50 ₪")
返回的字符串并不是看起来那样的干净 "1,234.50 ₪"。它带有两个
RTL 标记(U+200F)和一个不间断空格,而这正是防止符号在双向文本中漂移的关键。
绝不要在快照或单元测试中断言字符串与手打的字面量相等:应将 Intl 输出与 Intl 输出进行比较,或者先
去除 。
希伯来语正文中的数字
数字(电话号码、身份证号、价格、日期)在 RTL 下不会反转。但当长数字位于希伯来语文本中时,浏览器可能会重排周围的标点。请在数字元素上使用 <bdi> 或 dir="ltr" 将其锁定。
<p>מספר הזהות הוא <bdi>012345678</bdi>, בתוקף עד 2030.</p>
日期和时间
以色列日期是日在前,绝不是美国的 MM/DD/YYYY,在面向用户的文案中也绝不是 ISO 的 YYYY-MM-DD。使用 24 小时制时间(14:30);AM/PM 在以色列 UI 中很少见。
平台分隔符是点,不是斜杠。 CLDR 为希伯来语给出的短格式是 d.M.y,因此 Intl 返回的是点,任何浏览器设置都无法将其变成斜杠:
new Intl.DateTimeFormat('he-IL', {
day: '2-digit', month: '2-digit', year: 'numeric',
}).format(new Date(2026, 3, 20));
// => "20.04.2026" (dateStyle: 'short' gives "20.4.2026")
点是安全的默认选择:它是本地用户所期望的,也是其他所有希伯来语应用所显示的。如果品牌指南要求 20/04/2026,请自行拼接,而不要指望 Intl 生成它:
const parts = Object.fromEntries(
new Intl.DateTimeFormat('he-IL', { day: '2-digit', month: '2-digit', year: 'numeric' })
.formatToParts(new Date(2026, 3, 20))
.map((p) => [p.type, p.value]),
);
`${parts.day}/${parts.month}/${parts.year}`; // => "20/04/2026"
日历。 对于 he-IL,locale.getWeekInfo?.() ?? locale.weekInfo(配合 const locale = new Intl.Locale('he-IL');某些运行时,包括 Node 20 和 22,只有较旧的 weekInfo 访问器)返回 firstDay: 7(星期日)和 weekend: [5, 6](星期五和星期六)。日期选择器和日历网格必须将一周从星期日开始,并标记星期五和星期六,而不是星期六和星期日。原生 <input type="date"> 会以浏览器自身的区域格式显示,这可能会在你的 20.04.2026 文本旁边显示 20/04/2026;如果两者必须一致,请使用自定义选择器。
定义设计令牌,使下游组件保持一致:
:root {
--date-format-short: 'dd.MM.yyyy';
--time-format: 'HH:mm';
--currency-locale: 'he-IL';
--currency-code: 'ILS';
}
数字分隔符
千位分隔符是逗号(1,234,567),小数点是句点(1,234.50)。不要切换到欧洲的 1.234,50 风格;以色列金融使用美国约定。
第 8 步:测试两个方向
RTL 回归是视觉性的,所以要可视化地测试它们。在 dir="rtl" 和 dir="ltr"(以及每个主题)下渲染每个组件 story,例如通过一个在预览根节点上设置 dir 的 Storybook 全局配置,并在 CI 中用 Playwright 的 toHaveScreenshot() 对每种组合进行快照。添加一个 lint 或 grep 检查,使其在出现物理类和属性(ml-、mr-、pl-、pr-、left-、right-、margin-left)时失败,这样新代码就无法重新引入它们。
示例
示例 1:建立以色列设计系统
用户说:"为我的以色列 SaaS 产品创建一个设计系统" 结果:配置 Heebo + Inter 字体搭配,建立希伯来语调整后的字号体系,正文最小 16px、行高 1.7,使用 CSS 逻辑属性定义 RTL 优先的组件原语(按钮、卡片、输入框、侧边栏布局),并建立适合以色列的颜色令牌。
示例 2:构建希伯来语表单组件
用户说:"我需要一个具有正确 RTL 布局的希伯来语地址表单" 结果:创建具有希伯来语标签、右对齐字段组、数字字段(门牌号、邮政编码、电话)采用 LTR 输入方向、带希伯来语图例的正确 fieldset 分组,以及以色列特有的字段模式(7 位邮政编码、城市选择器)的 RTL 表单。
示例 3:实现 Gov.il 设计模式
用户说:“我的政府网站需要符合 gov.il 设计标准” 结果:应用带有机构蓝色的 gov.il 页眉模式、采用 RTL 流向的希伯来语导航、多页表单的步骤指示器、带有焦点指示器的无障碍表单样式,以及包含必需政府链接的页脚。
捆绑资源
参考资料
references/domain-checklist.md-- 以色列 RTL 设计系统的必覆盖项和应覆盖项,每项均附有来源,另有明确的超出范围行。references/hebrew-typography.md-- 希伯来语字体目录,包含 Google Fonts 度量、针对不同使用场景(SaaS、编辑、政府)的推荐搭配、字体加载性能策略、希伯来语特有的 CSS 属性(行高、词间距、字母间距规则),以及面向希伯来语/英语双语界面的字号比例建议。
注意事项
- 希伯来语文本通常比其英文对应文本更短,但短多少会随文案而变化。Agent 可能会依据英文文本长度以固定宽度设计 UI 布局,导致希伯来语文本出现过多空白,或在切换到英语时破坏布局。
- Heebo、Rubik 和 Assistant 是 Web 字体,由 Google Fonts 提供或可自托管。Agent 可能会加载其中一种字体,但未在通用字体族之前设置系统回退字体,导致文本无样式或在加载时发生跳变。保留
display: swap(或font-display: swap),并在sans-serif之前设置一个支持希伯来语字形的系统字体,例如 Arial,如步骤 1 所示。 - 希伯来语表单标签应右对齐,并放置在输入框的右侧(或其上方)。Agent 常常将标签放在输入框的左侧,这是英语惯例,在 RTL 中显得不自然。
- 以色列电话号码输入框应接受带国家代码和不带国家代码的格式:054-1234567、+972-54-1234567 和 0541234567。Agent 可能只验证国际格式。
- 谢克尔符号(₪)不是方向性字符,因此希伯来语段落中的内联价格(如
1,234.50 ₪)在不同浏览器之间可能会不可预测地移位。Agent 通常信任浏览器的双向文本算法,而跳过<bdi>或Intl.NumberFormat('he-IL', { style: 'currency' }),导致价格在 Chrome 和 Safari 之间渲染不一致。
参考链接
| 来源 | URL | 检查内容 |
|---|---|---|
| Google Fonts – Hebrew | https://fonts.google.com/?subset=hebrew | Heebo、Assistant、Rubik、Frank Ruhl Libre、加载片段 |
| CSS 逻辑属性(MDN) | https://developer.mozilla.org/en-US/docs/Web/CSS/Guides/Logical_properties_and_values | padding-inline、margin-block、逻辑定位 |
| Tailwind RTL 支持 | https://tailwindcss.com/docs/hover-focus-and-other-states#rtl-support | 用于组件库的 rtl: 和 ltr: 变体 |
| shadcn/ui RTL | https://ui.shadcn.com/docs/rtl | components.json 中的 rtl: true、支持的样式、DirectionProvider |
| WCAG 快速参考 | https://www.w3.org/WAI/standards-guidelines/wcag/ | 适用于 RTL 的对比度和阅读顺序要求 |
故障排除
错误:“希伯来语文本看起来拥挤或太小”
原因:对希伯来语使用了针对拉丁字母优化的字号和行高 解决方案:将正文字体大小至少增加到 16px。为希伯来语设置行高至少为 1.7。切勿对希伯来语文本应用字母间距。添加轻微的词间距(0.05em)以提高可读性。
错误:“组件布局在 RTL 中损坏”
原因:使用物理 CSS 属性(margin-left、padding-right)而非逻辑属性 解决方案:将所有物理方向属性替换为逻辑等价属性:margin-inline-start、padding-inline-end、border-inline-start、inset-inline-start。使用会自动遵循 dir 属性的 flexbox 和 grid。
错误:“在 RTL 中图标指向错误方向”
原因:方向性图标(箭头、V 形符号、返回按钮)未针对 RTL 进行镜像处理
解决方案:在 [dir="rtl"] 上下文中,使用 CSS transform: scaleX(-1) 对方向性 SVG 或图标字体图标(作为 inline-block)进行镜像处理。不要翻转诸如 > 或 › 之类的文本 V 形符号:浏览器在 RTL 中已经会自动镜像它们。非方向性图标(搜索、主页、设置)不应被镜像。创建一个图标镜像工具类以便一致地应用。