Conceptio › Archive › arXiv CS
arXiv CS open access

Runtime BiDi Structural Verification Catches Right-to-Left Layout Defects that Accessibility, Actionability, and Logical-Property Linting Miss

Karan Yadav · arxiv_cs
arXiv CS · Papers
Open Source ↗Direct PDF ↓
software-architecturesoftware-engineeringtesting
Bidirectional (right-to-left, RTL) layout defects arise when interfaces authored with physical directional CSS (margin-left, border-left, text-align:left) are rendered under dir="rtl" without being mirrored. Accessibility engines (axe-core), actionability engines (Playwright), and even Stylelint's c
Conceptio Open Archive

Analyze & explore related research in Conceptio

Connect this record directly into your research workflow or AI agent. Explore citations across open repositories, query full text, and export structured proof bundles.

Runtime BiDi Structural Verification Catches Right-to-Left Layout Defects that Accessibility, Actionability, and Logical-Property Linting Miss Karan Yadav

arXiv:2610.32934v1 [cs.SE] 23 Oct 2026

Google Abstract—Bidirectional (right-to-left, RTL) layout defects arise when interfaces authored with physical directional CSS (margin-left, border-left, text-align:left) are rendered under dir="rtl" without being mirrored. Accessibility engines (axe-core), actionability engines (Playwright), and even Stylelint’s current core logical-property rule systematically fail to localise these defects. We present runtime structural invariants— a zero-golden mode over computed style and geometry, and a bidi-conservative differential mode—that catch them in a headless browser. On a held-out benchmark of 14 real RTL bugs reconstructed from dated fix commits in Bootstrap and Material Components Web, the detector recovers 13/14 (2 via zero-golden, 11 via the differential mode), with no false alarm on any patched version; on genuinely real historical compiled CSS it catches 1 of 2 attempted (the miss consistent with the reconstruction), using the actual committed bootstrap.rtl.css. On 16 negative LTR-island cases (8 of them hard) it reports 0 false positives, and both modes report 0 false positives on 43 unmodified real components across four design systems and three RTL architectures (rule-of-three 95% upper bound ≤ 7%). Along the way it surfaced a real directional defect—a physical text-align:left in .menu-list—in the current Bulma 1.0.4. By contrast, Stylelint’s core rule emits an identical 1744 warnings on Bootstrap’s LTR and correct-RTL builds (it cannot triage a defect from intentional physical CSS), pseudo-localisation detects none of the mirroring bugs, and a naive pixel mirror-anddiff reaches only F1 0.87 with a test-set-tuned threshold, whereas the differential needs none. We measure the two modes’ limits directly and find them complementary: on a decoration/stylingasymmetry class, zero-golden recovers 5/6 physical-left bugs but false-flags the correct logical border-inline-end (4 of 4 border cases; 0 of 2 padding/margin), which computes to a left border under RTL, while the differential detects 0/6 of the same bugs yet never false-alarms—so on our benchmarks the differential is empirically exact (0 false alarms, no misses) only on the block-level inset/margin class, and zero-golden is the sole detector of the decoration class. We scope this paper to detection; repair is future work. Index Terms—right-to-left layout, bidirectional text, CSS logical properties, web accessibility, layout verification, internationalization

I. I NTRODUCTION Web interfaces are increasingly localised into RTL scripts (Arabic, Hebrew, Persian, Urdu). The correct, directionagnostic way to author them is with CSS logical properties (margin-inline-start, border-inline-start, text-align:start), which resolve to the physical right edge under dir="rtl". In practice, however, real design systems remain overwhelmingly physical. Measuring six

