It's because of the white-space:nowrap
.
Without you will have this which is an expected result:
div {
position: absolute;
left: 0;
top: 0;
bottom: 0;
width: 200px;
background: #f0f0f0;
}
span {
display: inline-block;
white-space: normal;
vertical-align: top;
}
label {
margin-top: 10px;
/*white-space: nowrap;*/
}
.label1 {
display: inline-block;
}
.label2 {
display: flex;
}
<div>
<label class=label1>
<input type=checkbox>
<span>
Here is a long description for the option that is set via the checkbox
on the left. The label is set to inline-block. For some reason,
it overflows the containing div. But why?
</span>
</label>
</div>
Note how the inline-block
has its width equal to the container because there a lot of text and it will break so it's like having a width:100%
. Then if you add white-space:nowrap
you will simply disable the wrap and move that inline-block
upper by keeping its width and you will create the overflow1
div {
position: absolute;
left: 0;
top: 0;
bottom: 0;
width: 200px;
background: #f0f0f0;
}
span {
display: inline-block;
white-space: normal;
vertical-align: top;
}
label {
margin-top: 10px;
white-space: nowrap;
}
.label1 {
display: inline-block;
}
.label2 {
display: flex;
}
<div>
<label class=label1>
<input type=checkbox>
<span>
Here is a long description for the option that is set via the checkbox
on the left. The label is set to inline-block. For some reason,
it overflows the containing div. But why?
</span>
</label>
</div>
For the flexbox it's different because the wrap is controlled by flex-wrap
that is by default nowrap
. Notice that inline-block
inside flexbox container are usless because element will be blockified when they become flex items.
Enable the wrap and you will have a similar behavior to the first example:
div {
position: absolute;
left: 0;
top: 0;
bottom: 0;
width: 200px;
background: #f0f0f0;
}
span {
display: inline-block;
white-space: normal;
vertical-align: top;
}
label {
margin-top: 10px;
/*white-space: nowrap;*/
}
.label1 {
display: inline-block;
}
.label2 {
display: flex;
flex-wrap:wrap;
}
<div>
<label class=label1>
<input type=checkbox>
<span>
Here is a long description for the option that is set via the checkbox
on the left. The label is set to inline-block. For some reason,
it overflows the containing div. But why?
</span>
</label>
<label class=label2>
<input type=checkbox>
<span>
Here is a long description for the option that is set via the checkbox
on the left. The label is set to flex. For some reason,
it does not overflow the containing div. But why not?
</span>
</label>
</div>
Now add back the nowrap of the white-space:
div {
position: absolute;
left: 0;
top: 0;
bottom: 0;
width: 200px;
background: #f0f0f0;
}
span {
display: inline-block;
white-space: normal;
vertical-align: top;
}
label {
margin-top: 10px;
white-space: nowrap;
}
.label1 {
display: inline-block;
}
.label2 {
display: flex;
flex-wrap:wrap;
}
<div>
<label class=label1>
<input type=checkbox>
<span>
Here is a long description for the option that is set via the checkbox
on the left. The label is set to inline-block. For some reason,
it overflows the containing div. But why?
</span>
</label>
<label class=label2>
<input type=checkbox>
<span>
Here is a long description for the option that is set via the checkbox
on the left. The label is set to flex. For some reason,
it does not overflow the containing div. But why not?
</span>
</label>
</div>
Nothing will happen with the flexbox because we no more deal with text and inline element but it's about flex items thus the white-space has no effect there since they are block element and as stated above the wrapping is controlled by flex-wrap
.
Another thing to note is that flex items will by default always shrink to fit their parent container which also explain why there is no overlow even if you set an explicit width:
div {
position: absolute;
left: 0;
top: 0;
bottom: 0;
width: 200px;
background: #f0f0f0;
}
span {
display: inline-block;
white-space: normal;
vertical-align: top;
}
label {
margin-top: 10px;
white-space: nowrap;
}
.label1 {
display: inline-block;
}
.label2 {
display: flex;
}
<div>
<label class=label1>
<input type=checkbox>
<span>
Here is a long description for the option that is set via the checkbox
on the left. The label is set to inline-block. For some reason,
it overflows the containing div. But why?
</span>
</label>
<label class=label2>
<input type=checkbox>
<span style="width:200px;">
Here is a long description for the option that is set via the checkbox
on the left. The label is set to flex. For some reason,
it does not overflow the containing div. But why not?
</span>
</label>
</div>
But if you disable the shrink
you can have an overflow:
div {
position: absolute;
left: 0;
top: 0;
bottom: 0;
width: 200px;
background: #f0f0f0;
}
span {
display: inline-block;
white-space: normal;
vertical-align: top;
}
label {
margin-top: 10px;
white-space: nowrap;
}
.label1 {
display: inline-block;
}
.label2 {
display: flex;
}
<div>
<label class=label1>
<input type=checkbox>
<span>
Here is a long description for the option that is set via the checkbox
on the left. The label is set to inline-block. For some reason,
it overflows the containing div. But why?
</span>
</label>
<label class=label2>
<input type=checkbox>
<span style="width:200px;flex-shrink:0">
Here is a long description for the option that is set via the checkbox
on the left. The label is set to flex. For some reason,
it does not overflow the containing div. But why not?
</span>
</label>
</div>
And without explicit width you will have this:
div {
position: absolute;
left: 0;
top: 0;
bottom: 0;
width: 200px;
background: #f0f0f0;
}
span {
display: inline-block;
white-space: normal;
vertical-align: top;
}
label {
margin-top: 10px;
white-space: nowrap;
}
.label1 {
display: inline-block;
}
.label2 {
display: flex;
}
<div>
<label class=label1>
<input type=checkbox>
<span>
Here is a long description for the option that is set via the checkbox
on the left. The label is set to inline-block. For some reason,
it overflows the containing div. But why?
</span>
</label>
<label class=label2>
<input type=checkbox>
<span style="flex-shrink:0">
Here is a long description for the option that is set via the checkbox
on the left. The label is set to flex. For some reason,
it does not overflow the containing div. But why not?
</span>
</label>
</div>
1 here is another example to illustrate the effect of the white-space:nowrap
and how it doesn't change the width of element calculated before:
.box {
width:200px;
border:2px solid red;
}
.box span {
border:2px solid green;
white-space:normal;
display:inline-block;
vertical-align:top;
}
<div class="box">
<span>lorem ipsume</span>
<span> lorem ipsume lorem ipsume lorem ipsume lorem ipsume lorem ipsume lorem ipsume lorem ipsume lorem ipsume lorem ipsume</span>
<span> lorem ipsume lorem ipsume lorem ipsume lorem ipsume lorem ipsume lorem ipsume lorem ipsume lorem ipsume lorem ipsume</span>
</div>
<div class="box" style="white-space:nowrap">
<span>lorem ipsume</span>
<span> lorem ipsume lorem ipsume lorem ipsume lorem ipsume lorem ipsume lorem ipsume lorem ipsume lorem ipsume lorem ipsume</span>
<span> lorem ipsume lorem ipsume lorem ipsume lorem ipsume lorem ipsume lorem ipsume lorem ipsume lorem ipsume lorem ipsume</span>
</div>