[Перевод] Погружаемся в логические свойства CSS

Поддержка логических свойств CSS со временем становится лучше. Однако мне по-прежнему трудно запомнить их, когда использую их в проекте. Что означают start и end? Несколько сложно охватить все детали без проб и ошибок.

В этой статье я нацелен прокачать вас и пробежаться по использованию логических свойств, чтобы возникло твёрдое понимание, у дизайнеров, говорящих на английском и арабском языках. Я попытался придумать визуальное объяснение логических свойств, которое, надеюсь, будет понятным. Готовы? Погружаемся!

Вступление

Основная идея логических свойств в том, что мы не будем использовать свойства направлений CSS как есть. Вместо этого мы привяжемся к прописанному в HTML направлению. Позволяющие сделать подобное свойства называются логическими. Посмотрите на пример:

2a2648ba1dfd89e50597344630bb074f.jpg

У нас есть карточка, содержащая аватар и текст. В макете слева направо поле расположено справа от аватара и наоборот, в макете справа налево поле отражено и расположено слева. Вот так это пишется без логических свойств:

.avatar {
  margin-right: 1rem;
}

html[dir="rtl"] .avatar {
  margin-right: 0;
  margin-left: 1rem;
}

Обратите внимание, что margin-right в макете справа налево сброшено в 0, оно здесь не нужно. Представьте, что мы делаем это для большого проекта; кода слишком много. Но логические свойства решают проблему.

.avatar {
  margin-inline-end: 1rem;
}

Нам нужно только установить margin-inline-end, и свойство будет работать по-разному в зависимости от направления в HTML-документе. Мощно, правда?

Разница между inline и block

Используя логические свойства, вы обычно видите inline млм block. Давайте посмотрим, что они означают.

ca5167ee59577073d50420d328e5ceab.jpg

Смысл inline и block меняется исходя из режима письма. В языках вроде английского inline направлен горизонтально, а block — вертикально. В языках вроде японского — всё наоборот: inline направлено вертикально, block — горизонтально.

Что означает inline?

В подобных английскому и арабскому языках inline направлено горизонтально. В английском start указывает на левую (left)сторону в макетах слева направо (на английском языке) и он же указывает на правую (right) сторону в арабских макетах, которые справа налево. В макетах справа налево start указывает на правую сторону, end — на левую.

В примере ниже круг имеет поле (margin) с правой стороны. В макетах справа налево поле должно быть слева. Запомните, что свойства start и end зависят от контекста — направления макета:

a6e4c72f03f35bcbe8419963017ff4da.jpg

Визуализация начала и конца

Начало и конец улицы

Чтобы прояснить, что же означают start и end, я покажу пример на картинке:

9ef15e9de1f74fd97e0e407524aadf4f.jpg

Мне нравится представлять это как начало и конец улицы. Когда направление — слева направо, начало находится слева, а конец — справа. Когда направление справа налево, всё наоборот.

Направление чтения

Другой способ запомнить принцип — думать о направлении чтения. Английский текст начинается слева и заканчивается справа, арабский текст начинается справа и заканчивается слева.

f84684cba7c74350a11afcedc87eee60.jpg

Какие свойства можно применять как логические?

Большую часть свойств CSS можно применять как логические. Вот основные из них:

  • размеры: высота, ширина (height, width);

  • margin, border, padding, их подвиды;

  • обтекание (floating), позиционирование;

  • выравнивание текста. 

Я не могу перечислить все логические свойства здесь: их много. Пожалуйста, прочитайте весь список на MDN.

Примеры и применение 

Первый пример 

Теперь, когда я рассказал об основах, позвольте мне показать пример UI, чтобы убедиться, что у вас есть твёрдое понимание.

0b588a8c42273b3f6c59455487f5438b.jpg

У нас есть компонент со следующими свойствами:

  • left-padding и right-padding;

  • рамка (border) с левой стороны;

  • поле (margin) для иконки.

Вот так можно справиться с макетом слева направо.

.card {
  padding-left: 2.5rem;
  padding-right: 1rem;
  border-left: 6px solid blue;
}

.card__icon {
  margin-right: 1rem;
}

А так — с макетом справа налево; направления должны быть отражены.

html[dir="rtl"] .card {
  padding-right: 2.5rem;
  padding-left: 1rem;
  border-left: 0;
  border-right: 6px solid blue;
}