shipped stylesheets (Section IV-A) we find 111–894 physical directional declarations each and near-zero logical adoption (the sole exception, Bulma, still ships 157); the dominant coping strategy is to maintain a second, machine-mirrored stylesheet (e.g. Bootstrap ships both bootstrap.css and bootstrap.rtl.css). A component rendered under dir="rtl" with the un-mirrored stylesheet—a common and easily made misconfiguration—then exhibits directional defects: start-side accents on the wrong edge, unmirrored directional icons, and popups clipped at the wrong viewport boundary. We set out to build a zero-golden detector—one needing no reference render—and found empirically that the dominant real-world defect class is not the styling asymmetry it targets but physical inset/margin offsets, which require a second, differential render: on real mined bugs the zero-golden mode accounts for only 2 of 13 detections. The two modes prove complementary—zero-golden is the only mode that detects the decoration/styling-asymmetry class, the differential the only mode for the dominant inset/margin class—and that division of labour is this paper’s empirical arc. Existing structural web-verification tools were not designed for this failure mode. ReDeCheck [2] detects element-overlap and responsive-breakpoint faults; VizAssert [3] verifies visuallogic assertions; and internationalisation-presentation tools [1], [5] model horizontal string expansion between translations, not directional mirroring. Industrial engines target orthogonal properties: axe-core [9] checks accessibility rules [8] and Playwright [10] checks pointer actionability. Static linters can flag physical properties in source, but—as we show—they are directionally blind and cannot see inline, computed, or runtime-injected styles. Contributions. (1) Runtime RTL structural invariants in two complementary modes—zero-golden (single render, a heuristic; the only mode that detects the decoration/stylingasymmetry class) and differential (bidi-conservative; empirically exact on the block-level inset/margin class it dominates, 11 of 13 detections)—with the empirical finding that neither mode subsumes the other. (2) A held-out recall evaluation on 14 real RTL bugs reconstructed from dated fix commits (two cross-checked against the actual committed historical bootstrap.rtl.css, one caught and one missed), and a precision evaluation on 43 unmodified real library components—all code we did not author—together with 16

authored LTR-island micro-benchmarks (8 genuinely hard) that stress the RTL-script precision gate. (3) A reproducible comparison against real axe-core, Playwright, Stylelint’s current core rule, pseudo-localisation, and a naive pixel mirrorand-diff, plus a prevalence and RTL-bug-history study of six shipped design systems. We scope this paper to detection; repair is future work. II. R ELATED W ORK AND P OSITIONING We position our detector against prior academic and industrial tooling. Prior i18n-presentation work [1], [5] compares a translated page against a baseline to find string-expansion overflow; it does not verify directional mirroring under dir="rtl". VizAssert [3] and its successor [4] verify formal visual-logic assertions over layout. IFix [5] and XFix [6] repair layout by constraint solving. ReDeCheck [2] models geometry and responsive breakpoints; Alameer et al.’s i18n tooling [1] uses a layout-graph model for string-expansion failures, not directional structure. axe-core and Playwright are industrial engines for accessibility and actionability respectively. None target RTL physical-vs-logical structure. Textlevel bidi checkers (e.g. Google’s BidiChecker) verify Unicode Bidirectional Algorithm conformance and mixed-script transposition within strings; our concern is orthogonal—CSS box-model geometry and physical-vs-logical layout mirroring. Two practitioner baselines are relevant: pseudo-localisation (accented, lengthened, RTL-wrapped strings) surfaces truncation and expansion but not physical-vs-logical mirroring, and mirror-and-diff visual regression (flip the LTR screenshot, diff against RTL) is the naive pixel competitor to our differential mode (Section IV-H); DOM-aware structural visual-regression tools—commercial or academic—filter pixel noise but remain direction-agnostic, encoding no start/end semantics, so they too cannot triage a mirroring defect without the logical-vsphysical knowledge our invariants add. III. RTL S TRUCTURAL I NVARIANTS We render each state in real headless Chromium and evaluate invariants over the computed style map and bounding boxes of every element whose computed direction is rtl. The invariants are zero-golden: they need no LTR reference rendering. Zero-golden detection is a heuristic that assumes startside decoration intent: a logical start-side decoration resolves to the physical right edge under dir="rtl", so a decoration still on the physical left edge is evidence—not proof—that a physical property was used where a logical one was intended. Throughout, we call a mode empirically exact on a defect class when, on our benchmarks, it produces no false alarms and no misses—an empirical property on the classes we test, not a formal soundness guarantee. Zero-golden cannot be made exact in this sense: per CSS, logical properties compute to their physical counterparts, so getComputedStyle cannot distinguish an authored border-left from a correct logical border-inline-end, which under RTL also computes to a left border. We measure this false-positive class in Section IV-D; there the differential never false-alarms on it,

but—as we also measure—never detects this class either, so the two modes are complementary rather than one dominating. Physical inline asymmetry: a left-only visible border, a left-dominant padding asymmetry, or text-align:left on RTL running text (RTL_PHYSICAL_BORDER_/PADDING_/ TEXT_ALIGN). These are gated on the element containing RTL-script (Arabic/Hebrew) text, so legitimate left-aligned LTR islands (English or numeric columns, code, <bdi> phone/email) are not flagged. • Viewport clipping: an absolutely/fixed-positioned popup, narrower than the viewport, whose box overflows [0, wviewport ] under RTL (RTL_VIEWPORT_CLIP). • Directional-icon mirroring: a directional glyph (arrow, chevron, send) not horizontally reflected (scaleX(-1)) under RTL (RTL_ICON_NOT_MIRRORED). Unlike the other invariants this one needs a per-icon directional annotation, so we exercise it only on the controlled benchmark (Table II) and exclude it from every real-code evaluation, where icons are unannotated. •

