Avoid line wrapping unless necessary, while allowing immediate text flow following last line of wrapped element

34 Views Asked by At

This is basically a more strict follow-up to Avoiding line wrapping unless necessary with CSS.

I have a very similar goal as in the previous question:

  1. Keep words in a <span> together - prefer to break before the <span>.
  2. If the <span> is so long that it passes the width of its container, allow a line break inside that <span>.
  3. If the <span> is short enough that it ends on the same line it starts on, keep the words before the <span> together with the span, as well as the words after it.

However, I have one extra requirement:

  1. If the <span> is so long that there has to be a wrap inside it, the following text content must immediately follow the last character of the <span>.

The answer for the previous question uses display: inline-block to ensure the span's words stay together unless they have to break. It gets far enough to satisfy the three points above, but it fails on the last one, because - by nature of inline-block - the span now occupies the full space up to its rightmost edge... even if that rightmost edge was only hit on a previous line!

See the demo below:

p {
  max-width: 180px;
  background: #fee;
  border: 3px solid red;
  padding: 8px;
}

span:nth-of-type(1) {
  display: inline-block;
  background: yellow;
}

span:nth-of-type(2) {
  display: inline-block;
  background: cyan;
}
<p>Hello, world. This is <span>a nice long paragraph</span>, and I'm interested in <span>armadillos, aqueducts, chlorophyll and choreography</span>. Do some of these interest you?</p>

Note how the period following the (second, cyan) <span> gets pushed down to the line beneath the span, because even though the last line of the span ends well before the wrapping point, the <span> itself is just as wide as the whole line. Both of these spans are styled with display: inline-block, but only the shorter one fits neatly with the following text.

I'm not aware of any combination of properties that would get text to flow nicely after a wrap inserted in a span whose words are otherwise kept together. It seems line inline-block is just not going to work, but I don't know where else to look.

1

There are 1 best solutions below

0
Nebula On

Here is a rather rough solution which nests inline-block elements deeper and deeper, so that the "following" content is really contained inside its parent span. (Styling or behavior is differentiated with <u> or another tag instead.)

p {
  max-width: 180px;
  background: #fee;
  border: 3px solid red;
  padding: 8px;
}

span {
  background: #4444;
  display: inline-block;
}

p > span > u {
  background: yellow;
}

p > span > span > u {
  background: cyan;
}
<p>Hello, world. This is <span><u>a nice long paragraph</u>, and I'm interested in <span><u>armadillos, aqueducts, chlorophyll and choreography</u>. Do some of these interest you?</span></p>

The <span>s above are transparent grey, so that the "darker" one shows it's nested deeper. The HTML basically has this structure:

<p>
  Blah blah blah...
  <span style="display: inline-block">
    <u>Some styled text which should stick together, unless a break is necessary</u>
    More content, la dee da
    <span style="display: inline-block">
      <u>More styled text sticking together</u>
      More content.
    </span>
  </span>
</p>

This works(!), but from an authorship or HTML generation standpoint (e.g. transforming from Markdown or some other source text), it's hardly tenable.

I'd love to find an alternate solution which doesn't depend so heavily on mangling the markup into an unnaturally nested form.