Switch to logical properties to handle LTR/RTL at once
Created by: BSarmady
Prerequisites
-
I have searched for duplicate or closed feature requests -
I have read the contributing guidelines
Proposal
Referring to this comment and this SO answer, and CanIUse inset-inline-end and others, it seems these following properties are supported in all major browsers (or green?) since mid 2020
inset-inline-start (in place of left property) inset-inline-end (in place of right property) margin-inline-start (in place of margin-left property) margin-inline-end (in place of margin-right property) margin-inline (in place of margin shorthand property) padding-inline-start (in place of padding-left property) padding-inline-end (in place of padding-right property) padding-inline (in place of padding shorthand property) text-align: start; (in place of left value) text-align: end; (in place of right value) float: inline-start; (in place of left value) float: inline-end; (in place of right value)
following styles are still using left and right
me-0
... 'me-auto',
ms-0
... ms-auto
,
.start
... .start-100
.end
... end-100
however using above mentioned attribute and properties will allow easier transition between LTR and RTL
so instead of
LTR .start-0 { left: 0 !important; }
RTL .start-0 { right: 0 !important; }
We can have just
.start-0 { inset-inline-start: 0 !important; }
and so on.
Currently I'm testing these transitions with following html, which allows me immediate transition between RTL and LTR
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8">
<meta content="width=device-width, initial-scale=1, maximum-scale=1, user-scalable=no" name="viewport">
<link rel="stylesheet" href="bootstrap-5.3.0/bootstrap.css">
<link rel="stylesheet" href="this/main.css">
<script src="jquery.1.11.3/jquery.min.js"></script>
<script src="bootstrap-5.3.0/bootstrap.bundle.js"></script>
<script>
$(function () {
const $html = $('html');
if (localStorage.getItem('dir') === 'rtl') {
$html.attr('dir', 'rtl');
} else {
$html.removeAttr('dir')
}
$('#btnDir').click(function () {
if ($html.attr('dir') === 'rtl') {
$html.removeAttr('dir');
localStorage.removeItem('dir')
} else {
$html.attr('dir', 'rtl');
localStorage.setItem('dir', 'rtl')
}
});
})
</script>
</head>
<body>
<input type="button" id="btnDir" class="btn btn-primary" value=" direction ">
<!-- Elements being tested below-->
<div class="toast-container p-3 bottom-0 end-0" aria-live="polite" aria-atomic="true">
<div class="toast show text-bg-danger" role="alert" aria-live="assertive" aria-atomic="true">
<div class="toast-header">
<strong class="me-auto">Toast-Header</strong>
<button type="button" class="btn-close" data-bs-dismiss="toast" aria-label="Close"></button>
</div>
<div class="toast-body">Toast Body</div>
</div>
<div class="toast text-bg-danger border-0 show" role="alert" aria-live="assertive" aria-atomic="true">
<div class="d-flex">
<div class="toast-body">
Hello, world! This is a toast message.
</div>
<button type="button" class="btn-close btn-close-white me-2 m-auto" data-bs-dismiss="toast" aria-label="Close"></button>
</div>
</div>
<div class="toast text-bg-primary border-0 show" role="alert" aria-live="assertive" aria-atomic="true">
<div class="d-flex">
<div class="toast-body">Toast Body</div>
<button type="button" class="btn-close btn-close-white m-auto ms-auto me-2" data-bs-dismiss="toast" aria-label="Close"></button>
</div>
</div>
</div>
</body>
</html>
Content of main.css is something like following (obviously for these to work I need to comment their counter part in bootstrap.css)
.text-start{ text-align:start !important; }
.text-end{ text-align:end !important; }
.me-0{ margin-inline-end:0 !important }
.me-1{ margin-inline-end:0.25rem !important }
.me-2{ margin-inline-end:0.5rem !important }
.me-3{ margin-inline-end:1rem !important }
.me-4{ margin-inline-end:1.5rem !important }
.me-5{ margin-inline-end:3rem !important }
.me-auto{ margin-inline-end:auto !important }
.start-0{ inset-inline-start:0 !important; }
.start-50{ inset-inline-start:50% !important;}
.start-100{ inset-inline-start:100% !important;}
.end-0{ inset-inline-end:0 !important; }
.end-50{ inset-inline-end:50% !important;}
.end-100{ inset-inline-end:100% !important;}
.toast-header .btn-close {
margin-inline-end: calc(-0.5 * var(--bs-toast-padding-x));
margin-inline-start: var(--bs-toast-padding-x);
}
Motivation and context
I think it allows transition from having two separate CSS for LTR and RTL to one single file. and in case in future you want to support top to bottom languages ;)