html[dir="rtl"] .card__icon {
  margin-right: 1rem;
}

И снова много работы. Но мы можем минимизировать CSS-код, вот так:

.card {
  padding-inline-start: 2.5rem;
  padding-inline-end: 1rem;
  border-inline-start: 6px solid blue;
}

.card__icon {
  margin-inline-end: 1rem;
}

Второй пример: выравнивание текста 

Иногда нужно сделать выравнивание английского текста справа. Смотрите пример. Есть поле ввода с ограниченным числом символов. Чтобы помочь пользователю это понять, у поля есть метка.

1e4526162f216c7ecd132b3e98b755e7.jpg

В английском подобное выравнивается справа, в арабском — слева. Это правило — прекрасный кандидат, чтобы продемонстрировать логические свойства CSS.

.indicator {
  text-align: end;
}

Вот как мы описали бы изложенное выше без логических свойств:

.indicator {
  text-align: right;
}

html[dir="rtl"] .indicator {
  text-align: left;
}

Третий пример: позиционирование

Когда какой-то элемент позиционируется абсолютно, мы должны уделить внимание свойствам right и left:

d19c30a872b45be25035aba8caec2792.jpg
.menu__toggle {
  position: absolute;
  right: 1rem;
  top: 1rem;
}

html[dir="rtl"] .menu__toggle {
  right: auto;
  left: 1rem;
}

Мы можем сократить код выше при помощи свойства inset Его поддержка не идеальна, но за ним будущее. Свойство inset-inline-end в макетах слева направо — эквивалент правой стороны, а в макетах справа налево — эквивалент левой стороны для макетов справа налево.Код выше можно написать так:

.menu__toggle {
  position: absolute;
  inset-inline-end: 1rem;
  top: 1rem;
}

Кроме того, top может выступать как inset-block-start, но это не нужно в нашем случае: мы не работаем с японским или с веб-сайтом на восточном языке.

Пример 4: float

664c1d5eeb6ea2c1ca5bb5a8c3efb982.jpg

Вы можете удивиться применению float в 2021 году. Когда у нас есть фигура и мы хотим, чтобы текст её обтекал, без старого доброго свойства float это не будет работать. Вот, как мы можем воплотить идею:

img {
  float: left;
  shape-outside: circle(50%);
  margin-right: 20px;
}

Код работает в макетах слева направо, для направления справа налево код CSS будет вроде такого:

html[dir="rtl"] img {
  float: right;
  margin-right: 0;
  margin-left: 20px;
}

При помощи логических свойств код на CSS сокращается, вот так:

img {
  float: inline-start;
  shape-outside: circle(50%);
  margin-inline-end: 20px;
}

Намного проще, правда?

Логические по своей природе свойства 

Grid и flexbox — по умолчанию логические свойства. Это означает, что они отражают направление автоматически. При помощи этих свойств CSS-код сеток и компонентов для мультиязычных сайтов сокращается до минимума.

В следующем примере у нас grid-обёртка. Обратите внимание, что элементы упорядочены согласно направления.

799b19ed5d957f1164f257c3a072ccb2.jpg

Чего бы мне хотелось

Единственное моё желание на данный момент, чтобы свойство background-color стало логическим.

b9f42d94775686cf5027b3bec776c629.jpg

Зачем? Чтобы добавить иконку как изображение фона так, чтобы она разворачивалась в зависимости от направления. К сожалению, свойства вроде background-position-inline у нас нет. Вот, что я напишу сейчас.

.input {
  background: url("mail.svg") left 0.5rem center/24px no-repeat;
  padding-inline-start: 2.4rem;
}

html[dir="rtl"] {
  background: url("icon.svg") right 0.5rem center/24px no-repeat;
}

Если вы хотите больше узнать о стилизации справа налево, написал о ней расширенное руководство. Надеюсь, оно вам понравится. А если хотите больше уделить время веб-разработке, то у нас как раз скоро стартует новый поток соответствующего курса.

5dcd67e0bd804aed5ea7f488a557f4aa.jpg

Узнайте, как прокачаться в других специальностях или освоить их с нуля:

Другие профессии и курсы

ПРОФЕССИИ

КУРСЫ

© Habrahabr.ru