Hebrew Tailwind Preset
Tailwind CSS v4 recommended (current release v4.3, May 2026); v3.1+ is compatible for dir variants. Works with React, Vue, Angular, Next.js, and Nuxt. No network required.
Instructions
Step 1: Install and Configure Tailwind v4 for RTL
See references/rtl-config.md for complete configuration reference.
Install the Tailwind v4 build plugin first. Tailwind v4 dropped the automatic tailwind.config.js loading, so @import "tailwindcss" alone will not build until a build plugin is wired. Pick the one matching your toolchain:
# Vite (recommended): install the first-party Vite plugin
npm install tailwindcss @tailwindcss/vite
// vite.config.js -- add the plugin
import { defineConfig } from 'vite';
import tailwindcss from '@tailwindcss/vite';
export default defineConfig({
plugins: [tailwindcss()],
});
# PostCSS-based toolchains (Next.js, Webpack, etc.)
npm install tailwindcss @tailwindcss/postcss postcss
// postcss.config.mjs
export default {
plugins: { '@tailwindcss/postcss': {} },
};
In v4 the @tailwindcss/postcss plugin handles @import inlining and vendor prefixing, so postcss-import and autoprefixer are no longer needed.
Then load Hebrew fonts with font-display: swap (via a Google Fonts <link> or an @font-face rule) to avoid a Flash of Invisible Text while the Hebrew font file loads. See Step 2 for the snippet.
Tailwind v4 (CSS-first configuration):
/* app.css -- imported by your build entry */
@import "tailwindcss";
@theme {
/* Hebrew font stacks */
--font-hebrew: 'Heebo', 'Assistant', 'Noto Sans Hebrew', sans-serif;
--font-hebrew-serif: 'Frank Ruhl Libre', 'David Libre', serif;
--font-mono: 'Fira Code', 'Source Code Pro', monospace;
/* Hebrew-optimized type scale */
--text-xs: 0.8125rem;
--text-sm: 0.875rem;
--text-base: 1rem;
--text-lg: 1.125rem;
--text-xl: 1.25rem;
--text-2xl: 1.5rem;
--text-3xl: 1.875rem;
--text-4xl: 2.25rem;
/* Hebrew line heights (taller than Latin defaults) */
--leading-tight: 1.4;
--leading-normal: 1.7;
--leading-relaxed: 1.9;
}
Tailwind v3 (JavaScript configuration):
// tailwind.config.js
module.exports = {
content: ['./src/**/*.{html,js,jsx,tsx}'],
theme: {
extend: {
fontFamily: {
hebrew: ['Heebo', 'Assistant', 'Noto Sans Hebrew', 'sans-serif'],
'hebrew-serif': ['Frank Ruhl Libre', 'David Libre', 'serif'],
},
lineHeight: {
'hebrew': '1.7',
'hebrew-tight': '1.4',
'hebrew-relaxed': '1.9',
},
},
},
plugins: [],
};
Load the Hebrew fonts with font-display: swap. Either add a Google Fonts <link> in your HTML head:
<link rel="preconnect" href="https://fonts.googleapis.com">
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>
<link href="https://fonts.googleapis.com/css2?family=Heebo:wght@400;500;700&family=Assistant:wght@400;600&display=swap" rel="stylesheet">
Or self-host with an @font-face rule inside the same CSS file as your @theme block:
@font-face {
font-family: 'Heebo';
src: url('/fonts/heebo-variable.woff2') format('woff2');
font-weight: 400 700;
font-display: swap;
}
The &display=swap query param (link) and the font-display: swap descriptor (@font-face) both make the browser render fallback text immediately instead of hiding text until the Hebrew font loads.
Next.js: wire next/font through @theme inline. When you self-host with next/font (recommended for Next.js: no external request, no layout shift), the font is exposed as a CSS variable, and @theme cannot reference a runtime variable directly. Use @theme inline so the variable resolves at the use site:
/* app.css */
@import "tailwindcss";
@theme inline {
--font-hebrew: var(--font-heebo); /* --font-heebo comes from next/font */
}
// layout.tsx
import { Heebo } from 'next/font/google';
const heebo = Heebo({ subsets: ['hebrew', 'latin'], variable: '--font-heebo' });
// <html lang="he" dir="rtl" className={heebo.variable}> ... </html>
Plain @theme { --font-hebrew: var(--font-heebo); } (without inline) breaks, because Tailwind tries to resolve the variable at build time when it does not yet exist.
Step 2: Use Logical Property Utilities
Tailwind v4's native logical utilities and rtl:/ltr: variants cover RTL on their own, so the old community tailwindcss-rtl plugin is no longer needed. Always prefer logical utilities over physical directional ones:
| Physical (avoid) | Logical (use) | RTL Behavior |
|---|---|---|
ml-4 |
ms-4 |
Right margin in RTL |
mr-4 |
me-4 |
Left margin in RTL |
pl-4 |
ps-4 |
Right padding in RTL |
pr-4 |
pe-4 |
Left padding in RTL |
left-0 |
inset-s-0 |
Right: 0 in RTL (v4.3+; start-0 is the deprecated alias) |
right-0 |
inset-e-0 |
Left: 0 in RTL (v4.3+; end-0 is the deprecated alias) |
border-l |
border-s |
Right border in RTL |
border-r |
border-e |
Left border in RTL |
rounded-l-lg |
rounded-s-lg |
Right rounded in RTL |
rounded-r-lg |
rounded-e-lg |
Left rounded in RTL |
text-left |
text-start |
Right-aligned in RTL |
text-right |
text-end |
Left-aligned in RTL |
scroll-ml-4 |
scroll-ms-4 |
Right scroll margin in RTL |
Tailwind v4.3 inset rename. As of v4.3 (May 2026) the logical positioning utilities start-*/end-* are deprecated in favor of inset-s-*/inset-e-* (so they line up with inset-bs-*/inset-be-*). The old names still work, but prefer inset-s-0/inset-e-0 in new code. This rename affects only inset/positioning; the margin/padding/border utilities ms-*/me-*/ps-*/pe-*/border-s/border-e are unchanged. Arbitrary values compose with logical utilities too (e.g. ms-[3px], inset-s-[10px]).
Step 3: Use Dir Variants for RTL-Specific Styles
Prerequisite: the rtl: and ltr: variants (built into Tailwind v4) match on an ancestor's dir attribute. They do nothing unless an ancestor element actually carries dir="rtl" (or dir="ltr") - normally the <html> element. Set dir="rtl" on the root before relying on any rtl: utility below. Because these variants resolve via the CSS :dir() pseudo-class, they also respond correctly to dir="auto" on mixed Hebrew/English user content, not only an explicit dir="rtl".
Dark mode in v4. The v3 darkMode config key is gone. In v4 you opt into class-based dark mode in CSS with @custom-variant dark (&:where(.dark, .dark *));, then combine freely with direction, e.g. class="dark:bg-gray-900 rtl:text-right". Set dir="rtl" on <html> and toggle .dark on the same element.
When you need direction-specific overrides:
<!-- Root setup -- dir="rtl" here is what activates every rtl: variant -->
<html lang="he" dir="rtl">
<!-- Dir variant usage -->
<div class="flex rtl:flex-row-reverse">
<span class="rtl:rotate-180">→</span>
<span>הבא</span>
</div>
<!-- Icon mirroring for directional icons -->
<button class="flex items-center gap-2">
<svg class="rtl:scale-x-[-1]"><!-- arrow icon --></svg>
<span>חזרה</span>
</button>
<!-- Conditional spacing that differs by direction -->
<div class="ltr:ml-auto rtl:mr-auto">
<!-- Push to end in both directions -->
</div>
Step 4: Hebrew Typography Utilities
<!-- Hebrew body text with proper settings -->
<body dir="rtl" class="font-hebrew text-base leading-hebrew
tracking-normal">
<!-- Hebrew heading -->
<h1 class="text-3xl font-bold leading-hebrew-tight">
כותרת ראשית
</h1>
<!-- Hebrew paragraph -->
<p class="text-base leading-hebrew [word-spacing:0.05em]">
טקסט גוף עם ריווח מותאם לקריאות עברית.
</p>
<!-- Mixed Hebrew + English content -->
<p class="text-base leading-hebrew">
פריט מספר <span dir="ltr" class="font-mono">ORD-12345</span> אושר
</p>
</body>
Step 5: RTL-First Component Patterns with Tailwind
RTL-first card:
<div class="rounded-lg border border-gray-200 p-6">
<div class="flex items-center justify-between mb-4
border-b border-gray-100 pb-4">
<h3 class="text-lg font-bold">כותרת הכרטיס</h3>
<span class="text-sm text-gray-500">פעיל</span>
</div>
<p class="text-base leading-hebrew text-gray-700">
תוכן הכרטיס עם טקסט בעברית.
</p>
<div class="mt-4 flex gap-3">
<button class="bg-blue-600 text-white px-4 py-2 rounded-md">
אישור
</button>
<button class="border border-gray-300 px-4 py-2 rounded-md">
ביטול
</button>
</div>
</div>
RTL-first navigation:
<nav dir="rtl" class="flex items-center justify-between
px-6 py-4 bg-white border-b">
<div class="flex items-center gap-3">
<img src="/logo.svg" alt="לוגו" class="h-8">
<span class="font-bold text-xl">שם האתר</span>
</div>
<ul class="flex gap-6 text-sm font-medium">
<li><a href="/" class="text-blue-600">ראשי</a></li>
<li><a href="/about" class="text-gray-600">אודות</a></li>
<li><a href="/contact" class="text-gray-600">צור קשר</a></li>
</ul>
</nav>
RTL-first sidebar layout:
<div class="grid grid-cols-[280px_1fr] min-h-screen">
<!-- Sidebar: appears on right in RTL automatically -->
<aside class="border-e border-gray-200 pe-6 p-4">
<nav class="space-y-2">
<a href="#" class="block ps-4 py-2 rounded-md
bg-blue-50 text-blue-700 border-s-4
border-blue-600">לוח בקרה</a>
<a href="#" class="block ps-4 py-2 rounded-md
text-gray-600">הגדרות</a>
</nav>
</aside>
<!-- Main content -->
<main class="p-6">
<h1 class="text-2xl font-bold mb-6">לוח בקרה</h1>
</main>
</div>
Step 6: Form Utilities for Hebrew
<form dir="rtl" class="max-w-lg space-y-6">
<div>
<label for="name" class="block text-sm font-medium
text-gray-700 mb-2">שם מלא</label>
<input id="name" type="text"
class="w-full px-4 py-3 border border-gray-300
rounded-md text-base font-hebrew
focus:outline-none focus:ring-2
focus:ring-blue-500">
</div>
<div>
<label for="phone" class="block text-sm font-medium
text-gray-700 mb-2">טלפון</label>
<input id="phone" type="tel" dir="ltr"
placeholder="05X-XXXXXXX"
class="w-full px-4 py-3 border border-gray-300
rounded-md text-base
focus:outline-none focus:ring-2
focus:ring-blue-500">
</div>
<div>
<label for="message" class="block text-sm font-medium
text-gray-700 mb-2">הודעה</label>
<textarea id="message" rows="4"
class="w-full px-4 py-3 border border-gray-300
rounded-md text-base font-hebrew
leading-hebrew
focus:outline-none focus:ring-2
focus:ring-blue-500"></textarea>
</div>
<button type="submit"
class="w-full bg-blue-600 text-white py-3
rounded-md font-medium text-base
hover:bg-blue-700 transition-colors">
שליחה
</button>
</form>
Examples
Example 1: Set Up Tailwind for Hebrew Project
User says: "Configure Tailwind for my Hebrew web app"
Result: Add Hebrew font families to Tailwind theme, configure Hebrew-optimized line heights, set up dir="rtl" on root HTML element, and demonstrate using logical utilities (ms-/me-/ps-/pe-) instead of physical ones (ml-/mr-/pl-/pr-).
Example 2: Convert LTR Tailwind Component to RTL
User says: "Make this Tailwind component work in Hebrew RTL" Result: Replace all physical utility classes with logical equivalents (ml- to ms-, pl- to ps-, text-left to text-start, border-l to border-s, rounded-l to rounded-s), add rtl: variants for directional icons, and set font-hebrew class on text elements.
Example 3: Build Hebrew Dashboard with Tailwind
User says: "Create a Hebrew admin dashboard layout with Tailwind" Result: Build grid layout with RTL sidebar (border-e, pe-6), navigation with Hebrew font and RTL flow, card components using logical spacing, and form elements with proper Hebrew typography (font-hebrew, leading-hebrew).
Bundled Resources
References
references/rtl-config.md-- Complete Tailwind CSS RTL configuration reference: v4 CSS-first and v3 JavaScript config examples, full physical-to-logical utility mapping table, dir variant usage patterns, Hebrew font stack presets, typography token definitions, and migration guide from physical to logical utilities.
Gotchas
- Tailwind CSS v3+ supports RTL variants (
rtl:prefix), but agents often do not use them, instead hardcodingmr-4when they should usems-4(margin-start) for RTL compatibility. - The
space-x-4utility in Tailwind does not respect RTL direction. Agents must usegap-4with flex or grid, or manually addrtl:space-x-reverseto flip spacing direction. - Custom font declarations for Hebrew must include
font-display: swapto prevent FOIT (Flash of Invisible Text). Agents may omit this, causing Hebrew text to disappear during font loading. - Tailwind's
text-leftandtext-rightare physical properties. Usetext-startandtext-endclasses for RTL-aware alignment. Agents default to physical direction classes. - Gradient and shadow direction is physical, not logical:
bg-gradient-to-rand offset shadows do not flip in RTL. Add artl:override (e.g.rtl:bg-gradient-to-l) when the direction is meaningful.
Reference Links
| Source | URL | What to Check |
|---|---|---|
| Tailwind CSS docs | https://tailwindcss.com/docs | Current configuration syntax, v4 migration notes |
| Tailwind RTL / logical properties | https://tailwindcss.com/docs/hover-focus-and-other-states#rtl-support | rtl: and ltr: variants |
| Google Fonts – Heebo | https://fonts.google.com/specimen/Heebo | Hebrew UI font, weights, loading snippet |
| Google Fonts – Assistant | https://fonts.google.com/specimen/Assistant | Hebrew body font |
| MDN font-display | https://developer.mozilla.org/en-US/docs/Web/CSS/@font-face/font-display | swap value and FOIT mitigation |
Troubleshooting
Error: "Tailwind logical utilities not working"
Cause: Using older Tailwind version without logical property support
Solution: Logical utilities (ms-, me-, ps-, pe-, and inset inset-s-/inset-e-, formerly start-/end-) require Tailwind v3.3+. For v3.0-3.2, use rtl:/ltr: variants instead (e.g., rtl:mr-4 ltr:ml-4). Tailwind v4 has full logical property support built in; the inset-s-*/inset-e-* names landed in v4.3 (the older start-*/end-* still resolve).
Error: "Font not applying with font-hebrew class"
Cause: Hebrew font family not defined in Tailwind configuration Solution: Add the Hebrew font stack to your Tailwind theme under fontFamily.hebrew. Ensure the font CSS is imported (Google Fonts link or local @font-face). Verify the class name matches your config key.
Error: "Sidebar appears on wrong side in RTL"
Cause: Grid or flex layout not respecting dir attribute
Solution: CSS Grid and Flexbox automatically respect dir="rtl". Ensure dir="rtl" is set on the html element. Use logical properties for borders (border-e instead of border-r) and padding (pe- instead of pr-). Keep the CSS direction value consistent with the HTML dir attribute - prefer setting direction via the dir attribute so the cascade and the rtl:/ltr: variants stay in sync; if you do set direction in CSS, make sure it matches dir.