Because the invariants read computed style, they detect defects regardless of whether the offending property originates in a stylesheet, an inline style attribute, or runtime JavaScript—a reach no static linter has. Physical inset/margin offsets (e.g. right:0 vs. inset-inline-start:0) resolve to the same used value in a single render and are therefore invisible to zero-golden detection. For these we add a differential mode (summarised in Figure 1): we render the identical component—same DOM and text—under dir=ltr and dir=rtl (a directional toggle, not a cross-lingual translation pair) and flag any block-level element whose distance from the inline-start edge of its parent fails to mirror. Unlike the zero-golden invariants, the differential is not gated on script—it compares every block-level element, so an LTR island (a code block or numeric table) embedded in an RTL layout is still checked, since its placement is governed by the RTL parent and must mirror. We call it bidi-conservative: it skips inline-level elements, because Unicode bidi legitimately reorders them across directions—avoiding that false-positive class at the cost of inline-margin defects (Section IV-F). The RTL-script gate uses the Arabic and Hebrew Unicode ranges and inspects an element’s descendant text, so a defect on a wrapper whose text lives in a child is still covered; but an element with no RTL text anywhere is not, so the detector must be run against pages with real RTL content, not placeholder text. Parameters. All thresholds are fixed constants, not tuned per subject. The differential takes each block-level element’s distance from its parent’s inline-start edge—the element’s left minus the parent’s left under LTR, and the parent’s right minus the element’s right under RTL—and flags a mismatch above a 2 px tolerance (absorbing sub-pixel rounding); it ignores boxes under 4×4 px and elements whose width changes by more than 4 px between directions (re-

RTL state — dir="rtl", real RTL text headless Chromium render

zero-golden

differential

single RTL render

LTR + RTL renders

computed-style & geometry invariants

inline-start offset diff

detects: decoration / styling-asymmetry

empirically exact on: block-level inset/margin

complementary — the two classes are disjoint; neither mode subsumes the other

Fig. 1. The two runtime modes. Zero-golden needs a single RTL render and detects the decoration/styling-asymmetry class (its precision limit is a border-inline-end false positive); the differential needs an LTR and an RTL render and is empirically exact on the block-level inset/margin class. The classes are disjoint, so the modes are complementary (Sections IV-D and IV-E).

flow). “Inline-level” means computed display:inline only, so inline-block, -flex, and -grid boxes are compared. Zero-golden’s padding-asymmetry rule fires only when left padding exceeds right by more than 4 px and the element also carries text-align:left or a leftonly visible border; the viewport-clip rule ignores full-bleed boxes (width ≥ 0.9 wviewport ) and flags any box exiting [−0.5, wviewport +0.5] after skipping elements that are display:none, visibility:hidden, or fully transparent. Because only the dir attribute changes between the two differential renders they share an identical DOM, so elements are matched by document order, and “parent” denotes the immediate DOM parent (a simplification for absolutelypositioned boxes whose containing block differs). IV. E VALUATION Setup. All results are from real execution on one VM: Node 22.14, Chromium/HeadlessShell 153.0.8010.12 (Playwright 1.63.0), axe-core 4.13.0 via @axe-core/playwright 4.13.0, and Stylelint 17.15.0 [11] using its current core layoutmappings rules (property-layout-mappings and value-keyword-layout-mappings, primary option flow-relative). Renders use the fonts bundled with the pinned Playwright Chromium build; we install no additional system fonts, so glyph metrics are fixed by that build. A. Prevalence of physical directional CSS Table I counts directional declarations in six shipped stylesheets. We count declarations by matching each property name at a declaration boundary in the CSS text (“phys. boxdir” = margin/padding/border-left|right plus left|right insets; “t-align L/R” = text-align:left|

TABLE I D IRECTIONAL DECLARATIONS IN REAL SHIPPED STYLESHEETS . Stylesheet bootstrap.css (LTR) bootstrap.rtl.css (RTL) primer.css material-components-web.css foundation.css bulma.css

phys. box-dir

logical

t-align L/R

644 644 894 111 334 157

6 6 3 0 0 217

18 18 18 4 13 22

right values). Physical directional properties dominate and logical adoption is negligible. Notably, bootstrap.css and bootstrap.rtl.css carry the same 644 physical declarations: RTLCSS rewrites direction (-left↔-right) without reducing physicality—the mirrored build is just as physical, which is precisely why a second stylesheet must be maintained. Bulma is the sole logical-property-first library, yet still ships 157 physical declarations and a physical text-align:left that breaks its menu under RTL (Section IV-D). B. Static linting cannot triage directional defects Stylelint’s current core rule property-layout-mappings (flow-relative) is a source-level convention rule: it flags physical properties that have flow-relative equivalents. On Bootstrap’s LTR build it emits 1744 warnings; on Bootstrap’s correct RTL build it emits the identical 1744 (Primer 2304, MDC 2481, Bulma 791). Emitting 1744 warnings is the correct behaviour for a convention rule—but the count is unchanged between a possibly-buggy sheet and a known-correct one, so the output cannot be triaged into defects; and a convention rule fundamentally cannot see inline, computed, cascaded, or runtime-injected styles. This is a scope mismatch (convention checker ̸= defect detector) plus an un-triageable volume, not a fault in Stylelint. (Direction-aware linter plugins add scoping directives such as /*rtl:ignore*/, but share the fundamental limit that no source linter sees computed, inline, cascaded, or JS-injected styles.) C. Controlled benchmark We built 12 self-contained states (6 buggy, 6 clean) exercising the invariant classes, with the defect placed in a stylesheet, an inline attribute, or runtime-injected JS. Table II reports real detection performance; axe-core and Playwright appear as negative controls—standard accessibility and actionability CI gates that target orthogonal specifications by design—rather than competing layout detectors, so their low recall shows only that passing those gates gives false confidence about RTL layout. axe-core detects none of the RTL defects (it ships no directional rule); Playwright detects only the geometric clip and false-positives on an sr-only region; Stylelint detects only the two stylesheet-located defects and misses the inline, injected, icon, and geometric ones. We note plainly that these states were authored by us to exercise the invariants; the next study uses unmodified third-party code.

