{"id":12934,"date":"2026-10-02T19:18:03","date_gmt":"2026-10-02T17:18:03","guid":{"rendered":"https:\/\/voctos.net\/rtl-css-wordpress-themes-audit\/"},"modified":"2026-10-02T21:16:42","modified_gmt":"2026-10-02T19:16:42","slug":"rtl-css-wordpress-themes-audit","status":"publish","type":"post","link":"https:\/\/voctos.net\/ar\/rtl-css-wordpress-themes-audit\/","title":{"rendered":"RTL \u0641\u064a \u0642\u0648\u0627\u0644\u0628 \u0648\u0648\u0631\u062f\u0628\u0631\u064a\u0633: \u0643\u064a\u0641 \u062a\u062a\u0639\u0627\u0645\u0644 10 \u0642\u0648\u0627\u0644\u0628 \u0634\u0627\u0626\u0639\u0629 \u0645\u0639 \u0627\u0644\u062a\u062e\u0637\u064a\u0637 \u0627\u0644\u0639\u0631\u0628\u064a"},"content":{"rendered":"<p>Most Arabic WordPress sites inherit their RTL quality from the theme. On 2 October 2026 we read the shipped CSS of 10 popular themes: 1,168 of 1,254 direction-sensitive declarations (93%) in their main stylesheets were physical left and right rules, and 6 of the 8 classic themes used no logical properties at all.<\/p>\n<blockquote>\n<p><strong>Key takeaways<\/strong><\/p>\n<ul>\n<li>9 of 10 themes carry the rtl-language-support tag; 8 of 10 ship an RTL stylesheet for their main CSS.<\/li>\n<li>Three themes swap in a full mirrored copy (Astra, Neve, Storefront). Four add a small override file on top (GeneratePress, Kadence, Blocksy, OceanWP).<\/li>\n<li>Only Blocksy (71% logical) and Hello Elementor (60%) write most direction-sensitive rules as logical properties.<\/li>\n<li>The two default block themes ship no RTL file. Core mirrors block styles, but inline padding in block markup is never flipped.<\/li>\n<li>Your own CSS (child theme, Additional CSS, builder custom CSS) is never flipped. Write it with logical properties.<\/li>\n<\/ul>\n<\/blockquote>\n<h2>What we found in 10 popular WordPress themes<\/h2>\n<p>Every theme we checked supports Arabic in some form, and they get there in four different ways. Nine carry the rtl-language-support tag, eight ship an RTL stylesheet for their main CSS, and only two write most direction-sensitive rules as logical properties. The rest depend on a second file to mirror them.<\/p>\n<table style=\"width:100%;border-collapse:collapse;font-size:14px\">\n<thead>\n<tr style=\"background:#0a2e1a;color:#fff\">\n<th style=\"padding:13px 16px;text-align:left;font-weight:600\">Theme (version)<\/th>\n<th style=\"padding:13px 16px;text-align:left;font-weight:600\">RTL tag<\/th>\n<th style=\"padding:13px 16px;text-align:left;font-weight:600\">Main CSS<\/th>\n<th style=\"padding:13px 16px;text-align:left;font-weight:600\">Physical rules<\/th>\n<th style=\"padding:13px 16px;text-align:left;font-weight:600\">Logical rules<\/th>\n<th style=\"padding:13px 16px;text-align:left;font-weight:600\">RTL stylesheet<\/th>\n<th style=\"padding:13px 16px;text-align:left;font-weight:600\">How RTL loads<\/th>\n<\/tr>\n<\/thead>\n<tbody>\n<tr style=\"background:#fff;border-bottom:1px solid #e5e7eb\">\n<td style=\"padding:12px 16px;font-weight:600;color:#0a2e1a\">Astra 4.14.0<\/td>\n<td style=\"padding:12px 16px\">Yes<\/td>\n<td style=\"padding:12px 16px\">43.9 KB<\/td>\n<td style=\"padding:12px 16px\">105<\/td>\n<td style=\"padding:12px 16px\">0<\/td>\n<td style=\"padding:12px 16px\">43.9 KB<\/td>\n<td style=\"padding:12px 16px\">Full mirrored copy (replace)<\/td>\n<\/tr>\n<tr style=\"background:#fff;border-bottom:1px solid #e5e7eb\">\n<td style=\"padding:12px 16px;font-weight:600;color:#0a2e1a\">Hello Elementor 3.5.1<\/td>\n<td style=\"padding:12px 16px\">Yes<\/td>\n<td style=\"padding:12px 16px\">18.7 KB (3 files)<\/td>\n<td style=\"padding:12px 16px\">14<\/td>\n<td style=\"padding:12px 16px\">21<\/td>\n<td style=\"padding:12px 16px\">18.7 KB, shipped<\/td>\n<td style=\"padding:12px 16px\">.rtl rules inside the main files<\/td>\n<\/tr>\n<tr style=\"background:#fff;border-bottom:1px solid #e5e7eb\">\n<td style=\"padding:12px 16px;font-weight:600;color:#0a2e1a\">GeneratePress 3.6.1<\/td>\n<td style=\"padding:12px 16px\">Yes<\/td>\n<td style=\"padding:12px 16px\">19.1 KB<\/td>\n<td style=\"padding:12px 16px\">77<\/td>\n<td style=\"padding:12px 16px\">0<\/td>\n<td style=\"padding:12px 16px\">2.8 KB<\/td>\n<td style=\"padding:12px 16px\">Override file added<\/td>\n<\/tr>\n<tr style=\"background:#fff;border-bottom:1px solid #e5e7eb\">\n<td style=\"padding:12px 16px;font-weight:600;color:#0a2e1a\">Kadence 1.5.2<\/td>\n<td style=\"padding:12px 16px\">Yes<\/td>\n<td style=\"padding:12px 16px\">105.1 KB (4 files)<\/td>\n<td style=\"padding:12px 16px\">209<\/td>\n<td style=\"padding:12px 16px\">0<\/td>\n<td style=\"padding:12px 16px\">3.9 KB<\/td>\n<td style=\"padding:12px 16px\">Override file added<\/td>\n<\/tr>\n<tr style=\"background:#fff;border-bottom:1px solid #e5e7eb\">\n<td style=\"padding:12px 16px;font-weight:600;color:#0a2e1a\">Blocksy 2.1.58<\/td>\n<td style=\"padding:12px 16px\">No<\/td>\n<td style=\"padding:12px 16px\">92.3 KB<\/td>\n<td style=\"padding:12px 16px\">27<\/td>\n<td style=\"padding:12px 16px\">65<\/td>\n<td style=\"padding:12px 16px\">2.2 KB<\/td>\n<td style=\"padding:12px 16px\">Override file added<\/td>\n<\/tr>\n<tr style=\"background:#fff;border-bottom:1px solid #e5e7eb\">\n<td style=\"padding:12px 16px;font-weight:600;color:#0a2e1a\">OceanWP 4.2.6<\/td>\n<td style=\"padding:12px 16px\">Yes<\/td>\n<td style=\"padding:12px 16px\">179.5 KB<\/td>\n<td style=\"padding:12px 16px\">512<\/td>\n<td style=\"padding:12px 16px\">0<\/td>\n<td style=\"padding:12px 16px\">17.3 KB<\/td>\n<td style=\"padding:12px 16px\">rtl.css in theme root<\/td>\n<\/tr>\n<tr style=\"background:#fff;border-bottom:1px solid #e5e7eb\">\n<td style=\"padding:12px 16px;font-weight:600;color:#0a2e1a\">Neve 4.2.15<\/td>\n<td style=\"padding:12px 16px\">Yes<\/td>\n<td style=\"padding:12px 16px\">39.3 KB<\/td>\n<td style=\"padding:12px 16px\">72<\/td>\n<td style=\"padding:12px 16px\">0<\/td>\n<td style=\"padding:12px 16px\">39.3 KB<\/td>\n<td style=\"padding:12px 16px\">Full mirrored copy (replace)<\/td>\n<\/tr>\n<tr style=\"background:#fff;border-bottom:1px solid #e5e7eb\">\n<td style=\"padding:12px 16px;font-weight:600;color:#0a2e1a\">Storefront 4.6.2<\/td>\n<td style=\"padding:12px 16px\">Yes<\/td>\n<td style=\"padding:12px 16px\">39.4 KB<\/td>\n<td style=\"padding:12px 16px\">152<\/td>\n<td style=\"padding:12px 16px\">0<\/td>\n<td style=\"padding:12px 16px\">39.4 KB<\/td>\n<td style=\"padding:12px 16px\">Full mirrored copy (replace)<\/td>\n<\/tr>\n<tr style=\"background:#fff;border-bottom:1px solid #e5e7eb\">\n<td style=\"padding:12px 16px;font-weight:600;color:#0a2e1a\">Twenty Twenty-Five 1.5<\/td>\n<td style=\"padding:12px 16px\">Yes<\/td>\n<td style=\"padding:12px 16px\">0.6 KB<\/td>\n<td style=\"padding:12px 16px\">0<\/td>\n<td style=\"padding:12px 16px\">0<\/td>\n<td style=\"padding:12px 16px\">None<\/td>\n<td style=\"padding:12px 16px\">Core block styles<\/td>\n<\/tr>\n<tr style=\"background:#fff;border-bottom:1px solid #e5e7eb\">\n<td style=\"padding:12px 16px;font-weight:600;color:#0a2e1a\">Twenty Twenty-Four 1.6<\/td>\n<td style=\"padding:12px 16px\">Yes<\/td>\n<td style=\"padding:12px 16px\">1.2 KB<\/td>\n<td style=\"padding:12px 16px\">0<\/td>\n<td style=\"padding:12px 16px\">0<\/td>\n<td style=\"padding:12px 16px\">None<\/td>\n<td style=\"padding:12px 16px\">Core block styles<\/td>\n<\/tr>\n<tr style=\"background:#fff;border-bottom:1px solid #e5e7eb\">\n<td style=\"padding:12px 16px;font-weight:600;color:#0a2e1a\"><strong>Total<\/strong><\/td>\n<td style=\"padding:12px 16px\"><strong>9 of 10<\/strong><\/td>\n<td style=\"padding:12px 16px\"><\/td>\n<td style=\"padding:12px 16px\"><strong>1,168<\/strong><\/td>\n<td style=\"padding:12px 16px\"><strong>86<\/strong><\/td>\n<td style=\"padding:12px 16px\"><strong>8 of 10<\/strong><\/td>\n<td style=\"padding:12px 16px\"><\/td>\n<\/tr>\n<\/tbody>\n<\/table>\n<p>A physical rule is not a bug: the RTL file flips it, and <code>left:0; right:0<\/code> renders the same both ways. The count shows how much of the Arabic layout depends on that second file.<\/p>\n<p>The tag is self-declared. The <a href=\"https:\/\/make.wordpress.org\/themes\/handbook\/review\/required\/theme-tags\/\" target=\"_blank\" rel=\"noopener\">WordPress.org theme tag rules<\/a> define rtl-language-support as a theme showing no visual issues in RTL mode, tested with the RTL Tester plugin, which was last updated in August 2020. Blocksy has no tag, yet loads an RTL file.<\/p>\n<blockquote>\n<p><strong>How we checked<\/strong><\/p>\n<p>VOCTOS, 2 October 2026. Versions and tags come from the WordPress.org Theme API, code from each theme&#8217;s official zip. We counted the front-end stylesheet(s) each theme&#8217;s PHP enqueues, plus the file it loads when <code>is_rtl()<\/code> is true. A Python script split every rule block into declarations and counted properties, never selectors. Physical: margin, padding and border left\/right, <code>left<\/code>, <code>right<\/code>, and float, clear or text-align set to left or right. Logical: the <code>-inline<\/code> equivalents and start\/end values.<\/p>\n<p>Limits: free versions only. CSS generated in PHP (Astra, Kadence and Neve all print inline CSS) and shorthand such as <code>margin: 0 8px 0 0<\/code> are not counted. These are code counts, not rendered pages: they measure maintenance load, not visible defects.<\/p>\n<\/blockquote>\n<h2>How does WordPress load an RTL stylesheet?<\/h2>\n<p>WordPress loads RTL CSS three ways. A file named rtl.css in the theme root loads automatically when the site language is right-to-left. Any enqueued stylesheet can declare an -rtl twin with wp_style_add_data(), either replacing the original or loading after it. PHP can also branch on is_rtl() for markup and inline CSS.<\/p>\n<p>The first route is documented in the <a href=\"https:\/\/developer.wordpress.org\/themes\/classic-themes\/basics\/template-files\/\" target=\"_blank\" rel=\"noopener\">Theme Handbook&#8217;s template files list<\/a>: rtl.css loads on its own whenever the site language is right-to-left. OceanWP uses it. The second route is <a href=\"https:\/\/developer.wordpress.org\/reference\/functions\/wp_style_add_data\/\" target=\"_blank\" rel=\"noopener\">wp_style_add_data()<\/a> with the <code>rtl<\/code> key. Pass <code>'replace'<\/code> and WordPress swaps the file; pass <code>true<\/code> and it loads the -rtl file after the original.<\/p>\n<p>The <code>suffix<\/code> key decides the filename: core&#8217;s <code>WP_Styles<\/code> class inserts -rtl before it. Without a suffix, main.min.css becomes main.min-rtl.css (Astra&#8217;s naming). With <code>'suffix', '.min'<\/code> it becomes main-rtl.min.css (Neve&#8217;s naming). A wrong guess means a 404 and an unstyled Arabic site.<\/p>\n<pre><code>add_action( 'wp_enqueue_scripts', function () {\n    $ver = wp_get_theme()-&gt;get( 'Version' );\n\n    wp_enqueue_style(\n        'mytheme-main',\n        get_theme_file_uri( 'assets\/css\/main.min.css' ),\n        array(),\n        $ver\n    );\n\n    \/\/ On RTL locales, load assets\/css\/main-rtl.min.css instead.\n    wp_style_add_data( 'mytheme-main', 'rtl', 'replace' );\n    wp_style_add_data( 'mytheme-main', 'suffix', '.min' );\n} );\n\n\/\/ Direction-aware markup: swap arrow characters, as Hello Elementor does.\n$prev_arrow = is_rtl() ? '&amp;rarr;' : '&amp;larr;';\n$next_arrow = is_rtl() ? '&amp;larr;' : '&amp;rarr;';<\/code><\/pre>\n<p><a href=\"https:\/\/developer.wordpress.org\/reference\/functions\/is_rtl\/\" target=\"_blank\" rel=\"noopener\">is_rtl()<\/a> checks whether the current locale is right-to-left, and body_class() adds an <code>.rtl<\/code> class. Neve uses is_rtl() to move its scroll-to-top button between <code>left:20px<\/code> and <code>right:20px<\/code>; OceanWP swaps its arrow icons.<\/p>\n<h2>Do block themes need an rtl.css?<\/h2>\n<p>Mostly no. WordPress core registers an -rtl version of block styles and swaps it in on RTL sites, so Twenty Twenty-Five and Twenty Twenty-Four ship no RTL file at all. The gap is inline styles: padding and margins saved in block markup are physical, and no RTL stylesheet ever touches them.<\/p>\n<p>We checked WordPress 7.1.2, the current release. In blocks.php, <a href=\"https:\/\/developer.wordpress.org\/reference\/functions\/register_block_style_handle\/\" target=\"_blank\" rel=\"noopener\">register_block_style_handle()<\/a> calls <code>wp_style_add_data( $style_handle_name, 'rtl', 'replace' )<\/code> whenever the site is RTL and an -rtl file exists. In script-loader.php, <a href=\"https:\/\/developer.wordpress.org\/reference\/functions\/wp_default_styles\/\" target=\"_blank\" rel=\"noopener\">wp_default_styles()<\/a> does the same for wp-block-library. All 87 core blocks that have a style.css also ship style-rtl.css.<\/p>\n<p>Patterns are the weak spot. Across 114 template, part and pattern files, Twenty Twenty-Five has 139 physical declarations in inline styles and zero logical ones; 7 set different left and right padding, such as a spacing preset on the left and <code>padding-right:0<\/code>. Twenty Twenty-Four has 91 and 3. In Arabic, those offsets stay where they were drawn.<\/p>\n<p><strong>If you build block patterns for Arabic sites, keep left and right spacing equal or check each one on an Arabic staging copy.<\/strong><\/p>\n<h2>Why write logical properties if the theme already ships rtl.css?<\/h2>\n<p>Because the theme&#8217;s RTL file covers only the theme&#8217;s own CSS. Your child theme, Additional CSS, plugin overrides and page builder custom CSS reach the browser exactly as written, so every <code>margin-left<\/code> in them stays on the left in Arabic. A logical property makes one rule correct in both directions.<\/p>\n<p>The W3C internationalization guidance on <a href=\"https:\/\/www.w3.org\/International\/questions\/qa-html-dir\" target=\"_blank\" rel=\"noopener\">structural markup and right-to-left text<\/a> says to &#8220;use logical (&#8216;end&#8217; and &#8216;start&#8217;) on properties or values related to margins, padding, alignment&#8221;. Browser support is settled. MDN lists <a href=\"https:\/\/developer.mozilla.org\/en-US\/docs\/Web\/CSS\/margin-inline-start\" target=\"_blank\" rel=\"noopener\">margin-inline-start<\/a> as Baseline widely available since January 2020 and <a href=\"https:\/\/developer.mozilla.org\/en-US\/docs\/Web\/CSS\/inset-inline-start\" target=\"_blank\" rel=\"noopener\">inset-inline-start<\/a> since April 2021. <a href=\"https:\/\/developer.mozilla.org\/en-US\/docs\/Web\/CSS\/float\" target=\"_blank\" rel=\"noopener\">float: inline-start<\/a> is newer (Chrome 118), so prefer flexbox there.<\/p>\n<p>Maintenance matters too. Astra&#8217;s main stylesheet is 44,905 bytes and its RTL copy 44,936, two files that must stay in step every release. Elementor&#8217;s developers named that cost when they began <a href=\"https:\/\/developers.elementor.com\/elementor-3-15-developers-update\/\" target=\"_blank\" rel=\"noopener\">replacing physical properties with logical ones in version 3.15<\/a>, aiming to drop the duplicate *-rtl.css files.<\/p>\n<pre><code>\/* Before: physical rules, plus a second rule set in rtl.css *\/\n.card        { padding-left: 24px; border-left: 4px solid var(--accent); text-align: left; }\n.card__badge { position: absolute; top: 12px; right: 12px; }\n.card__icon  { float: left; margin-right: 12px; }\n\n.rtl .card        { padding-left: 0; padding-right: 24px; border-left: 0;\n                    border-right: 4px solid var(--accent); text-align: right; }\n.rtl .card__badge { right: auto; left: 12px; }\n.rtl .card__icon  { float: right; margin-right: 0; margin-left: 12px; }\n\n\/* After: one rule set, correct in both directions *\/\n.card        { padding-inline-start: 24px; border-inline-start: 4px solid var(--accent); text-align: start; }\n.card__badge { position: absolute; top: 12px; inset-inline-end: 12px; }\n.card__head  { display: flex; gap: 12px; } \/* icon + title row; replaces the float *\/\n\n\/* Only genuinely directional icons get mirrored *\/\n:dir(rtl) .icon--directional { transform: scaleX(-1); }<\/code><\/pre>\n<h2>Which icons should flip in RTL, and which should not?<\/h2>\n<p>Flip icons that point along the reading direction: back and forward arrows, breadcrumb chevrons, next and previous controls. Do not flip media playback controls, clocks and refresh arrows, search magnifiers, or icons that carry no direction, such as a checkmark. Google&#8217;s Material Design bidirectionality guidance draws the same line.<\/p>\n<p>The <a href=\"https:\/\/material.io\/archive\/guidelines\/usability\/bidirectionality.html\" target=\"_blank\" rel=\"noopener\">Material bidirectionality page<\/a> keeps playback buttons and progress bars left-to-right because they follow the media, not time. Clocks still turn clockwise, a search handle reflects right-handed use, and icons that do not communicate direction are not changed. The <a href=\"https:\/\/developers.google.com\/fonts\/docs\/material_icons\" target=\"_blank\" rel=\"noopener\">Material Icons guide<\/a> adds that in RTL, forward points left.<\/p>\n<p>In CSS, mirror with <code>transform: scaleX(-1)<\/code> on a class you add only to directional icons. The <a href=\"https:\/\/developer.mozilla.org\/en-US\/docs\/Web\/CSS\/:dir\" target=\"_blank\" rel=\"noopener\">:dir() pseudo-class<\/a> has been available across browsers since December 2023 and matches the direction the browser computes, even when inherited or set by <code>dir=\"auto\"<\/code>. MDN notes that <code>[dir=rtl]<\/code> attribute selectors never match the auto value. Transforms never flip on their own.<\/p>\n<p>If you want a developer to put your Arabic WordPress build through these checks, <a href=\"https:\/\/www.voctos.com\/web-development\/\" target=\"_blank\" rel=\"noopener\">I want VOCTOS to review my site&#8217;s RTL layout<\/a>.<\/p>\n<h2>How do flexbox and grid behave under dir=rtl?<\/h2>\n<p>They follow the text direction without extra code. A flex row starts at the inline-start edge, so in Arabic the first item sits on the right, and grid column line 1 moves to the right-hand side. Problems start when CSS fights this with row-reverse, order hacks or physical offsets.<\/p>\n<p>MDN defines <a href=\"https:\/\/developer.mozilla.org\/en-US\/docs\/Web\/CSS\/flex-direction\" target=\"_blank\" rel=\"noopener\">flex-direction: row<\/a> as a main axis that matches the text direction. For grid, MDN&#8217;s guide to <a href=\"https:\/\/developer.mozilla.org\/en-US\/docs\/Web\/CSS\/Guides\/Grid_layout\/Logical_values_and_writing_modes\" target=\"_blank\" rel=\"noopener\">logical values and writing modes<\/a> shows line 1 placed on the right and line -1 on the left once direction is rtl. <code>justify-content: flex-start<\/code> and <code>gap<\/code> mirror for free.<\/p>\n<p>Three things do not. <code>translateX()<\/code> is physical, so a menu hidden with <code>translateX(-100%)<\/code> needs the opposite sign in RTL. <code>background-position: left<\/code> stays left. And a <code>row-reverse<\/code> added to fake RTL reverses again once <code>dir=\"rtl\"<\/code> is set.<\/p>\n<h2>Numbers, Latin text and Arabic fonts inside RTL pages<\/h2>\n<p>Direction is not only layout. Prices, phone numbers, SKUs and English brand names inside Arabic sentences need bidi isolation, or digits and punctuation drift to the wrong end. Wrap inserted values in <code>&lt;bdi&gt;<\/code>, give user-generated fields <code>dir=\"auto\"<\/code>, and keep email and URL inputs left-to-right.<\/p>\n<p>Check that the header calls <code>language_attributes()<\/code>, which prints <code>lang<\/code> and <code>dir=\"rtl\"<\/code> on the html element. In our <a href=\"https:\/\/voctos.net\/arabic-website-hreflang-lang-dir-audit\/\">audit of lang, dir and bdi on 29 Arab brand homepages<\/a>, 3 of 27 Arabic pages had no dir on html: a Saudi bank, an Egyptian retailer and an Egyptian hospital.<\/p>\n<p>Fonts are the other half of an Arabic layout. Set an Arabic font family explicitly rather than trusting the theme default, then check its weights and line height on long Arabic headings. Our <a href=\"https:\/\/voctos.net\/arabic-web-fonts-page-speed\/\">measurements of Arabic web font payloads and loading<\/a> show how to subset and preload without hurting LCP.<\/p>\n<h2>Elementor and other page builders on Arabic sites<\/h2>\n<p>Treat the builder as a second theme. Elementor ships its own LTR and RTL CSS and has moved toward logical properties since version 3.15, but values you type into widget controls, absolute offsets and custom CSS still need an RTL check on a real Arabic page before launch.<\/p>\n<p>Since <a href=\"https:\/\/elementor.com\/blog\/new-localized-editor-number-scrubber\/\" target=\"_blank\" rel=\"noopener\">Elementor 3.7<\/a>, the editor language is independent of the site, so a team can work in an English editor while the site renders RTL. Use it: set the Site Language to Arabic on staging before building, so widgets are placed in their real direction.<\/p>\n<p>Hello Elementor, the theme published by the Elementor team, takes the logical route itself: 21 of its 35 direction-sensitive declarations are logical, and its three stylesheets carry 8 selectors that target <code>.rtl<\/code> or <code>[dir=rtl]<\/code> directly. Version 3.5.1 also ships flipped -rtl copies that no theme PHP enqueues. On a builder site, the risk sits in your widget settings.<\/p>\n<h2>Our read<\/h2>\n<p>The rtl-language-support tag tells you almost nothing. Nine of ten themes carry it, and the one without it has the most logical CSS in our set. Choose a theme by how it loads RTL and how much of its CSS is physical, then judge the rest on an Arabic staging site.<\/p>\n<p>Mirrored copies (Astra, Neve, Storefront) are the most predictable for the theme&#8217;s own CSS, because the RTL file is a complete flipped copy of every rule. Override files are far smaller, 2.2 to 3.9 KB for Blocksy, GeneratePress and Kadence, but they must restate each asymmetric rule by hand, so gaps appear as one-off misalignments. Neither protects your own code.<\/p>\n<p>Our position: do not rewrite a theme&#8217;s CSS. Put Arabic fixes in a child theme or plugin, written in logical properties, and keep an RTL override only for transforms, background positions and directional icons.<\/p>\n<h2>A 15-point RTL QA checklist before launch<\/h2>\n<p>Run these checks on a staging copy with the Site Language set to Arabic, at desktop width and at 360 pixels. They target the faults our theme review points to: physical CSS outside the theme&#8217;s RTL file, unmirrored inline styles, wrongly flipped icons and mixed-direction strings.<\/p>\n<ol>\n<li>View source: html carries <code>lang=\"ar\"<\/code> (or your regional code) and <code>dir=\"rtl\"<\/code>.<\/li>\n<li>body carries the <code>.rtl<\/code> class, so theme and plugin RTL selectors can match.<\/li>\n<li>Network panel: the theme&#8217;s -rtl or rtl.css file returns 200, and with replace the LTR file is not also loaded.<\/li>\n<li>Header: logo on the right, menu flowing right to left, nested submenus opening to the left.<\/li>\n<li>Mobile menu: the off-canvas panel slides in from the correct side.<\/li>\n<li>Breadcrumb separators, pagination and previous\/next links point the reading way.<\/li>\n<li>Directional icons are mirrored; play buttons, clocks, search and checkmarks are not.<\/li>\n<li>Sliders and carousels: &#8220;next&#8221; moves forward in Arabic reading order, and swipe matches.<\/li>\n<li>Forms: labels and errors align right; email, URL and phone inputs use <code>dir=\"ltr\"<\/code>.<\/li>\n<li>Prices, SKUs, phone numbers and Latin brand names inside Arabic text are isolated with <code>&lt;bdi&gt;<\/code> or <code>dir=\"auto\"<\/code>.<\/li>\n<li>WooCommerce cart and checkout: column order, quantity buttons and totals read correctly.<\/li>\n<li>Additional CSS, child theme CSS and builder custom CSS contain no physical left or right rules.<\/li>\n<li>Block patterns and templates: no asymmetric inline padding or margins left from an LTR design.<\/li>\n<li>The Arabic font loads in every weight the design uses.<\/li>\n<li>At 360 pixels wide, the page has no horizontal scroll in RTL.<\/li>\n<\/ol>\n<h2>What to do next<\/h2>\n<p>The useful question is not whether a theme &#8220;supports RTL&#8221;. All ten here do, in some form. Ask instead how much of your CSS gets mirrored for you, and how much you wrote yourself. That second share grows with every customisation.<\/p>\n<p>If you are choosing a theme for a new Arabic or bilingual site in Saudi Arabia, the UAE, Egypt or elsewhere, test two shortlisted themes on Arabic staging with the checklist first. If the site is already live, start with point 12: search your custom CSS for left and right, convert it to logical properties, then run the full list. For hands-on help, <a href=\"https:\/\/www.voctos.com\/web-development\/\" target=\"_blank\" rel=\"noopener\">get my Arabic WordPress site checked by a VOCTOS developer<\/a>, or <a href=\"https:\/\/www.voctos.com\/seo\/\" target=\"_blank\" rel=\"noopener\">book a technical SEO review of my Arabic pages<\/a>.<\/p>\n<h2>FAQ<\/h2>\n<h3>Which popular WordPress themes support Arabic RTL layouts?<\/h3>\n<p>All ten we checked on 2 October 2026 support RTL. Astra, Neve and Storefront swap in a full mirrored stylesheet. GeneratePress, Kadence, Blocksy and OceanWP add an override file. Hello Elementor puts RTL rules inside its main files, and Twenty Twenty-Five and Twenty Twenty-Four rely on core block styles.<\/p>\n<h3>Do I need an rtl.css file in my child theme?<\/h3>\n<p>Only for rules that logical properties cannot express. Write child theme CSS with margin-inline, padding-inline, inset-inline and text-align start or end, and it works in both directions. Keep a small rtl.css for transforms, background positions and mirrored icons. WordPress loads rtl.css from the active theme&#8217;s root automatically on RTL sites.<\/p>\n<h3>Does the rtl-language-support tag guarantee a good Arabic layout?<\/h3>\n<p>No. The tag is self-declared by the theme author and means no visual issues were found in RTL mode during testing. In our check, 9 of 10 themes carried it, while Blocksy, which has no tag, wrote 71% of its direction-sensitive rules as logical properties. Test on Arabic staging instead.<\/p>\n<h3>My site looks fine in English but the Arabic version is misaligned. Why?<\/h3>\n<p>Usually because custom CSS was written with physical properties. The theme&#8217;s RTL file mirrors only the theme&#8217;s own stylesheet, so margin-left in Additional CSS, a child theme, block markup or builder custom CSS stays on the left. Search those sources for left and right and convert them to logical properties.<\/p>\n<h3>Should every icon be flipped with transform: scaleX(-1) in RTL?<\/h3>\n<p>No. Flip only icons that point along the reading direction, such as back and forward arrows, breadcrumb chevrons and next or previous controls. Material Design guidance keeps media playback controls, clocks, refresh arrows, search icons and non-directional icons as drawn. Add a dedicated class to directional icons and mirror only that class.<\/p>\n<p><script type=\"application\/ld+json\">\n{\n  \"@context\": \"https:\/\/schema.org\",\n  \"@graph\": [\n    {\n      \"@type\": \"BlogPosting\",\n      \"headline\": \"RTL in WordPress Themes: How 10 Popular Themes Handle Arabic Layouts\",\n      \"description\": \"We read the shipped CSS of 10 popular WordPress themes on 2 October 2026: 93% of direction-sensitive rules in their main stylesheets were physical, and 6 of 8 classic themes used no logical properties. Includes a developer playbook and a 15-point RTL QA checklist.\",\n      \"datePublished\": \"2026-10-02\",\n      \"dateModified\": \"2026-10-02\",\n      \"inLanguage\": \"en\",\n      \"author\": {\n        \"@type\": \"Person\",\n        \"name\": \"Reem Sameh\",\n        \"jobTitle\": \"Senior Full-Stack Web Developer\",\n        \"url\": \"https:\/\/voctos.net\/team\/reem-sameh\/\",\n        \"worksFor\": {\"@type\": \"Organization\", \"name\": \"VOCTOS\", \"url\": \"https:\/\/www.voctos.com\/\"}\n      },\n      \"publisher\": {\n        \"@type\": \"Organization\",\n        \"name\": \"VOCTOS\",\n        \"url\": \"https:\/\/www.voctos.com\/\",\n        \"logo\": {\"@type\": \"ImageObject\", \"url\": \"https:\/\/voctos.net\/wp-content\/themes\/voctos-blog\/assets\/img\/logo.png\"}\n      },\n      \"mainEntityOfPage\": \"https:\/\/voctos.net\/rtl-css-wordpress-themes-audit\/\"\n    },\n    {\n      \"@type\": \"Dataset\",\n      \"name\": \"VOCTOS check of 10 WordPress themes: RTL stylesheets and physical vs logical CSS (October 2026)\",\n      \"description\": \"Theme versions, rtl-language-support tags, main and RTL stylesheet sizes, and counts of physical versus logical direction-sensitive CSS declarations for Astra, Hello Elementor, GeneratePress, Kadence, Blocksy, OceanWP, Neve, Twenty Twenty-Five, Twenty Twenty-Four and Storefront, read from official WordPress.org theme packages on 2 October 2026.\",\n      \"creator\": {\"@type\": \"Organization\", \"name\": \"VOCTOS\", \"url\": \"https:\/\/www.voctos.com\/\"},\n      \"temporalCoverage\": \"2026-10-02\"\n    },\n    {\n      \"@type\": \"FAQPage\",\n      \"mainEntity\": [\n        {\n          \"@type\": \"Question\",\n          \"name\": \"Which popular WordPress themes support Arabic RTL layouts?\",\n          \"acceptedAnswer\": {\"@type\": \"Answer\", \"text\": \"All ten we checked on 2 October 2026 support RTL. Astra, Neve and Storefront swap in a full mirrored stylesheet. GeneratePress, Kadence, Blocksy and OceanWP add an override file. Hello Elementor puts RTL rules inside its main files, and Twenty Twenty-Five and Twenty Twenty-Four rely on core block styles.\"}\n        },\n        {\n          \"@type\": \"Question\",\n          \"name\": \"Do I need an rtl.css file in my child theme?\",\n          \"acceptedAnswer\": {\"@type\": \"Answer\", \"text\": \"Only for rules that logical properties cannot express. Write child theme CSS with margin-inline, padding-inline, inset-inline and text-align start or end, and it works in both directions. Keep a small rtl.css for transforms, background positions and mirrored icons. WordPress loads rtl.css from the active theme's root automatically on RTL sites.\"}\n        },\n        {\n          \"@type\": \"Question\",\n          \"name\": \"Does the rtl-language-support tag guarantee a good Arabic layout?\",\n          \"acceptedAnswer\": {\"@type\": \"Answer\", \"text\": \"No. The tag is self-declared by the theme author and means no visual issues were found in RTL mode during testing. In our check, 9 of 10 themes carried it, while Blocksy, which has no tag, wrote 71% of its direction-sensitive rules as logical properties. Test on Arabic staging instead.\"}\n        },\n        {\n          \"@type\": \"Question\",\n          \"name\": \"My site looks fine in English but the Arabic version is misaligned. Why?\",\n          \"acceptedAnswer\": {\"@type\": \"Answer\", \"text\": \"Usually because custom CSS was written with physical properties. The theme's RTL file mirrors only the theme's own stylesheet, so margin-left in Additional CSS, a child theme, block markup or builder custom CSS stays on the left. Search those sources for left and right and convert them to logical properties.\"}\n        },\n        {\n          \"@type\": \"Question\",\n          \"name\": \"Should every icon be flipped with transform: scaleX(-1) in RTL?\",\n          \"acceptedAnswer\": {\"@type\": \"Answer\", \"text\": \"No. Flip only icons that point along the reading direction, such as back and forward arrows, breadcrumb chevrons and next or previous controls. Material Design guidance keeps media playback controls, clocks, refresh arrows, search icons and non-directional icons as drawn. Add a dedicated class to directional icons and mirror only that class.\"}\n        }\n      ]\n    }\n  ]\n}\n<\/script><\/p>\n","protected":false},"excerpt":{"rendered":"<p>\u0642\u0631\u0623\u0646\u0627 CSS \u0641\u064a 10 \u0642\u0648\u0627\u0644\u0628 \u0648\u0648\u0631\u062f\u0628\u0631\u064a\u0633 \u0634\u0627\u0626\u0639\u0629: 93% \u0645\u0646 \u0627\u0644\u0642\u0648\u0627\u0639\u062f \u0627\u0644\u062d\u0633\u0627\u0633\u0629 \u0644\u0644\u0627\u062a\u062c\u0627\u0647 \u0641\u064a \u0623\u0648\u0631\u0627\u0642 \u0623\u0646\u0645\u0627\u0637\u0647\u0627 \u0627\u0644\u0631\u0626\u064a\u0633\u064a\u0629 \u0641\u064a\u0632\u064a\u0627\u0626\u064a\u0629\u060c \u06486 \u0645\u0646 8 \u0642\u0648\u0627\u0644\u0628 \u0643\u0644\u0627\u0633\u064a\u0643\u064a\u0629 \u0644\u0627 \u062a\u0633\u062a\u062e\u062f\u0645 \u0623\u064a \u062e\u0635\u0627\u0626\u0635 \u0645\u0646\u0637\u0642\u064a\u0629. \u0625\u0644\u064a\u0643 \u0643\u064a\u0641 \u064a\u064f\u062d\u0645\u0651\u0644 RTL\u060c \u0648\u0642\u0627\u0626\u0645\u0629 \u062a\u062d\u0642\u0642 \u0644\u0644\u0625\u0637\u0644\u0627\u0642.<\/p>","protected":false},"author":2,"featured_media":12941,"comment_status":"closed","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":{"_acf_changed":false,"inline_featured_image":false,"post_team_member":1296,"vb_event":"","vb_takeaways":"","vb_sources":"","vb_figure":"","vb_figure_label":"","vb_sector":"","vb_sample":"","vb_period":"","vb_engines":"","vb_method":"","vb_verified":"","footnotes":""},"categories":[53,1],"tags":[],"class_list":["post-12934","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-research-data","category-technical-seo"],"acf":[],"_links":{"self":[{"href":"https:\/\/voctos.net\/ar\/wp-json\/wp\/v2\/posts\/12934","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/voctos.net\/ar\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/voctos.net\/ar\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/voctos.net\/ar\/wp-json\/wp\/v2\/users\/2"}],"replies":[{"embeddable":true,"href":"https:\/\/voctos.net\/ar\/wp-json\/wp\/v2\/comments?post=12934"}],"version-history":[{"count":1,"href":"https:\/\/voctos.net\/ar\/wp-json\/wp\/v2\/posts\/12934\/revisions"}],"predecessor-version":[{"id":12942,"href":"https:\/\/voctos.net\/ar\/wp-json\/wp\/v2\/posts\/12934\/revisions\/12942"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/voctos.net\/ar\/wp-json\/wp\/v2\/media\/12941"}],"wp:attachment":[{"href":"https:\/\/voctos.net\/ar\/wp-json\/wp\/v2\/media?parent=12934"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/voctos.net\/ar\/wp-json\/wp\/v2\/categories?post=12934"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/voctos.net\/ar\/wp-json\/wp\/v2\/tags?post=12934"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}