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

Итак, мы работали над библиотекой компонентов для 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 и он не отображается.
Посмотрим на пример:
Есть два варианта решения такой проблемы:
- нужно установить ширину для тега
<hr>
, - избегать использования FlexBox в подобных случаях.
Итак, FlexBox отличный и мощный инструмент, возможно, это лучшее, что случилось в CSS за долгое время. Тем не менее, он должен применяться только в тех случаях, когда действительно необходим. Необдуманное использование flex-модели, как мы убедились, приводит к неожиданным результатам.
Спасибо за внимание.
По материалам статьи Alvaro Motoro “The Disappearing Line (a CSS Mystery)”.