Home > Mobile >  Why do consecutive spans overflow their line box?
Why do consecutive spans overflow their line box?

Time:12-10

Alternative title: Please help me understand the CSS visual formatting model.

I'm reading the W3C Editor's Draft for CSS2.

From section 9.2.2., with my emphasis,

Inline-level elements are those elements of the source document that do not form new blocks of content; the content is distributed in lines [...]. The following values of the display property make an element inline-level: inline, inline-table, and inline-block.

Inline-level elements generate inline-level boxes, which are boxes that participate in an inline formatting context.

So the following span elements should generate inline-level boxes.

<span>Hello.</span><span>Hallo.</span><span>Hello.</span><span>Hallo.</span><span>Hello.</span>

But to be safe we can make that explicit.

span {
  display: inline;
}

Then, from section 9.4.2,

When several inline-level boxes cannot fit horizontally within a single line box, they are distributed among two or more vertically-stacked line boxes. Thus, a paragraph is a vertical stack of line boxes.

But if you resize the document containing the spans, they don't wrap, i.e., they're not distributed among two or more line boxes. Changing their display property to inline-block fixes the problem, even though inline-block elements generate inline-level boxes.

From section 9.2.2.,

Inline-level boxes that are not inline boxes (such as replaced inline-level elements, inline-block elements, and inline-table elements) are called atomic inline-level boxes because they participate in their inline formatting context as a single opaque box.

Adding spaces between the spans also fixes the problem, but I'm not sure why. The wording of the normal value of the white-space property is not very specific.

Sequences of white space are collapsed. Newline characters in the source are handled the same as other white space. Lines are broken as necessary to fill line boxes.

When is it necessary to fill a line box?

CodePudding user response:

In addition to the other answers, there's a distinction here is between inline-level boxes (as used in the OP CSS 2 quote) and inline-level content as per Temani's CSS Text 3 quote.

When several inline-level boxes cannot fit horizontally within a single line box, they are distributed among two or more vertically-stacked line boxes. Thus, a paragraph is a vertical stack of line boxes.

What this doesn't explain is how the boxes are distributed. In particular, it doesn't describe the concept of fragmentation. That is, that non-atomic inline boxes can be fragmented into two or more parts, and those fragments placed in different lines.

CodePudding user response:

You need to consider line breaking to understand what is happening

When inline-level content is laid out into lines, it is broken across line boxes. Such a break is called a line break. When a line is broken due to explicit line-breaking controls (such as a preserved newline character), or due to the start or end of a block, it is a forced line break. When a line is broken due to content wrapping (i.e. when the UA creates unforced line breaks in order to fit the content within the measure), it is a soft wrap break. The process of breaking inline-level content into lines is called line breaking.

it's clear that you don't have any "forced line break" and no "soft wrap break" as well.

Wrapping is only performed at an allowed break point, called a soft wrap opportunity. When wrapping is enabled (see white-space), the UA must minimize the amount of content overflowing a line by wrapping the line at a soft wrap opportunity, if one exists.

white-space is only used to either allow or not the wrapping but not to force the wrapping. For this you need to consider other properties:

While CSS does not fully define where soft wrap opportunities occur, some controls are provided to distinguish common variations:

  • The line-break property ...
  • The word-break property ...
  • The hyphens property ...
  • The overflow-wrap ...

I won't dig into them but you can keep reading to understand how each one affect the wrapping

Examples:

.box {
  margin:5px;
  border:1px solid;
  width:150px;
}
<div >
 <span>Hello.</span><span>Hallo.</span><span>Hello.</span><span>Hallo.</span><span>Hello.</span>
</div>
<div  style="word-break:break-all">
 <span>Hello.</span><span>Hallo.</span><span>Hello.</span><span>Hallo.</span><span>Hello.</span>
</div>
<div  style="overflow-wrap:break-word">
 <span>Hello.</span><span>Hallo.</span><span>Hello.</span><span>Hallo.</span><span>Hello.</span>
</div>
<div  style="line-break: anywhere">
 <span>Hello.</span><span>Hallo.</span><span>Hello.</span><span>Hallo.</span><span>Hello.</span>
</div>

CodePudding user response:

Having a bunch of spans directly after one another is treating them all as the same "word". Since there are no places to break to a newline, it causes horizontal overflow.

When you put a bunch of spaces inbetween, there are now logical breakpoints that the browser can use to wrap.

If you change them to inline-block, then they are all treated as separate "words" so it can do a line-break anywhere before or after a span node.

Writing <span>Hello.</span><span>Hello.</span><span>Hello.</span> is effectively the same as writing Hello.Hello.Hello.

  •  Tags:  
  • css
  • Related