dr.Brain

doctor Brain

мир глазами веб-разработчика

Исчезающая линия

исчезающая линия или еще кое-что о магии CSS

dr.Brain

время чтения 2 мин.

Photo by Andre Benz on Unsplash

Итак, мы работали над библиотекой компонентов для React, и, спустя некоторое время, обнаружили проблему, связанную с одним из базовых компонентов, а именно с горизонтальной линией, выполнявшей роль разделителя. Проблема рендеринга самой примитивной линии - это практически невообразимо.

Простейшая версия этого компонента выглядела так:

const Divider = props => {
  const { dataTest, type } = props;
  const className = type === 'thick' ? 'thick' : undefined;

  return (
    <hr
      className={className}
      data-test={dataTest}
    />
  );
}

И этот компонент генерировал следующий HTML-код:

<hr />

Вы видите HTML-тег <hr />. Да, в данном случае использовался устаревший синтаксис HTML-документов, но никаких явных ошибок, препятствующих выводу горизонтальной линии не было.

В целом, генерируемый код проекта, в котором ошибка впервые дала о себе знать, был исключительно прост:

<div class="container">
  <p>Some text here</p>
  <hr />
  <p>More text here</p>
</div>

Итак, все были озадачены. Естественно, мы проверили версии библиотек, корректность импорта, корректность использования компонентов, так же, мы неоднократно проверили проект на отсутствие дополнительных стилей, применяемых к hr. Все результаты были превосходными, ошибок не было, как и горизонтальной линии в проекте.

Спустя некоторое время, мы наконец-то выяснили, что произошло.

Проблема заключалась в том, что весь контент был обернут в блок с следующими CSS-свойствами:

.container {
    display: flex;
    flex-direction: column;
}

Когда мы используем FlexBox, практически все элементы внутри flex-контейнера ведут себя так же, как и в обычных условиях. Но некоторые свойства: flex, display, clear меняют свое поведение.

Браузеры отображают <hr>, как пустой блок с автоматическим позиционированием горизонтальных отступов (margin-left: auto; margin-right: auto). Такой блок будет центрироваться по горизонтали, если указана его ширина. Но, когда <hr> находится внутри flex-контейнера, его ширина по умолчанию приводится к 0 и он не отображается.

Посмотрим на пример:

Есть два варианта решения такой проблемы:

  1. нужно установить ширину для тега <hr>,
  2. избегать использования FlexBox в подобных случаях.

Итак, FlexBox отличный и мощный инструмент, возможно, это лучшее, что случилось в CSS за долгое время. Тем не менее, он должен применяться только в тех случаях, когда действительно необходим. Необдуманное использование flex-модели, как мы убедились, приводит к неожиданным результатам.


Спасибо за внимание.


По материалам статьи Alvaro Motoro “The Disappearing Line (a CSS Mystery)”.

Новые публикации

Далее

Категории

О нас

Frontend & Backend. Статьи, обзоры, заметки, код, уроки.