Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

"br" is not friendly with the flexbox?

Tags:

html

css

flexbox

I got a table using flexbox and noticed one interesting feature: the br element can not do anything inside the flexbox.

Example:

.flexbox {
  display: flex;
  flex-wrap: wrap;
  border: 2px solid red;
  padding: 2px;
}

.item {
  width: 50px;
  height: 50px;
  margin: 2px;
  border: 2px solid blue;
}

.new-row, br {
  display: block;
  width: 100%;
  height: 0px;
}
<p>Line break using div:</p>
<div class="flexbox">
  <div class="item"></div>
  <div class="item"></div>
  <div class="new-row"></div>
  <div class="item"></div>
  <div class="item"></div>
</div>

<p>Line break using br:</p>
<div class="flexbox">
  <div class="item"></div>
  <div class="item"></div>
  <br>
  <div class="item"></div>
  <div class="item"></div>
</div>

In the example, div and br share the same properties, but div transfers elements to the new line, and br does not.

Why?

like image 208
Yuri Avatar asked Jul 13 '17 17:07

Yuri


2 Answers

The implementation of the br element in CSS is very well known to be quite the mystery. Different browsers support a different set of properties on the element, to varying degrees of effect (although all of them do support setting display: none to remove it from the layout at least). CSS itself acknowledges this oddity as early as CSS1, having dedicated an entire subsection to it, and even now in CSS3 it's still severely underspecified.

This peculiarity involving flexbox is not new; it has been known since 2014. Basically, in current implementations br does not generate a principal box, but is instead treated as part of a contiguous run of text as described in section 4 of the Flexbox spec, generating an anonymous flex item that cannot be styled (because it's anonymous). This is similar to an orphaned display: table-cell element causing an anonymous table box to be created around it, except you can at least still style the display: table-cell element — in the case of the br element, the style properties you apply have no effect, and the anonymous flex item is laid out with the defaults.

In this case, since br itself is (mostly) empty and it is not being accompanied by any other bare text within the flex container, this results in an anonymous flex item with no dimensions, making it seem as though the br element has vanished completely.

Back in 2014 the CSSWG resolved this "mystery" not by changing the Flexbox spec, but simply to add a special definition for the br element to css-display-3 to account for the behavior seen here. But no such definition exists in the current version of that spec, nor the FPWD (which was published after the resolution!), nor the HTML spec, nor anywhere else. Nevertheless, the definition looks like this in terms of the current css-display-3 spec (which does not define any new properties, just changes the definition of display):

br {
  content: '\A';
  display: contents;
  white-space: pre;
}

... which means that the br element doesn't generate a principal box, but simply an anonymous inline box containing a single newline.

Because this definition is still missing from css-display-3, I wouldn't immediately consider it canon just yet. Even so, the behavior seen here is extremely unlikely to change considering this is how the br element has been for so long.

like image 166
BoltClock Avatar answered Sep 30 '22 05:09

BoltClock


Unlike Chrome, you must add whitespace (&nbsp;) after a <br> in order for it to work in Firefox.

By doing so, you will have the same result in both browsers.

Conlusion:

Works only in Chrome: <br><br><br>
Works in both Chrome and Firefox: <br>&nbsp;<br>&nbsp;<br>&nbsp;

like image 44
David Bérubé Avatar answered Sep 30 '22 05:09

David Bérubé