For a product adding an Arabic locale, how would you choose between refactoring the stylesheet to CSS logical properties and generating a mirrored stylesheet with a build-time RTL post-processor such as rtlcss or CSSJanus?
answer
- build time versus style-resolution time
- one bundle or two
- mixed-direction pages settle it
- codemod cost against zero refactor
- neither one fixes shadows and icons
basics
~20 sLogical properties resolve per element at style time and need one stylesheet, but require touching every rule. A post-processor flips physical declarations at build time with no refactor, yet ships two bundles and cannot handle both directions on one page.
solid answer
~50 sThe two approaches differ in *when* the mirroring happens. A post-processor like rtlcss or CSSJanus rewrites physical declarations at build time, producing a second stylesheet you serve to right-to-left locales — no source changes, works on legacy and third-party CSS, and it ships today. Its costs are structural: two bundles and a serving decision, one direction per document so a mixed-direction page is impossible, escape hatches like rtlcss's `/*rtl:ignore*/` control comments scattered through the source, and nothing for vertical writing modes. Logical properties move the decision to style resolution in the browser: one stylesheet, correct per subtree so an Arabic quote inside an English page just works, and no build coupling — at the cost of a codemod across every rule and no help for CSS you do not own. My default is logical properties as the standard for owned code, a post-processor confined to vendor stylesheets, and a visual audit either way for shadows, transforms, gradients and directional icons, which neither approach mirrors.
go deeper
Know that both routes exist: rewrite the CSS in logical properties, or run a tool that generates a mirrored stylesheet. Being able to name the two options is enough here.
Explain the mechanism of each — a build step rewriting physical values versus the browser resolving flow-relative ones live — and note that a post-processor produces a second bundle.
Argue the tradeoff with concrete failure modes: mixed-direction content, escape-hatch comments accumulating in source, third-party CSS, and the residue of shadows and transforms that neither approach mirrors.
Own the decision framework and the rollout: which inputs decide it, how the migration is sequenced by cascade layer, what lint gate prevents regression, how vendor CSS is contained, and what QA budget the launch carries.
## Frame the choice correctly This is not a question about which tool is better. It is a question about *when* the physical mapping is decided: - **Post-processor**: decided at **build time**. The output is two stylesheets whose physical values are already mirrored. - **Logical properties**: decided at **style-resolution time** in the browser, from the element's inherited `writing-mode` and `direction`. Every difference below falls out of that one distinction. ## What a post-processor gives you rtlcss and CSSJanus parse your CSS and swap physical values: `margin-left` becomes `margin-right`, `left: 0` becomes `right: 0`, `text-align: left` becomes `right`, background positions and shadow offsets are negated. Both tools have been used in production for years. **Strengths** - **No source refactor.** The existing stylesheet, however large, ships as-is. - **It handles CSS you do not own.** Vendor and third-party stylesheets go through the same pipeline. - **It flips more than the box.** Good post-processors also mirror shadow and background offsets, which logical properties do not touch at all. **Costs** - **Two artifacts.** A second bundle per direction, a serving or bundling decision, and doubled cache entries. - **One direction per document.** The whole page gets one stylesheet. A page that must render an English UI around an Arabic body, or a comment thread with mixed-direction posts, cannot be expressed. - **Escape hatches leak into source.** Anything that must *not* flip — a code block, a phone-number field, a logo — needs a control comment such as rtlcss's `/*rtl:ignore*/`. Those accumulate, and a developer who does not know the pipeline exists will not add them. - **It is a heuristic.** The tool guesses intent from syntax. Shorthands, `calc()` expressions, custom-property values and gradients are where the guesses go wrong. - **Nothing for vertical writing modes.** It only knows left/right. ## What logical properties give you **Strengths** - **One stylesheet.** No second build artifact, no serving logic, no cache split. - **Per-subtree correctness.** Because `direction` is inherited and resolved live, a right-to-left island inside a left-to-right page is automatically correct. For any product with user-generated content this is often decisive rather than merely nice. - **Intent is in the source.** `padding-inline-start` says "the gutter before the text", which is what the designer meant. The next developer inherits the meaning, not a build-time transformation they must know about. - **It generalises.** The same code is correct in vertical writing modes. **Costs** - **A codemod across the codebase**, plus review of the cases a codemod cannot decide — a physical `left` that is genuinely physical, such as a decorative element pinned to the screen edge. - **Half-migration is a real hazard.** Mixing spellings for the same side makes the outcome depend on source order. - **Third-party CSS is untouched.** You still need an answer for it. - **It covers the box only.** Shadows, transforms, gradients and directional icons remain your problem. ## The decision inputs I would actually weigh 1. **Does one page ever need both directions?** If yes, the post-processor is disqualified for owned code and the question is settled. 2. **How much CSS do we own?** A codebase that is mostly vendor CSS gets little from a refactor. 3. **Is this a one-off locale launch or a long-term internationalisation posture?** A single launch under deadline can justify the build-time route; a product committed to many locales pays the refactor once and stops thinking about it. 4. **What is the state of the design system?** If components are already tokenised, a codemod is cheap and the blast radius is contained. 5. **Is vertical typography plausible?** If Japanese vertical layout is on any roadmap, only logical properties survive it. ## The answer I would give Adopt logical properties as the standard for code we own, enforced by a lint rule so new components cannot regress, and migrate cascade layer by cascade layer — reset and base first — rather than component by component, so override order never sits in a half-migrated state. Keep a post-processor scoped to vendor stylesheets we cannot change. Then, regardless of route, budget a visual QA pass in the target locale, because the residue — shadow direction, chevron rotation, gradient angle, directional artwork — is invisible to both mechanisms and is exactly what a native reader notices first. Logical box properties are supported in all current browsers, so browser support is not a live factor in this decision; the tradeoff is entirely about migration cost, mixed-direction pages, and what each approach leaves behind.
- Which single requirement most often decides this outright?Whether one page must render both directions at once. A post-processor picks a direction per stylesheet, so a page containing a right-to-left quote inside a left-to-right interface — or any user-generated content feed — cannot be served correctly by it. Logical properties resolve per element, so mixed-direction content is simply correct.
- If you choose the logical-properties route, what stops the codebase drifting back?A lint rule that fails the build on physical box longhands in owned stylesheets, plus migrating whole cascade layers rather than individual components so override order is never half-converted. Convention alone does not hold; the collision between a physical and a logical declaration for the same side is decided by source order, which reviewers do not reliably catch.
- Can the two approaches coexist?Yes, and that is usually the pragmatic answer. Owned code uses logical properties; vendor stylesheets you cannot edit go through a mirroring step and sit in an earlier cascade layer so your own declarations still win. The one thing to avoid is running a post-processor over logical CSS, where its physical heuristics have nothing correct to do.
saying these in an interview costs you the question
- Treats the choice as purely a matter of taste
- Ignores that a post-processor ships two stylesheets
- Assumes a build-time flip handles mixed-direction pages
- Claims either approach removes the need for visual QA
- Cites browser support as the deciding factor today