Imported from amirbiron/Noa_Leads (
docs/Skills/hebrew-rtl-best-practices/SKILL.md). Install upstream withnpx skills add amirbiron/Noa_Leads --skill hebrew-rtl-best-practices. Copyright stays with the author (MIT).
שיטות עבודה מומלצות ל-RTL בעברית
הנחיות
שלב 1: הגדרת כיוון המסמך
תמיד מתחילים עם תכונת ה-HTML (לא רק עם CSS):
<html lang="he" dir="rtl">
זה אומר לדפדפנים, לקוראי מסך ול-CSS להשתמש ב-RTL ככיוון הבסיס.
שלב 2: תכונות CSS לוגיות
אף פעם לא להשתמש בתכונות כיווניות פיזיות לפריסה:
| פיזי (תימנעו) | לוגי (תשתמשו) |
|---|---|
margin-left |
margin-inline-start |
margin-right |
margin-inline-end |
padding-left |
padding-inline-start |
padding-right |
padding-inline-end |
border-left |
border-inline-start |
text-align: left |
text-align: start |
text-align: right |
text-align: end |
float: left |
float: inline-start |
left: 10px |
inset-inline-start: 10px |
ככה הפריסה משתקפת אוטומטית במצב RTL.
כשבאמת צריך כלל שתלוי בכיוון שתכונות לוגיות לא יכולות לבטא, עדיף להשתמש בפסבדו-קלאס :dir() במקום בסלקטורים על תכונת [dir="rtl"]:
/* מודרני: מתאים לכיוון המחושב, כולל dir="auto" וירושה */
.chevron:dir(rtl) { transform: scaleX(-1); }
/* גישה ישנה: מתאים רק לתכונת dir מפורשת על האלמנט או מעליו */
[dir="rtl"] .chevron { transform: scaleX(-1); }
הפסבדו-קלאס :dir() הוא חלק מ-Selectors Level 4 והוא פותר את הכיוון המחושב, אז הוא עובד גם לאלמנטים שהכיוון שלהם מגיע מ-dir="auto" או מאב קדמון, איפה שסלקטור תכונה היה מפספס אותם. תמיכת דפדפנים: כרום ו-Edge הוסיפו אותו בגרסה 120 (סוף 2023), פיירפוקס תומך בו כבר שנים, וספארי הוסיף אותו ב-16.4. לתמיכה בדפדפנים ישנים, כדאי לשמור כלל גיבוי עם [dir="rtl"] או להשתמש בתכונה לוגית במקום. אפשר לבדוק תמיכה עדכנית בכתובת https://caniuse.com/css-dir-pseudo.
שלב 3: טיפול בטקסט דו-כיווני
כשמשלבים עברית עם אנגלית/מספרים:
/* Isolate embedded LTR content */
.ltr-content {
unicode-bidi: isolate;
direction: ltr;
}
/* For inline elements with mixed content */
.bidi-override {
unicode-bidi: bidi-override;
}
בעיות bidi נפוצות:
- מספרי טלפון מופיעים הפוך: עוטפים ב-
<bdo dir="ltr"> - סימני פיסוק בקצה הלא נכון של המשפט: משתמשים ב-
unicode-bidi: isolate - כתובות URL ואימייל בתוך טקסט עברי: עוטפים ב-
<span dir="ltr">
מספרים ותאריכים: מספרים בודדים ותאריכים בפורמט DD/MM/YYYY בתוך טקסט עברי בדרך כלל מוצגים תקין כי ספרות הן חלשות-LTR, אבל מספר שאחריו מיד סימן, מטבע או מספר שני עלול להתהפך. כשערך חייב לשמור על סדר ויזואלי קבוע, בודדו אותו עם <span dir="ltr"> או unicode-bidi: isolate במקום לסמוך על פתרון ה-bidi הדיפולטי.
האלמנט <bdi> מול <bdo>: השתמשו ב-<bdo dir="ltr"> רק כשרוצים לכפות כיוון (הוא דורס את אלגוריתם ה-bidi). לתוכן שנוצר על ידי משתמשים או תוכן בכיוון לא ידוע, עדיף <bdi>, שמבודד את התוכן כך שהכיוון שלו מזוהה אוטומטית ולא יכול לדלוף לטקסט שמסביב:
<!-- שם המשתמש יכול להיות בעברית או בלטינית; bdi מבודד אותו כך או כך -->
<p>שלום, <bdi>{{ userName }}</bdi>, ברוך הבא</p>
לשדות טקסט חופשי, dir="auto" (או unicode-bidi: plaintext ב-CSS) נותן לדפדפן לבחור את כיוון הבסיס לכל ערך, וזו ברירת המחדל הנכונה לתגובות, שמות ומחרוזות חיפוש שבהן לא יודעים מראש את השפה.
צללים וגרדיאנטים לא מתהפכים אוטומטית. תכונות CSS לוגיות משקפות פריסה, אבל היסטים וזוויות של box-shadow, text-shadow ו-linear-gradient הם פיזיים ונשארים קבועים כשהכיוון מתהפך. היסט צל של 4px 4px שנראה תקין ב-LTR יצביע לכיוון "הלא נכון" ביחס לפריסת RTL. הפכו אותם במפורש עם דריסת :dir(rtl) (או [dir="rtl"]) כשהכיוון שלהם משמעותי.
שלב 4: שיקוף אייקונים כיווניים
שיקוף אייקונים הוא אחד הבאגים הנפוצים ביותר ב-RTL. הכלל: לשקף אייקונים שהמשמעות שלהם קשורה לכיוון הקריאה, ולהשאיר את כל השאר במקום.
לשקף את אלה (הכיוון שלהם מקודד "קדימה/אחורה/הבא/הקודם" ביחס לסדר הקריאה):
- חצי ניווט, כפתורי קדימה ואחורה, שברונים בפירורי לחם
- חצי "שליחה" והגשה, חצי קרוסלה ועימוד
- חצי הזחה, קינון רשימות ותגובה
- מחווני התקדמות שמרמזים על תנועה קדימה
אל תשקפו את אלה (שיקוף הופך אותם לשגויים או לא מזוהים):
- לוגואים וסמלי מותג
- סימני וי וסימני X או סגירה
- כפתורי הפעלה של מדיה (כפתור הפעלה תמיד מצביע ימינה, הוא מתייחס לציר הזמן ולא לכיוון הקריאה)
- שעונים ואייקוני שעון אנלוגי (כיוון השעון אוניברסלי)
- אייקונים שמתארים עצמים מהעולם האמיתי עם כיוון קבוע (שפופרת טלפון, זכוכית מגדלת עם ידית, רוב אייקוני המוצר)
טכניקה, שיקוף עם טרנספורם היפוך אופקי:
/* היפוך רק כשכיוון המסמך הוא RTL */
.icon-directional:dir(rtl) { transform: scaleX(-1); }
<!-- Tailwind: variant של rtl: למקרים שתכונות לוגיות לא מכסות -->
<button class="rtl:-scale-x-100">
<ArrowLeftIcon />
</button>
הרבה ערכות אייקונים (למשל Material Symbols) כבר מספקות וריאנטים מודעי-RTL, עדיף אותם על פני היפוך כשהם זמינים, כי אייקון הפוך עלול לעוות פרטים עדינים או טקסט מוטמע.
שלב 5: טיפוגרפיה עברית
מחסנית גופנים מומלצת:
font-family: 'Heebo', 'Assistant', 'Rubik', 'Noto Sans Hebrew', sans-serif;
הגדרות טיפוגרפיה:
body[dir="rtl"] {
font-size: 16px; /* Hebrew needs slightly larger than Latin */
line-height: 1.7;
letter-spacing: normal; /* NEVER add letter-spacing for Hebrew */
word-spacing: 0.05em; /* Slight word spacing improves readability */
}
שלב 6: הגדרה לפי פריימוורק
Tailwind CSS RTL (v3.3+ / v4):
עדיף להשתמש בכלי תכונות לוגיות במקום ב-variants של rtl:/ltr::
| קלאס פיזי | קלאס לוגי | תכונת CSS |
|---|---|---|
ml-4 |
ms-4 |
margin-inline-start |
mr-4 |
me-4 |
margin-inline-end |
pl-4 |
ps-4 |
padding-inline-start |
pr-4 |
pe-4 |
padding-inline-end |
left-4 |
start-4 |
inset-inline-start |
right-4 |
end-4 |
inset-inline-end |
rounded-l-lg |
rounded-s-lg |
border-start-start-radius + border-end-start-radius |
rounded-r-lg |
rounded-e-lg |
border-start-end-radius + border-end-end-radius |
<!-- רע: דורש שני קלאסים, נשבר בלי תכונת dir -->
<div class="ltr:ml-4 rtl:mr-4">...</div>
<!-- טוב: קלאס אחד, משתקף אוטומטית לפי dir -->
<div class="ms-4">...</div>
תשאירו את ה-variants של rtl: / ltr: רק למקרים שתכונות לוגיות לא מכסות (אייקונים כיווניים, transforms וכדומה).
הערה ל-Tailwind v4: גרסה 4 משתמשת בקונפיגורציה מבוססת CSS (@import "tailwindcss" ב-CSS) במקום tailwind.config.js. התכונות הלוגיות עובדות זהה בגרסאות 3 ו-4.
Next.js App Router:
// app/layout.tsx
import { Heebo } from 'next/font/google';
const heebo = Heebo({
subsets: ['hebrew', 'latin'],
weight: ['400', '500', '700'],
});
export default async function RootLayout({
children,
params,
}: {
children: React.ReactNode;
params: Promise<{ locale: string }>;
}) {
const { locale } = await params;
const isRTL = locale === 'he';
return (
<html lang={locale} dir={isRTL ? 'rtl' : 'ltr'}>
<body className={heebo.className}>{children}</body>
</html>
);
}
החבילה next/font שומרת את הגופן מקומית (בלי בקשות חיצוניות ל-Google Fonts, בלי הזזת פריסה).
React עם MUI:
גרסאות MUI v6 ו-v7 משתמשות בפיצול הרשמי @mui/stylis-plugin-rtl, ולא בחבילת הקהילה הישנה stylis-plugin-rtl. הפיצול הרשמי מתקן בעיות עם CSS layers ותומך בגרסאות Stylis עדכניות.
import { createTheme, ThemeProvider } from '@mui/material/styles';
import { CacheProvider } from '@emotion/react';
import createCache from '@emotion/cache';
import { rtlPlugin } from '@mui/stylis-plugin-rtl';
import { prefixer } from 'stylis';
const cacheRtl = createCache({
key: 'muirtl',
stylisPlugins: [prefixer, rtlPlugin],
});
const theme = createTheme({ direction: 'rtl' });
כדאי לאמת את שם הייבוא המדויק ואת ההגדרה מול מדריך ה-RTL העדכני של MUI (https://mui.com/material-ui/customization/right-to-left/) לגרסת ה-MUI שלכם.
שלב 7: מלכודות נפוצות שכדאי לבדוק
- אייקונים כיווניים - צריך לשקף (ראו שלב 4 לאילו אייקונים להפוך ואילו להשאיר)
- פסי התקדמות - צריכים להתמלא מימין לשמאל
- סליידרים וקרוסלות - כיוון ההחלקה צריך להתהפך
- תוויות טפסים - צריכות להיות מיושרות לימין
- פירורי לחם (breadcrumbs) - כיוון המפריד צריך להתהפך
- טבלאות - יישור כותרות ותאים
- גרפים - יכול להיות שציר ה-X צריך להתהפך לקוראים בעברית
- צללים וגרדיאנטים - היסטים וזוויות פיזיים לא מתהפכים אוטומטית (ראו שלב 3)
דוגמאות
דוגמה 1: המרת רכיב LTR ל-RTL
המשתמש אומר: "התאם את רכיב הכרטיס הזה לעבודה בעברית"
לפני (LTR בלבד):
.card {
margin-left: 16px;
padding-right: 12px;
text-align: left;
border-left: 3px solid blue;
}
אחרי (תואם RTL):
.card {
margin-inline-start: 16px;
padding-inline-end: 12px;
text-align: start;
border-inline-start: 3px solid blue;
}
ב-Tailwind, מחליפים ml-4 pr-3 text-left border-l-4 ב-ms-4 pe-3 text-start border-s-4.
דוגמה 2: בעיית טקסט דו-כיווני
המשתמש אומר: "מספרים מוצגים הפוך בטקסט העברי שלי"
<!-- שגוי: מספר הטלפון מוצג כ-0544-123-050 -->
<p>התקשרו אלינו: 050-321-4450</p>
<!-- נכון: מבודדים את תוכן ה-LTR -->
<p>התקשרו אלינו: <span dir="ltr">050-321-4450</span></p>
אפשר להשתמש ב-unicode-bidi: isolate על ה-span המכיל לפתרון מבוסס CSS בלבד.
דוגמה 3: ניווט RTL ב-Tailwind
המשתמש אומר: "הסיידבר שלי בצד הלא נכון בעברית"
<!-- רע: סיידבר תקוע בשמאל -->
<aside class="fixed left-0 w-64">...</aside>
<!-- טוב: סיידבר משתקף אוטומטית -->
<aside class="fixed start-0 w-64">...</aside>
<!-- אייקון חץ חזרה עדיין דורש variant של rtl: -->
<button class="rtl:rotate-180">
<ArrowLeftIcon />
</button>
משאבים מצורפים
קובצי עזר
references/css-logical-properties.md- טבלת מיפוי מלאה מתכונות CSS פיזיות ללוגיות (margin, padding, border, מיקום, יישור טקסט, גדלים) בתוספת המלצות למחסניות גופנים עבריים ל-sans-serif, serif ו-monospace. תסתכלו בו כשממירים גיליון סגנונות LTR לתכונות לוגיות תואמות RTL או בוחרים גופני ווב עבריים.
מלכודות נפוצות
- הכלל
text-align: leftשגוי לעברית. תשתמשו ב-text-align: startשמכבד את כיוון המסמך. סוכנים נוטים לקודד יישורleftב-CSS. - התכונות
margin-leftו-padding-rightלא מתהפכות במצב RTL. תשתמשו בתכונות CSS לוגיות:margin-inline-startו-padding-inline-endבמקום. סוכנים שאומנו על CSS של LTR ייצרו תכונות פיזיות. - כיוון
rowב-Flexbox מתהפך אוטומטית ב-RTL, אבלrow-reverseגם מתהפך, מה שגורם להיפוך כפול וחזרה לסדר LTR. סוכנים עלולים להוסיףrow-reverseכי הם חושבים שזה יוצר RTL, אבל בפועל זה יוצר LTR בתוך הקשר RTL. - מספרי טלפון, מספרי כרטיסי אשראי וקטעי קוד חייבים להישאר LTR גם בתוך מיכלים RTL. תעטפו אותם ב-
<bdo dir="ltr">או תשתמשו ב-direction: ltrעל האלמנט המכיל. סוכנים לפעמים נותנים להם לרשת RTL.
קישורי עזר
| מקור | כתובת | מה לבדוק |
|---|---|---|
| MDN תכונות CSS לוגיות | https://developer.mozilla.org/en-US/docs/Web/CSS/CSS_logical_properties_and_values | רשימת תכונות מלאה, טבלאות תמיכת דפדפנים |
MDN פסבדו-קלאס :dir() |
https://developer.mozilla.org/en-US/docs/Web/CSS/:dir | תחביר, התנהגות מול סלקטורים על תכונת [dir] |
Can I use: :dir() |
https://caniuse.com/css-dir-pseudo | טבלת תמיכת דפדפנים עדכנית |
MDN אלמנט <bdi> |
https://developer.mozilla.org/en-US/docs/Web/HTML/Reference/Elements/bdi | בידוד תוכן דו-כיווני שנוצר על ידי משתמשים |
| תמיכת RTL ב-Tailwind CSS | https://tailwindcss.com/docs/hover-focus-and-other-states#rtl-support | תחביר variants של rtl: / ltr: |
| תכונות לוגיות ב-Tailwind | https://tailwindcss.com/docs/margin#logical-properties | כלי ms-*, me-*, ps-*, pe-* |
| MUI ימין לשמאל | https://mui.com/material-ui/customization/right-to-left/ | הגדרת @mui/stylis-plugin-rtl ל-MUI עדכני |
| Google Fonts עברית | https://fonts.google.com/?subset=hebrew | משפחות גופנים עבריים זמינות |
| W3C בינלאומיות | https://www.w3.org/International/articles/inline-bidi-markup/ | אלגוריתם bidi של Unicode, שיטות עבודה מומלצות |
פתרון בעיות
שגיאה: "יישור הטקסט נראה שגוי"
סיבה: שימוש ב-text-align: left במקום ב-text-align: start
פתרון: תחליפו כל left ו-right ב-text-align ל-start ו-end.
שגיאה: "הפריסה לא משתקפת"
סיבה: שימוש ב-margin ו-padding פיזיים במקום בתכונות לוגיות
פתרון: תחליפו כל margin-left ו-margin-right ב-margin-inline-start ו-margin-inline-end.