I\'m trying to get an element to have items aligned to the right, and all overflowing elements to be hidden but accessed by scrollbar.
But it seems like the scrollba
The main problem is that you're dealing with a contradiction:
The justify-content property is designed to distribute extra space in the container.
However, an overflow condition occurs when there is no space left in the container.
Basically, justify-content
and overflow
have no association. The former applies only inside the container. The latter applies only outside the container.
With justify-content: flex-end
, the flex items must be packed at the end of the container (not the end of the flex-start
overflow area).
If the end-aligned items are too big to fit in the container, they will overflow on the start side, which is what you're seeing in your layout. But because the overflow
property only applies in the direction of the writing mode (LTR, in this case), scrollbars are not rendered (more details).
So I would suggest forgetting about justify-content
to make this layout work.
Instead, consider this: Use an invisible spacer item to push your content items to the right.
.row {
display: flex;
overflow: auto;
max-width: 500px;
background: #DADADA;
}
.box {
flex: 0 0 200px;
height: 40px;
margin: 4px 10px;
background: red;
}
.row::before {
content: "";
flex: 0 0 400px;
visibility: hidden;
}
<div class="row">
<div class="box"></div>
<div class="box"></div>
<div class="box"></div>
<div class="box"></div>
<div class="box"></div>
<div class="box"></div>
</div>
You'll notice that the last item margin collapses. That issue is explained here:
Here's how I would recommend you do it
.row {
width: 100%;
max-width: 500px;
background: #DADADA;
flex: 1;
display: flex;
overflow: auto;
}
.box {
display: flex;
width: 200px;
height: 40px;
margin: 4px 10px;
background: red;
flex-shrink: 0;
}
<div class="row">
<div class="box"></div>
<div class="box"></div>
<div class="box"></div>
<div class="box"></div>
<div class="box"></div>
<div class="box"></div>
</div>
When an overflow occur to the left (or top), a scroll doesn't get rendered, and the reason is that a HTML document's normal flow is left-to-right (top-to-bottom).
Flexbox has a row-reverse direction, which will solve that, thought 2 things comes with that:
One need to reorder the items or use an inner wrapper
I.a. Firefox and Edge doesn't show the scroll (possible bug)
Stack snippet
.row {
width: 100%;
max-width: 500px;
background: #DADADA;
display: flex;
flex-direction: row-reverse;
overflow: auto;
}
.box {
width: 200px;
height: 40px;
margin: 4px 10px;
background: red;
flex-shrink: 0;
}
/* no wrapper */
.row > .box:nth-child(1) { order: 6; }
.row > .box:nth-child(2) { order: 5; }
.row > .box:nth-child(3) { order: 4; }
.row > .box:nth-child(4) { order: 3; }
.row > .box:nth-child(5) { order: 2; }
.row > .box:nth-child(6) { order: 1; }
/* wrapper */
.inner {
display: flex;
}
<div class="row">
<div class="box">1</div>
<div class="box">2</div>
<div class="box">3</div>
<div class="box">4</div>
<div class="box">5</div>
<div class="box">6</div>
</div>
<div><br><br></div>
<div class="row">
<div class="inner">
<div class="box">1</div>
<div class="box">2</div>
<div class="box">3</div>
<div class="box">4</div>
<div class="box">5</div>
<div class="box">6</div>
</div>
</div>
Possible workarounds are:
direction: rtl
to change the flow direction.row {
width: 100%;
max-width: 500px;
background: #DADADA;
display: flex;
overflow: auto;
direction: rtl;
}
.inner {
display: flex;
direction: ltr;
}
.box {
width: 200px;
height: 40px;
margin: 4px 10px;
background: red;
flex-shrink: 0;
}
<div class="row">
<div class="inner">
<div class="box">1</div>
<div class="box">2</div>
<div class="box">3</div>
<div class="box">4</div>
<div class="box">5</div>
<div class="box">6</div>
</div>
</div>
transform
to flip the row
element.row {
width: 100%;
max-width: 500px;
background: #DADADA;
display: flex;
overflow: auto;
transform: scale(-1,1); /* flip horizontally */
}
.inner {
display: flex;
transform: scale(-1,1); /* reset so items is not backwards */
}
.box {
width: 200px;
height: 40px;
margin: 4px 10px;
background: red;
flex-shrink: 0;
}
<div class="row">
<div class="inner">
<div class="box">1</div>
<div class="box">2</div>
<div class="box">3</div>
<div class="box">4</div>
<div class="box">5</div>
<div class="box">6</div>
</div>
</div>
window.addEventListener("load", function(e) {
var el = document.querySelector(".row");
el.scrollLeft = el.scrollWidth;
});
.row {
width: 100%;
max-width: 500px;
background: #DADADA;
display: flex;
overflow: auto;
}
.box {
width: 200px;
height: 40px;
margin: 4px 10px;
background: red;
flex-shrink: 0;
}
<div class="row">
<div class="box">1</div>
<div class="box">2</div>
<div class="box">3</div>
<div class="box">4</div>
<div class="box">5</div>
<div class="box">6</div>
</div>