Зачем нужны логические свойства CSS
Свойства -top, -bottom, -left и -right
Многие свойства CSS — такие как margin, padding, border и другие — имеют направленные варианты.
Возьмём, к примеру, свойство margin. Допустим, необходимо установить отступы 1em сверху и снизу, 2em слева и справа.
Длинная форма записи будет выглядеть так…
.component {
margin-top: 1em;
margin-bottom: 1em;
margin-left: 2em;
margin-right: 2em;
}CSS предоставляет удобный сокращённый синтаксис, позволяющий создавать такие элементы с помощью одного свойства margin, следуя порядку top, right, bottom, left по часовой стрелке.
.component {
margin: 1em 2em 1em 2em;
}При использовании сокращённой записи, если значение опущено, то копируется значение, расположенное напротив него. В результате можно ещё больше сократить запись.
.component {
margin: 1em 2em;
}Это отлично работает, когда ваш код всегда используется в языке, который следует одному и тому же потоку текста.
Но не все языки такие!
Как обрабатывать RTL и вертикальные языки
Русский, мой родной язык, пишется слева направо и сверху вниз.
Но такой язык, как арабский, пишется справа налево. Такие языки, как китайский и японский, традиционно пишутся вертикальными столбцами.
Если я применю направленный margin только к одной стороне, как здесь…
.component:first-child {
margin-left: 0;
}…где удаляется margin? Это зависит от языка!
В русском языке поле удаляется с начала первого элемента. В арабском языке оно удаляется после первого элемента, что может привести к неожиданным визуальным эффектам.
В традиционном китайском языке оно было бы удалено из пространства между двумя столбцами (немного похоже на удаление нижнего поля в параграфе).
Исторически сложилось так, что для поддержки различных языков необходимо было проверять атрибут [dir], чтобы обрабатывать подобные вещи...
[dir="ltr"] .component:first-child {
margin-left: 0;
}
[dir="rtl"] .component:first-child {
margin-right: 0;
}Очень раздражает, правда? Но теперь есть логические свойства CSS!
Логические свойства CSS
Логические свойства CSS определяют значения свойств не явными указаниями, такими как top или left, а их логическим направлением: inline или block, start или end.
*-inlineсвойства следуют направлению текста (слева и справа для русского языка)*-blockсвойства пересекают его (сверху и снизу для русского языка)*-startсвойства применяются перед элементом (сверху или слева для русского языка)*-endсвойства применяются после элемента (справа или снизу для русского языка)
Возьмём предыдущий пример…
.component {
margin-top: 1em;
margin-bottom: 1em;
margin-left: 2em;
margin-right: 2em;
}Его можно переписать с использованием логических свойств следующим образом…
.component {
margin-block-start: 1em; /* top */
margin-block-end: 1em; /* bottom */
margin-inline-start: 2em; /* left */
margin-inline-end: 2em; /* right */
}Свойства *-block и *-inline также имеют сокращённые версии, в формате {start} {end}…
.component {
margin-block: 1em 1em;
margin-inline: 2em 2em;
}И, как и в случае со старыми свойствами, можно ещё больше упростить, если оба значения одинаковы…
Практический пример
Помните предыдущий пример, где мы удалили поле из элемента :first-child?
[dir="ltr"] .component:first-child {
margin-left: 0;
}
[dir="rtl"] .component:first-child {
margin-right: 0;
}С помощью логических свойств CSS его можно записать следующим так...
.component:first-child {
margin-inline-start: 0;
}Теперь, независимо от направления текста, margin применяется (или в данном случае удаляется) в нужном месте!