RTL implementation
Created by: ffoodd
There have been quite a few dicussions around this in Bootstrap, and it's probably been asked more often than any other feature.
Pre-requisites
- Should work in all supported browsers, meaning Edge Legacy and Safari 10 for the oldest.
- Should work seamlessly with all our components and utilities.
- Should be tested, probably with new examples templates.
- Should be maintainable, thus not lay on hacky things.
Am I missing any pre-requisite, @twbs/team?
FWIW, one of the best resource I ever read about RTL is very recent: RTL Styling 101 by Ahmad Shadeed.
Solutions
Let me try to sum up the various ways to tackle this in v5.
dist
file
Another This is what we used in Boosted v4, using rtlcss.
Pros
- another file, not a single bloated one
- easy to setup
Cons
- some values have to be ignored, and rtlcss is not very pleasant to use with clunky CSS comments to flag things: https://rtlcss.com/learn/usage-guide/control-directives/#ignore
- a few overrides were required in Boosted, mostly around
transform
s and inlined SVGs
Logical properties
They're meant to be the standard way to do. However Edge Legacy doesn't support them, so we're kinda stuck with this.
PostCSS-logical is meant to handle this in two ways:
- each logical property results in two new declarations, suffixed with
:dir()
- each logical property only gets a LTR fallback:
text-align: left; text-align: start;
Both of them will result in a bloated filesize, and the second—despite being the ordinary fallback—won't allow Edge Legacy to handle RTL.
Pros
- future-proof
- standardized and CSS-y
Cons
- Lack of support
- Filesize (directly due to the lack of support)
Resources
- Adrian Roselli's post about logical properties
- Can I Use logical properties?
- Chen Hui Jing's "CSS for internationalisation"
- Andy Bell's Piccalilli's post about logical properties
Sassy way
As suggested in the most recent issue about RTL— #28797 (closed)— a sassy way is possible.
I'd be in favor of a simpler way to handle things:
- using a mixin, like we do for media queries:
@include rtl()
-
checking for a boolean before going ahead, like we do for shadows or rounded:
@if $enable-rtl {}
- then wrapping mixin content in
:dir(rtl)
using@content
- and then, just use CSS.
Pros
- Sass only
- Consistent with our current way to do things
- Can be
false
by default
Cons
- Requires that we write the RTL styles by ourselves
- Source code bloat
- A single bloated output when enabled
So…
My CSS geekery would like to go with Logical properties; rtlcss seems simpler to me since I'm already used to it and it's a robust and proven solution; the sassy way looks a bit naive…
I'd like to hear opinions and suggestions before trying something.
Related issues
Thanks @ZaidBarghouthi for listing this!
#28797 (closed) #28238 (closed) #24807 (closed) #27123 (closed) #27122 (closed) #26879 (closed) #26818 (closed) #19545 (closed) #26299 (closed) #25422 (closed) #24662 (closed) #23703 #24332 (closed) #23117 (closed) #22708 #22137 (closed) #21619 (closed) #21180 (closed) #20293 (closed) #19555 (closed) #20075 (closed) #19787 (closed) #19703 (closed) #19668 (closed) #19643 (closed) #19545 (closed) #19379 (closed) #18184 (closed) #17595 (closed) #16455 (closed) #16419 (closed) #15717 (closed) #15700 (closed) #15509 (closed) #15479 (closed) #15433 (closed) #14717 (closed) #14510 (closed) #13564 (closed)