TABLE II D ETECTION ON THE CONTROLLED BENCHMARK ( N =12; POSITIVE = BUGGY ). Tool Detector (ours) axe-core 4.13.0 Playwright Stylelint (core)

TP 6 0 1 2

FP 0 0 1 0

TN 6 6 5 6

FN 0 6 5 4

P 100 – 50 100

R 100 0 17 33

TABLE III FALSE POSITIVES ON CORRECTLY- RENDERED REAL COMPONENTS , 3 VIEWPORTS EACH .

F1

Library

RTL architecture

100 – 25 50

Bootstrap 5.3.8 Foundation 6.9.0 MDC 14 Bulma 1.0.4

mirror stylesheet mirror stylesheet [dir=rtl] overrides logical properties

Total (components)

comp.

FP

14 9 10 10

0 0 0

0∗

43

0

∗

D. False positives on unmodified real components To measure precision without authoring the code, we render 43 real components under dir="rtl" using each library’s correct RTL configuration, each populated with real Arabic/Hebrew text (labels, headings, body) so the RTL-script gate is genuinely exercised rather than vacuously satisfied by English placeholder text; any flag is then a false positive. We cover four design systems spanning the three RTL architectures found in the wild: mirror stylesheet (Bootstrap 5.3.8, Foundation 6.9.0), [dir=rtl] overrides (Material Components Web 14; 526 override rules), and native logical properties (Bulma 1.0.4). Correctness is defined per architecture: the .rtl.css build (Bootstrap, Foundation); the intact stylesheet vs. a mutation that strips its [dir=rtl] rules with PostCSS (MDC), i.e. mutation-based evaluation; and the single logical-property stylesheet (Bulma). The detector reports 0 false positives across all 43 components (Table III); rerendering each at 360/768/1280 px (129 renders) leaves this unchanged, so viewport is a robustness check, not independent replication. With 0 events in n = 43, the rule-of-three 95% upper bound on the false-positive rate is 3/43 ≈ 7%. We separately run the differential mode over the same 43 correctly-built components (rendering each library’s real LTR and RTL configurations and checking that they mirror): it too reports 0 false positives, so both modes are clean on real code. This 0/43 is consistent with zero-golden’s 4/4 end-side false-positive rate below: zero-golden’s pass is the runtime check for a left-only border on an RTL-text element (invariant RTL_PHYSICAL_BORDER_ASYMMETRY), and it fired on none of the 43—so no correctly-built component actually renders such an element, and the end-side idiom that defeats zero-golden does not arise in this real-component sample. (Consistently, the only end-side border rule we find in the sampled libraries is Bulma’s .card-footer-item divider, absent from the sampled components.) The one apparent exception is not a false positive but a real bug the detector found: Bulma 1.0.4—though logicalproperty-first (157 physical vs. 217 logical declarations)—still ships .menu-list a { text-align: left }, so its menu text hugs the wrong edge under dir="rtl". Under the un-adapted condition the detector also flags genuine defects, e.g. the shipped Bootstrap .text-start utility (text-align:left !important) and leftaligned MDC text-field/data-table content that MDC’s own [dir=rtl] rules exist to fix. (Bulma does not advertise explicit RTL support; its logical properties provide it

We count the Bulma menu flag as a real bug (jgthms/bulma#4063), not a false positive, giving 0/43; under a strict protocol that treats any flag on a shipped configuration as a false positive it is 1/43 (≈ 2.3%; rule-of-three upper bound ≈ 9%). Each component is also rendered at 360/768/1280 px (129 renders) with no change; the differential mode is likewise 0 FP on the 43.

implicitly, so the menu flag is a latent directional defect rather than a regression against a promised feature; we reported it upstream as jgthms/bulma#4063.) Negative cases. A clean set that merely removes leftside styling would make “0 false positives” near-tautological. We therefore add 16 negative cases (8 of them genuinely hard) on which any flag would be a false positive: English SKU and numeric table columns, URLs, an LTR code block (including one with a physical left accent border), inline <code>, phone/email in <bdi>, an isolated LTR identifier, non-mirroring icons (checkmark, search), a brand logo, an English note, a progress bar, and a range scrubber. The detector flags 0/16, because the physical-decoration invariants are gated on the element containing RTL-script text (Section III); three positive controls—RTL text with the same physical property— are all caught, confirming the gate does not cost recall on these three controls; the gate does forgo recall on elements with no RTL text anywhere (icon-only controls, empty containers), a deliberate precision trade and a deployment precondition (Section V). By exclusion mechanism the 16 split into 8 whose physical-left styling is suppressed only by the RTL-script gate (SKU/numeric columns, URLs, code, brand logo, English note, mixed table) and 8 with no physical-left styling or an annotation-gated icon; the gate—the load-bearing rule—is thus exercised by 8, and the end-side cases below are the negatives that actually stress the invariant logic. The genuinely hard case is an element that does contain RTL text and correctly carries left-side styling. Under RTL a correct logical border-inline-end computes to a left border, indistinguishable from a physical border-left by computed style. We measure this on 6 correct end-side decorations (4 border-inline-end, one padding-inline-end, one margin-inline-end) on RTL-text elements: the zero-golden heuristic false-positives on 4/4 of the border-inline-end cases (the class it cannot distinguish) and none of the padding/margin cases, while the differential mode is clean on all 6. This is the precision limit of the zero-golden heuristic; the same class turns out to be the one only zero-golden can detect (Section IV-E). Figure 2 shows a representative defect and its logical fix. The MDC study additionally found a bug in our own

F. Recall on real mined bugs

Fig. 2. An RTL blockquote. Top: a physical border-left/text-align:left accent renders on the wrong (left) edge—the detector flags it. Bottom: the logical border-inline-start/text-align:start version renders on the correct (right/start) edge and is not flagged.

detector: an early viewport-clip invariant fired on MDC’s fullwidth fixed top-app-bar; we refined it to ignore full-bleed elements (width ≥ 0.9 wviewport ), removing the false positive while preserving detection of narrow clipped popups. This fullbleed rule is a semantic invariant—a near-full-width bar cannot be a clipped narrow popup—rather than an MDC-specific patch; but because it was prompted by the MDC set, the clip invariant’s MDC figure is not fully held-out (Section V). E. Mode complementarity: neither mode subsumes the other The precision limit above has a recall counterpart that makes the two modes complementary rather than one dominating. We construct the mirror image of the end-side set—6 physicalleft decoration bugs (border-left, text-align:left, padding-left) on RTL text, the actual mirroring defect those logical properties fix—and run both modes on this constructed decoration set. Zero-golden recovers 5/6 and the differential 0/6; both are clean on the correct counterparts. The single zero-golden miss is the padding-left case: the padding-asymmetry rule fires only when left padding exceeds right by more than 4 px and the element also carries text-align:left or a left-only border—a deliberately conservative co-condition—so a lone padding-left (which has neither co-signal) is not flagged, whereas its border-left and text-align siblings trip categorical invariants directly. The differential’s 0/6 is not a tuning artifact but structural: its only signal is an element’s box offset from the parent’s inline-start edge, and a border-left, text-align:left, or padding-left does not move that box, so the whole decoration/styling-asymmetry class is invisible to it by construction—its zero false alarms there come from never firing, not from soundness. Zero-golden is thus the only mode that detects this class, paying the border-inline-end false positive of Section IV-D as the price, while the differential is empirically exact (0 false alarms, no misses) on the disjoint block-level inset/margin class it dominates. This division of labour is not an artifact of constructed fixtures: on the 14 held-out real bugs reconstructed from Bootstrap and MDC fix commits (Section IV-F, Table IV), the partition is exact—zero-golden catches 2 (both text-align), the differential 11 (inset/margin), 1 is missed by both, and no bug is caught by both modes—so complementarity holds on code we did not write.

The controlled benchmark measures recall only on bugs we wrote. To measure recall on bugs we did not write, we started from the 53 mined RTL-fix commits (Section IV-G), kept the 24 whose diff changes a directional CSS declaration (19 MDC, 5 Bootstrap), and reconstructed the 14 that map to a single renderable declaration into minimal held-out states (pre-fix buggy, post-fix correct). Selection was by renderability of the changed declaration, decided before running the detector; no commit was dropped after observing detector behaviour. The excluded commits were SCSS-mixin/variable changes with no single renderable declaration, or docs/build commits. By bug class the 24 split as inset/offset 10, margin 6, text-align 2, border-radius 2, and other 4, and are MDC-heavy (19 of 24); the inset/margin-offset class dominates, which is why the differential carries recall. The 14 reconstructions follow this shape (11 MDC, 3 Bootstrap; 11 offset/margin, 2 text-align, 1 inline-margin miss)—so per-library recall cannot be estimated from Bootstrap’s n = 3. We run both modes and count a bug as caught if either fires; the correct version must pass both. The detector recovers 13/14 (Table IV), but the split is the real finding: only 2 are caught by zero-golden (the styling-asymmetry class, e.g. MDC bd8d1aaf data-table alignment) and 11 by the differential mode (the inset/margin-offset class, which dominates the mined fix commits). Both zero-golden catches are textalign styling-asymmetry bugs—both instances of its class in this corpus (n = 2, both MDC; on Bootstrap zero-golden is 0/3)—while the differential is 11/11 on the dominant blocklevel inset/margin class, and no bug is caught by both modes— the exact partition that corroborates the mode complementarity of Section IV-E. The miss (489e7b679, an inline card-link margin-left) is skipped by the bidi-conservative differential. The differential fires on 0/14 patched versions. (Cost is secondary: zero-golden’s single render is a median 55 ms per component and the differential’s two renders 110 ms (IQR 54– 56 vs. 108–113 ms), so the second render roughly doubles the cost—but the reason to keep zero-golden is coverage of the decoration class, plus that it needs only one direction when auditing a deployed RTL build one cannot re-render.) Because these are minimal reconstructions, 13/14 is an upper bound on field recall (real pages add cascade, specificity, and sibling noise). To validate on genuinely real code, we also render two of these Bootstrap defects using the actual committed historical bootstrap.rtl.css from the buggy revision (Bootstrap ships a single compiled RTL stylesheet, so the historical build is directly recoverable; MDC’s [dir=rtl] overrides are interleaved in its main sheet and were not as cleanly reconstructable, which is why the two spot-checks are Bootstrap’s). The dropdown-menu-end defect (57205e3d8, real right:0;left:auto) is caught by the differential on the real compiled CSS; the inline card-link is missed, consistent with the reconstruction.

TABLE IV H ELD - OUT RECALL ON REAL RTL BUGS RECONSTRUCTED FROM DATED FIX COMMITS .

reconstructed bugs caught by zero-golden caught by differential missed false alarm on patched version

Bootstrap

MDC

Total

3 0 2 1 0

11 2 9 0 0

14 2 11 1 0

Overall recall 13/14. The library split (MDC 11, Bootstrap 2) and the mode split (differential 11, zero-golden 2) are different partitions: both zero-golden catches are MDC, so Bootstrap’s two caught bugs are both differential. The 14 commits span 2017– 2021, a recent subset of the 2014–2022 fix history.

G. RTL bugs recur across a library’s lifetime We mined the full history (blobless clones) of each repository with a case-insensitive commit-message query (fix.*rtl or rtl.*(bug|fix|incorrect|broken| wrong)) and kept commits that touch .scss/.css with a directional declaration; the 14 reconstructions of Section IV-F are drawn from this set. This yields 19 explicit RTL fixes in Bootstrap and 34 in Material Components Web, spanning 2014–2022 and 2016–2022. Nineteen fixes over eight years is a small fraction of Bootstrap’s commit volume, so we do not claim RTL is a dominant cost; the defensible observation is that RTL layout defects recur across the entire lifetime of both libraries, including years after official RTL support was added. Primer has 0 such fixes, consistent with its shipping no RTL support at all (0 [dir=rtl] rules) rather than with correctness. H. Baselines: pseudo-localisation and mirror-and-diff We run the two practitioner baselines over the 14 heldout bugs. Pseudo-localisation (RTL-wrap the text with isolate marks, expand it, and bracket it, then check for overflow) detects the directional defect in 0/14 (0 recall) and moreover raises 2 false alarms: it targets truncation and expansion, and mirroring produces no overflow, while 2/14 show incidental expansion overflow that is present on the correct versions too. Mirror-and-diff (screenshot the component—not the full viewport—under LTR, flip it horizontally, and diff against RTL with pixelmatch) cannot cleanly separate buggy from correct: across the 14, the minimum buggy mismatch (0.2%) is below the maximum correct mismatch (0.6%), so the classes overlap; its best achievable F1 is 0.87 (accuracy 0.86) and only with a threshold tuned on the test set itself. The geometry differential needs no threshold, reports exactly 0 on all 14 correct versions, and flags 13/14 buggy. We compare against the standard pixel form of mirror-and-diff; a text-masking or box-only variant would reduce its noise but is itself a step toward the geometric comparison the differential performs directly. V. T HREATS TO VALIDITY Construct. The controlled benchmark, the end-side falsepositive set, and the decoration-recall set were authored by us; we therefore de-emphasise their figures, rely on the

held-out recall (13/14) and negative-case precision (0/16, 8 hard) for generalisation, and report 13/14 as an upper bound on field recall. The mode complementarity is likewise corroborated on the held-out real bugs, where the partition is exact (Section IV-E). Complementary modes, not one exact mode. Zero-golden false-positives on correct end-side (border-inline-end) decorations, which compute to a left border under RTL; the differential does not false-alarm there but also does not detect the decoration class at all (0/6), so it is empirically exact only on the block-level inset/margin class (11/11, 0 FP) and the two modes are complementary (Section IV-D). Precision generality. The 0/43 field figure reflects the physical-dominant prevalence we measured; on codebases that heavily use native logical end-side properties (border-inline-end on RTL-text elements), zerogolden’s false-positive rate rises toward the 4/4 we measure on that idiom—the differential stays clean. Tuning disclosure. One invariant, the viewport clip, was refined after a false positive on the MDC set (full-bleed suppression), so its MDC 0-FP figure is not held-out; the refinement is a general semantic rule and the other invariants were unchanged. Baseline scope. We benchmark the practitionerdefault pixel mirror-and-diff; DOM-aware structural visualregression tools reduce pixel noise but are direction-agnostic (no start/end semantics), so detecting RTL mirroring with them needs exactly the logical-vs-physical knowledge our invariants add. Benchmark availability. No public benchmark of RTL directional-mirroring defects exists—responsive-layout [2] and i18n string-expansion [1] datasets target different classes—so we mine and reconstruct our own; a full-page RTL corpus is future work. RTL-content precondition. The RTL-script gate means the detector finds nothing on pages rendered with placeholder or English text, nor on textless controls (icon-only buttons, empty inputs, pagination arrows) unless RTL text lives in a descendant; it must be run against real RTL content, and textless controls need explicit directional annotation. Composition. Components are rendered standalone; a component embedded in a real page may inherit direction and context we do not model, and minimal reconstructions omit cascade, specificity, and sibling noise. Rendering. The detector’s algorithm is deterministic, but headless layout depends on font metrics; we pin the Playwright Chromium build and install no extra fonts, so metrics are fixed but not identical to other environments. Coverage. Inline-margin, float, and physical corner-radius (border-radius) directional bugs are missed (e.g. 489e7b679), and a lone physical padding on a text-only leaf block escapes both modes (zero-golden lacks its co-signal; the differential’s box does not move and its text children are inline). The viewport-clip rule can in principle false-positive on an off-canvas panel parked off-screen while still visible; the differential’s 4 px reflow filter can mask a defect that itself shifts an element’s width; and because the differential compares inline-block/-flex boxes, one legitimately bidi-reordered among mixed-script text could in principle mismatch (none did in our sample). External. We evaluate Arabic/Hebrew RTL; other scripts (Thaana, Syriac, N’Ko,

Adlam) and mixed bidi runs are untested. Reconstruction. The held-out bugs are minimal reconstructions (a form of mutation [7]) of the changed declarations, validated on two cases with the real committed historical build. VI. C ONCLUSION Runtime BiDi structural verification detects RTL directional defects that accessibility engines, actionability engines, and Stylelint’s core logical-property rule miss. On real bugs it did not author it recovers 13/14 (2 via zero-golden, 11 via the differential mode), with no false alarm on the patched code; on legitimate LTR islands and 43 real components both modes report 0 false positives; and it surfaced a real directional defect in the current Bulma. The two modes are complementary: the differential is empirically exact (0 false alarms, no misses) on the block-level inset/margin class it dominates, while zerogolden is the only mode that detects the decoration/stylingasymmetry class, at the price of a border-inline-end false positive. Two implications follow. Because the differential carries recall—11 of the 13 real detections, with no false alarm on any patched version—it is the natural premerge CI gate wherever both directions can be rendered; the cheaper single-render zero-golden pass (median 55 vs. 110 ms, but recall-limited and prone to end-side false positives) is best reserved as a lightweight audit for deployed or thirdparty builds that cannot be re-rendered LTR. And the eightyear persistence of physical directional CSS (Section IV-G) suggests this defect class is a maintenance constant of longlived design systems, not a transient migration cost. Future work: enlarge the held-out benchmark, infer directional-icon annotations, cover more scripts and composed pages, and add multi-node counterfactual repair evaluated against an independent oracle. ACKNOWLEDGMENT Claude (Anthropic) was used to assist with background research, and portions of the tooling and prose were drafted with its assistance; the author reviewed and revised all AIassisted content, and all experiments were executed and verified by the author. The artifact (detector, both modes, baselines, benchmarks, and raw results) will be made publicly available. The Bulma .menu-list defect was reported upstream (jgthms/bulma#4063; no maintainer response at the time of writing). R EFERENCES [1] A. Alameer, S. Mahajan, W. G. J. Halfond. Detecting and localizing internationalization presentation failures in web applications. ICST, 2016. [2] T. A. Walsh, G. M. Kapfhammer, P. McMinn. ReDeCheck: automated layout failure detection for responsive web pages. ISSTA, 2017. [3] P. Panchekha, A. T. Geller, M. D. Ernst, Z. Tatlock, S. Kamil. Verifying that web pages have accessible layout. PLDI, 2018. [4] P. Panchekha, M. D. Ernst, Z. Tatlock, S. Kamil. Modular verification of web page layout. OOPSLA, 2019. [5] A. Alameer, P. T. Chiou, W. G. J. Halfond. Efficiently repairing internationalization presentation failures by solving layout constraints. ICST, 2019.

[6] S. Mahajan, A. Alameer, P. McMinn, W. G. J. Halfond. Automated repair of layout cross browser issues using search-based techniques. ISSTA, 2017. [7] Y. Jia, M. Harman. An analysis and survey of the development of mutation testing. IEEE TSE, 37(5), 2011. [8] W3C. Web Content Accessibility Guidelines (WCAG) 2.2. 2023. [9] Deque Systems. axe-core accessibility engine, v4.13.0. 2025. [10] Microsoft. Playwright: actionability checks. 2025. [11] Stylelint core rules property-layout-mappings and value-keyword-layout-mappings, primary option flow-relative (Stylelint 17.15.0). https://stylelint.io/user-guide/ rules/property-layout-mappings/ and https://stylelint.io/user-guide/rules/ value-keyword-layout-mappings/, accessed 2026-09-17.

Related documents

Record · ID 1442422 · SHA-256 eb4a9dcd9975933f
Retrieved via Conceptio: every document is proof-bundled with source, license, and retrieval metadata.
Bring this data into your agent: Connect via MCP or API · 20 free credits to start · no card required
Read the Docs → · View CLI source on GitHub · Conceptio Open Knowledge Archive