#css #flexbox #grid #internationalization
Вопрос:
У меня есть простой div
( grid layout
но то же самое относится и к flexbox
), который показывает три разных text
элемента.
Проблема в том , что всякий раз, когда для моего html
dir
атрибута установлено значение rtl
, порядок элементов сетки меняется, и я хотел бы иметь возможность предотвратить это изменение в этом конкретном случае (где порядок содержимого основан не на направлении записи, а на семантическом значении.
Для примера, вот как выглядят мои предметы:
let direction = 'rtl';
document.getElementById('toggle-direction').addEventListener('click', () => {
direction = direction === 'rtl' ? 'ltr' : 'rtl';
document.documentElement.setAttribute('dir', direction);
});
.container {
display: grid;
grid-template-rows: 1fr;
grid-template-columns: repeat(3, 1fr);
border-radius: 5px;
padding: 10px;
}
.left-arrow {
grid-column: 1 / 2;
grid-row: 1 / 2;
margin-inline-end: auto;
}
.center-content {
grid-row: 1 / 2;
grid-column: 2 / 3;
text-align: center;
}
.right-arrow {
grid-row: 1 / 2;
grid-column: 3 / 4;
margin-inline-start: auto;
}
#toggle-direction {
grid-row: 2 / 3;
grid-column: 1 / 4;
}
<div class="container">
<span class="left-arrow"><</span>
<span class="center-content">Center content</span>
<span class="right-arrow">></span>
<button id="toggle-direction">Toggle direction</button>
</div>
PS: Я мог бы добавить direction: ltr;
в .container
селектор, но это создало бы нежелательный стиль, так как я хочу использовать встроенный стиль.
Комментарии:
1. укажите направление в сеточном контейнере, которое должно быть ltr
2. @TemaniAfif, я улучшил код, чтобы показать, почему простое добавление
direction: ltr
не является решением
Ответ №1:
Насколько я понимаю, вы хотите, чтобы стрелки сохраняли свою ориентацию. Поэтому вы должны изолировать и обернуть элементы, направление которых вы хотите согласовать, в контейнеры с согласованным направлением потока (и поместить все, что вы хотите обновить, за пределы этих контейнеров) примерно так :
let direction = 'rtl';
document.getElementById('toggle-direction').addEventListener('click', () => {
direction = direction === 'rtl' ? 'ltr' : 'rtl';
document.documentElement.setAttribute('dir', direction);
});
.container {
display: grid;
grid-template-rows: 1fr;
grid-template-columns: repeat(3, 1fr);
}
.ltr {
direction: ltr;
}
.left-arrow {
grid-column: 1 / 2;
text-align: center;
}
.center-content {
grid-column: 2 / 3;
text-align: center;
}
.right-arrow {
grid-column: 3 / 4;
text-align: center;
}
#toggle-direction {
grid-column: 1 / 4;
}
<!-- inherit direction flow -->
<div class="container ltr">
<!-- ltr direction flow -->
<p class="left-arrow">Left arrow</p>
<p class="center-content">Center content</p>
<p class="right-arrow">Right arrow</p>
</div>
<div class="container">
<!-- inherit direction flow -->
<button id="toggle-direction">Toggle direction</button>
</div>
Внесенные изменения: заверните первую строку, которая была у вас внутри контейнера, в другой контейнер ( class="colum rtl"
), у которого всегда есть направление.
Небольшие обновления css для сохранения вида.
В качестве альтернативы вы можете поместить контейнер со стрелками внутри контейнера с помощью кнопки. Но для того, чтобы иметь согласованное rtl
направление, вам нужно будет поместить их в контейнер (с class="rtl"
), и вам понадобится немного больше обновлений для вашего css, чтобы сохранить аспект.
В качестве альтернативы, если у вас действительно нет возможности изолировать все компоненты, необходимые для обеспечения согласованного направления, вы можете для некоторых конкретных случаев создать класс class="inherit-direction"
(например), и в вашем js, когда вы меняете направление документа, измените направление контейнеров с помощью этого класса ( document.getElementsByClassName("inherit-direction")
и повторите их).
Но я бы настоятельно посоветовал использовать этот последний вариант только в качестве последней меры и максимально ограничить количество применений.
Комментарии:
1. В этом и заключается проблема с таким упрощенным примером. Проблема в том, что теперь каждый дочерний компонент
.container
будет элементом, основанным на направлении ltr , и потеряет все соответствующие стили, предоставленные изdir="rtl"
. Я улучшу свой пример.2. Лучшим способом было бы поместить компоненты, в которых вы хотите обеспечить согласованный поток, в отдельные контейнеры и добавить к ним универсальный класс . Таким образом, все, что находится снаружи, наследует тело, и только то, что находится внутри этих контейнеров, остается ltr (я обновлю пример для лучшего понимания).
3. Я обновил ответ. Надеюсь, это поможет 🙂