In HTML, an element is in flow or out of flow.
float: right
can be used to take elements out of flow.
In-flow and out-of-flow elements can be combined, i.e. some elements can be in flow while others float out of flow next to them.
A flexbox (particularly with flex: auto
) can be used to automatically nicely adjust the size of in-flow elements.
But using a flexbox to slightly adjust in-flow elements completely breaks out-of-flow elements: The float: right
element stops floating right, and stops spanning several rows:
.container {
display: flex;
flex-wrap: wrap;
align-items: stretch;
}
.container span {
flex: auto;
background-color: gray;
}
.container .float {
float: right;
background-color: yellow;
}
* {
border: 1px solid black;
margin: 1px;
padding: 1px;
}
<div class="container">flexbox
<span class="float">multiline<br>float</span>
<span>element with much content</span>
<span>element with much content</span>
<span>element with much content</span>
<span>element with much content</span>
<span>element with much content</span>
<span>element with much content</span>
<span>element with much content</span>
<span>element with much content</span>
<span>element with much content</span>
<span>element with much content</span>
</div>
How can a layout be achieved where some elements have automatically adjusted sizes (like they would with flex: auto
) while other large elements float and span several rows? Ideally, it shouldn’t be too hacky (such as painting on a <canvas>
).
1
I’d like to know whether there are better solutions, but here’s my current solution:
That layout can be achieved by using text-align: justify
instead of a flexbox.
To make the white gaps between the gray <span>
elements have the same width in all rows, I use tricks to avoid expansion caused by text-align: justify
.
(Before that trick, I had tried adding justify-self: stretch
to the children elements, but it has no effect if the parent <div>
has display: block
. I in turn tried all possible display
values for the parent <div>
, but none of them achieve the desired result.)
.container {
text-align: justify;
}
.container span {
white-space: nowrap;
background-color: gray;
}
.container .float {
float: right;
background-color: yellow;
}
* {
border: 1px solid black;
margin: 1px;
padding: 1px;
}
<div class="container">justified div
<span>span with suppressed line breaks</span> <span>span with suppressed line breaks</span> <span>span with suppressed line breaks</span> <span>span with suppressed line breaks</span> <span>span with suppressed line breaks</span> <span class="float">multiline<br>float</span><span>span with suppressed line breaks</span> <span>span with suppressed line breaks</span> <span>span with suppressed line breaks</span> <span>span with suppressed line breaks</span> <span>span with suppressed line breaks</span> <span>span with suppressed line breaks</span> <span>span with suppressed line breaks</span> <span>span with suppressed line breaks</span> <span>span with suppressed line breaks</span> <span>span with suppressed line breaks</span> <span>no line breaks</span> <span>no line breaks</span> <span>no line breaks</span> <span>no line breaks</span> <span>no line breaks</span> <span>foo</span> <span>foo</span> <span>foo</span> <span>foo</span> <span>foo</span> <span>foo</span> <span>foo</span> <span>foo</span> <span>foo</span> <span>foo</span> <span>foo</span> <span>foo</span> <span>foo</span> <span>foo</span> <span>foo</span> <span>foo</span> <span>span with suppressed line breaks</span> <span>span with suppressed line breaks</span> <span>span with suppressed line breaks</span> <span>span with suppressed line breaks</span> <span>span with suppressed line breaks</span>
</div>
user-select: none
can prevent selection of the
characters, but then those characters should be wrapped inside own <span>
s with user-select: none
(with an additional convenience of setting their width) because it seems that setting user-select: none
for the parent can’t be overriden by other children.
To avoid the stretched spaces, I’m thinking about adding a space character in the beginning and end of each gray <span>
so that that character would do all the stretching; and wrapping the text in some tag with some CSS that would prevent the stretching or applying the same tricks to the intermediate spaces.