You mainly have two issues:
- You are setting
width:100%
to the wrapper and this doesn't account for margin so you will logically have overflow and since the body is a flex container with justify-content:center
the margin will overflow equally from both sides that's why you think it's not applied.
- You are facing the
min-width
constraint of flexbox which is forcing you to set width:100%
thinking it's the good solution. This same constraint is also preventing the element from shrinking lower than the 100% you specified (related: Why is a flex item limited to parent size?)
To fix this you need to remove width:100%
from wrapper and consider min-width:0
instead. You can also remove the min-width
applied to .L
and you need to consider flex-shrink:0
on .R
(or replace its width by min-width
)
body {
background-color: #000;
color: #FFF;
display: flex;
justify-content: center;
}
.wrapper {
margin: 0 1.5rem;
max-width: 40rem;
min-width:0;
}
.fit_content_box {
display: flex;
align-items: center;
}
.L {
overflow: hidden;
white-space: nowrap;
text-overflow: ellipsis;
}
.R {
margin-left: 1rem;
flex-shrink:0;
height: 1rem;
width: 1rem;
background-color: #FFF;
}
.overflow {
display: flex;
justify-content: space-between;
}
.overflow>div {
width: 0;
display: flex;
justify-content: center;
}
<body>
<div class="wrapper">
<div class="fit_content_box">
<p class="L">Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure
dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.</p>
<div class="R"></div>
</div>
<div class="overflow">
<div>
<p>0</p>
</div>
<div>
<p>12</p>
</div>
<div>
<p>24</p>
</div>
</div>
</div>
</body>
If you want the element to remain at least equal to max-width
when there is a small amount of text add flex-grow:1
:
body {
background-color: #000;
color: #FFF;
display: flex;
justify-content: center;
}
.wrapper {
margin: 0 1.5rem;
max-width: 40rem;
min-width:0;
flex-grow:1;
}
.fit_content_box {
display: flex;
align-items: center;
}
.L {
flex-grow:1;
overflow: hidden;
white-space: nowrap;
text-overflow: ellipsis;
}
.R {
margin-left: 1rem;
flex-shrink:0;
height: 1rem;
width: 1rem;
background-color: #FFF;
}
.overflow {
display: flex;
justify-content: space-between;
}
.overflow>div {
width: 0;
display: flex;
justify-content: center;
}
<body>
<div class="wrapper">
<div class="fit_content_box">
<p class="L">Lorem ipsum dolor sit e dolor sit e</p>
<div class="R"></div>
</div>
<div class="overflow">
<div>
<p>0</p>
</div>
<div>
<p>12</p>
</div>
<div>
<p>24</p>
</div>
</div>
</div>
</body>
To better illustrate the (1) here is another example with overflowing margin that you can hardly notice:
.container {
width:200px;
margin:auto;
display:flex;
justify-content:center;
}
.box {
height:50px;
width:100%;
background:red;
}
<div class="container">
<div class="box" style="margin:0 5966px">a_long_text_to_avoid_the_shrink</div>
</div>
<div class="container">
<div class="box">a_long_text_to_avoid_the_shrink</div>
</div>
You can see that we have a long text forcing our element to not shrink (the min-width constraint), the element is taking full width and we are centring the content. This will make the margin overflowing like if there is no margin.
If you break one rule then you will see the effect of the margin.
Remove the long text:
.container {
width:200px;
margin:auto;
display:flex;
justify-content:center;
}
.box {
width:100%;
height:50px;
background:red;
}
<div class="container">
<div class="box" style="margin:0 5966px">a long text to avoid the shrink</div>
</div>
<div class="container">
<div class="box">a long text to avoid the shrink</div>
</div>
Remove the centring:
.container {
width:200px;
margin:auto;
display:flex;
}
.box {
width:100%;
height:50px;
background:red;
}
<div class="container">
<div class="box" style="margin:0 5966px">a_long_text_to_avoid_the_shrink</div>
</div>
<div class="container">
<div class="box">a_long_text_to_avoid_the_shrink</div>
</div>
Make a different margin on each side
.container {
width:200px;
margin:auto;
display:flex;
justify-content:center;
}
.box {
width:100%;
height:50px;
background:red;
}
<div class="container">
<div class="box" style="margin:0 500px 0 400px">a_long_text_to_avoid_the_shrink</div>
</div>
<div class="container">
<div class="box">a_long_text_to_avoid_the_shrink</div>
</div>
(2) The white-space
is creating the min-width contraint preventing the element from shrinking.
Here is an exmaple to illustrate:
.body {
display: flex;
justify-content: center;
margin: 10px 100px;
border: 2px solid red;
}
.wrapper {
border: 1px solid;
margin: 0 20px;
}
.box {
display:flex;
}
The below is a logical behavior where the text will wrap and the margin are respected
<div class="body">
<div class="wrapper">
<div class="box">
<div>some long text here some long text here some long text here some long text here</div>
</div>
</div>
</div>
Let's add white-space:nowrap. We add a min-width contraint since we said to the text to never wrap thus our flex element will not shrink and overflow.
<div class="body">
<div class="wrapper">
<div class="box">
<div style="white-space:nowrap">some long text here some long text here some long text here some long text here</div>
</div>
</div>
</div>
If we add width:100% we force its width to be the same as the container BUT the margin aren't included and are kept outside (the text will logically overflow)
<div class="body">
<div class="wrapper" style="width:100%">
<div class="box">
<div style="white-space:nowrap">some long text here some long text here some long text here some long text here</div>
</div>
</div>
</div>
Now if we add min-width:0 we remove the constaint of minimum sizing and we can see the margin again even if we keep width:100% because the element will shrink by default
<div class="body">
<div class="wrapper" style="width:100%;min-width:0">
<div class="box">
<div style="white-space:nowrap">some long text here some long text here some long text here some long text here</div>
</div>
</div>
</div>
The trick is that we are centring the element and applying the same margin on both side which will create the illusion of a collapsing margin but it's a simple overflow of the margin from both sides equally.
Let's change the margin slightly on one side to see a little offset to the other side:
.body {
display: flex;
justify-content: center;
margin: 10px 100px;
border: 2px solid red;
}
.wrapper {
border: 1px solid;
margin: 0 20px 0 40px;
}
.box {
display:flex;
}
The below is a logical behavior where the text will wrap and the margin are respected
<div class="body">
<div class="wrapper">
<div class="box">
<div>some long text here some long text here some long text here some long text here</div>
</div>
</div>
</div>
Let's add white-space:nowrap. We add a min-width contraint since we said to the text to never wrap thus our flex element will not shrink and overflow.
<div class="body">
<div class="wrapper">
<div class="box">
<div style="white-space:nowrap">some long text here some long text here some long text here some long text here</div>
</div>
</div>
</div>
If we add width:100% we force its width to be the same as the container BUT the margin aren't included and are kept outside (the text will logically overflow)
<div class="body">
<div class="wrapper" style="width:100%">
<div class="box">
<div style="white-space:nowrap">some long text here some long text here some long text here some long text here</div>
</div>
</div>
</div>
Now if we add min-width:0 we remove the constaint of minimum sizing and we can see the margin again even if we keep width:100% because the element will shrink by default
<div class="body">
<div class="wrapper" style="width:100%;min-width:0">
<div class="box">
<div style="white-space:nowrap">some long text here some long text here some long text here some long text here</div>
</div>
</div>
</div>