Horizontal scroliing overflowing parent in flexbox - html

I am trying to create 2 column divs in which one of them is scrollable horizontally (no wrap), but it keeps overflowing his parent container. The problem is both divs are using flex to calculate their size.
Is there a way to prevent the overflowing except using a fixed width on one of them?
<div class="container">
<div class="small-container">
</div>
<div class="large-container">
<div class="horiz-container">
<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>
</div>
</div>
body {
margin: 0;
}
div {
box-sizing: border-box;
}
.container {
display: flex;
flex-direction: row;
background-color: grey;
width: 100vw;
height: 100vh;
box-sizing: border-box;
}
.small-container {
display: flex;
flex-direction: column;
flex: 0 0 200px;
background-color: salmon;
margin: 10px;
box-sizing: border-box;
}
.large-container {
display: flex;
flex-direction: column;
flex: 1 0 0;
background-color: lightBlue;
margin: 10px;
box-sizing: border-box;
}
.horiz-container {
display: flex;
flex-direction: row;
height: 200px;
background-color: purple;
flex-wrap: nowrap;
width: 100%;
}
.box {
width: 100px;
height: 100px;
background-color: red;
margin: 5px;
}
https://jsfiddle.net/0m6Lj2re/

The changes made are in classes .large-container, .horiz-container and .box
body {
margin: 0;
}
div {
box-sizing: border-box;
}
.container {
display: flex;
flex-direction: row;
background-color: grey;
width: 100vw;
height: 100vh;
box-sizing: border-box;
}
.small-container {
display: flex;
flex-direction: column;
flex: 0 0 200px;
background-color: salmon;
margin: 10px;
box-sizing: border-box;
}
.large-container {
background-color: lightBlue;
margin: 10px;
box-sizing: border-box;
overflow: hidden;
}
.horiz-container {
/*height: 200px;*/
background-color: purple;
width: 100%;
overflow: auto;
white-space: nowrap;
}
.box {
width: 100px;
height: 100px;
background-color: red;
margin: 5px;
display: inline-block;
}
<div class="container">
<div class="small-container">
</div>
<div class="large-container">
<div class="horiz-container">
<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>
</div>
</div>

Related

How to make nested flex child scrollable

I have a list of messages (which is a flex child) in a container with unknown height and want to make them scrollable. But I cannot find a proper combination of flex-grow: 1, min-height: 0 and other flex tricks to make it working - message list is still bigger than its parent.
When I add overflow-y: auto to its parent - it works but this parent besides messages list includes some content which should not scroll.
Here's my example for this case: https://jsfiddle.net/ecbtrn58/2/
<div class="page">
<div class="messages-section">
<div class="header">Your messages</div>
<div class="content">
<img src="https://http.cat/100" width="70" height="50"/>
<div class="messages-list">
<div class="message">Hi.</div>
<div class="message">Hello.</div>
<div class="message">Good morning.</div>
<div class="message">Yo!</div>
</div>
</div>
</div>
</div>
.page {
background-color: #ddd;
width: 300px;
height: 300px;
.messages-section {
display: flex;
flex-direction: column;
width: 50%;
height: 100%;
background-color: #ccc;
.header {
background: #bbb;
padding: 5px;
}
.content {
display: flex;
flex-direction: column;
align-items: center;
padding: 5px;
.messages-list {
display: flex;
flex-direction: column;
overflow-y: auto;
/* What to add here to make it scrollable? */
.message {
height: 50px;
margin: 10px;
padding: 10px;
background: #1dc497;
}
}
}
}
}
How can I make messages list to scroll?
You have to set the height of .content to 100% and make it scrollable:
.page {
background-color: #ddd;
width: 300px;
height: 300px;
}
.page .messages-section {
display: flex;
flex-direction: column;
width: 50%;
height: 100%;
background-color: #ccc;
}
.page .messages-section .header {
background: #bbb;
padding: 5px;
}
.page .messages-section .content {
display: flex;
flex-direction: column;
align-items: center;
padding: 5px;
height: 100%;
overflow-x: scroll;
}
.page .messages-section .content .messages-list {
display: flex;
flex-direction: column;
overflow-y: auto;
/* What to add here to make it scrollable? */
}
.page .messages-section .content .messages-list .message {
height: 50px;
margin: 10px;
padding: 10px;
background: #1dc497;
}
<div class="page">
<div class="messages-section">
<div class="header">Your messages</div>
<div class="content">
<img src="https://http.cat/100" width="70" height="50" />
<div class="messages-list">
<div class="message">Hi.</div>
<div class="message">Hello.</div>
<div class="message">Good morning.</div>
<div class="message">Yo!</div>
</div>
</div>
</div>
</div>

Prevent Flexbox from growing in size, truncate text [duplicate]

This question already has answers here:
Why don't flex items shrink past content size?
(5 answers)
Closed 3 years ago.
Hoping some one can help me, I'm trying to create a split view display, with the left half of the screen been full height and the right hand side been split into quarters.
In the Left column there will be rows of text split into columns, each column should have the content truncated if exceeds width of column, the same effect should be in the 4 quarters on the right hand side. Whatever I seem to do the quarters grow in width if the content overflows. here is my primitive code...
<!DOCTYPE html>
<html>
<head>
<title>"Active Work</title>
<style>
* {
box-sizing: border-box;
}
body {
display: flex;
min-height: 100vh;
flex-direction: row;
margin: 0;
}
.container {
width: 100%;
background: #D7E8D4;
display: flex;
min-height: 100vh;
flex-direction: row;
margin: 0;
}
.colLeft {
width: 50%;
background: blue;
min-height: 100vh;
}
.colRight {
width: 50%;
background: green;
min-height: 100vh;
display: flex;
flex-wrap: wrap;
justify-content: space-between;
}
.grid {
height: 50vh;
flex: 0 0 50%;
}
.rowFlex {
display: flex;
flex-direction: row;
line-height: 36px;
}
.btn1 {
padding: 5px;
background-color: #00796b;
border-radius: 5px;
max-height: 30px;
margin: 0px 5px;
}
.gridHeader {
width: 100%;
}
.truncate {
overflow: hidden;
white-space: nowrap;
flex-wrap: nowrap;
flex: 0 0 50%;
background-color: yellow;
text-overflow: ellipsis;
}
.spanDiv {
white-space: nowrap;
overflow: hidden;
text-overflow: ellipsis;
flex: 1;
}
</style>
</head>
<body>
<div class="container">
<div class="colLeft">
<div class="rowFlex">
<div>Some Text</div>
<div class="btn1">G1</div>
<div class="btn1">G2</div>
<div class="btn1">G3</div>
<div class="btn1">G4</div>
</div>
</div>
<div class="colRight">
<div class="grid" style="background-color:#ff8a80;">
<div class="rowFlex">
<div class="gridHeader">GROUP1</div>
</div>
<div class="rowFlex">
<div class="truncate">LCT-56477</div>
<div class="truncate"><span class="spanDiv">LCT-5647 cvvfvdfgdfgdfgdfgfdvhjghjghjghfvfvfv7-</span></div>
</div>
</div>
<div class="grid" style="background-color:#7b1fa2;">2</div>
<div class="grid" style="background-color:#64b5f6;">3</div>
<div class="grid" style="background-color:#80cbc4;">4</div>
</div>
</div>
</body>
</html>
Just add min-width:0 to your .grid class.
* {
box-sizing: border-box;
}
body {
display: flex;
min-height: 100vh;
flex-direction: row;
margin: 0;
}
.container {
width: 100%;
background: #D7E8D4;
display: flex;
min-height: 100vh;
flex-direction: row;
margin: 0;
}
.colLeft {
width: 50%;
background: blue;
min-height: 100vh;
}
.colRight {
width: 50%;
background: green;
min-height: 100vh;
display: flex;
flex-wrap: wrap;
justify-content: space-between;
}
.grid {
height: 50vh;
flex: 0 0 50%;
min-width: 0;
}
.rowFlex {
display: flex;
flex-direction: row;
line-height: 36px;
}
.btn1 {
padding: 5px;
background-color: #00796b;
border-radius: 5px;
max-height: 30px;
margin: 0px 5px;
}
.gridHeader {
width: 100%;
}
.truncate {
overflow: hidden;
white-space: nowrap;
flex-wrap: nowrap;
flex: 0 0 50%;
background-color: yellow;
text-overflow: ellipsis;
}
.spanDiv {
white-space: nowrap;
overflow: hidden;
text-overflow: ellipsis;
flex: 1;
}
<div class="container">
<div class="colLeft">
<div class="rowFlex">
<div>Some Text</div>
<div class="btn1">G1</div>
<div class="btn1">G2</div>
<div class="btn1">G3</div>
<div class="btn1">G4</div>
</div>
</div>
<div class="colRight">
<div class="grid" style="background-color:#ff8a80;">
<div class="rowFlex">
<div class="gridHeader">GROUP1</div>
</div>
<div class="rowFlex">
<div class="truncate">LCT-56477</div>
<div class="truncate"><span class="spanDiv">LCT-5647 cvvfvdfgdfgdfgdfgfdvhjghjghjghfvfvfv7-</span></div>
</div>
</div>
<div class="grid" style="background-color:#7b1fa2;">2</div>
<div class="grid" style="background-color:#64b5f6;">3</div>
<div class="grid" style="background-color:#80cbc4;">4</div>
</div>
</div>

Scroll in a deeply nested flex container - min-height not working

I have the following flex layout. I need overflow to occur in div.stretchy. I would like div.stretchy to reach the boundary of the page and then overflow it's content. Per this stackoverflow post, I have tried many combinations of min-height: 0 and overflow: hidden, but div.stretchy will not shrink.
body {
margin: 0;
}
.page-wrapper {
display: flex;
height: 100vh;
width: 100vw;
overflow: hidden;
}
.sidebar {
background: blue;
flex: 0 0 40px;
}
.main {
background: green;
display: flex;
flex-direction: column;
flex: 1;
min-width: 0;
}
.topbar {
display: flex;
flex: 0 0 40px;
background-color: red;
}
.content {
display: flex;
overflow: auto;
}
.row {
display: flex;
}
.column {
display: flex;
flex-direction: column;
}
.grow {
flex-grow: 1;
}
.card {
height: 300px;
border: solid 1px;
min-width: 600px;
}
.card .row {
justify-content: space-between;
}
.wrapper {
padding: 16px;
height: fit-content;
}
.stats {
padding: 8px;
background-color: pink;
}
.overflow-hidden {
overflow: hidden;
}
.body .column {
background-color: indigo;
}
.wide-content {
background-color: yellow;
height: 50px;
width: 800px;
}
.block {
flex: none;
width: 300px;
height: 200px;
&:nth-of-type(odd) {
background: darken(green, 10%);
}
}
<div class="page-wrapper">
<div class="sidebar">sidebar</div>
<div class="main">
<div class="topbar">topbar</div>
<div class="content">
<div class="wrapper">
<div class="card column grow">
<div class="stats row">
<span>12345</span>
<span>12345</span>
<span>12345</span>
</div>
<div class="body row grow">
<div class="column">
<span>Dynamic Width Content</span>
</div>
<div class="stretchy column grow overflow-hidden">
<div class="wide-content grow"></div>
</div>
<div class="column">
<span>Dynamic Width Content</span>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
This is a tough battle. The enemy is cunning, deceitful and ruthless. I say we launch a massive carpet bombing campaign, showering the whole area with min size overrides. That should clear out 80% of the problem. Then we send in the ground troops to finish the job :-)
* {
min-width: 0 !important;
min-height: 0 !important;
}
.page-wrapper {
display: flex;
height: 100vh;
/* width: 100vw; */
/* overflow: hidden; */
}
.sidebar {
background: cornflowerblue;
/* flex: 0 0 40px; */
flex: 0 0 100px; /* changed for demo purposes */
}
.main {
background: lightgreen;
display: flex;
flex-direction: column;
flex: 1;
}
.topbar {
display: flex;
flex: 0 0 40px;
background-color: orangered;
}
.content {
display: flex;
/* overflow: auto; */
flex: 1; /* added */
}
.row {
display: flex;
}
.column {
display: flex;
flex-direction: column;
}
.grow {
flex-grow: 1;
}
.card {
/* height: 300px; */
border: solid 1px;
min-width: 600px;
}
.stretchy {
overflow: auto;
}
.card .row {
justify-content: space-between;
}
.wrapper {
padding: 16px;
/* height: fit-content; */
display: flex; /* added */
}
.stats {
padding: 8px;
background-color: pink;
}
.overflow-hidden {
/* overflow: hidden; */
}
.body .column {
background-color: violet;
}
.wide-content {
background-color: yellow;
height: 50px;
width: 800px;
}
body {
margin: 0;
}
/*
.block {
flex: none;
width: 300px;
height: 200px;
&:nth-of-type(odd) {
background: darken(green, 10%);
}
}
*/
<div class="page-wrapper">
<div class="sidebar">sidebar</div>
<div class="main">
<div class="topbar">topbar</div>
<div class="content">
<div class="wrapper">
<div class="card column grow">
<div class="stats row">
<span>12345</span>
<span>12345</span>
<span>12345</span>
</div>
<div class="body row grow">
<div class="column">
<span>Dynamic Width Content</span>
</div>
<div class="stretchy column grow overflow-hidden">
<div class="wide-content grow">test<br>test<br>test<br>test<br>test<br>test<br>test<br>test<br>test<br>test<br>test<br>test<br>test<br>test<br>test<br>test<br>test<br>test<br>test<br>test<br>test<br>test<br>test<br>test<br>test<br>test<br>test<br>test<br>test<br>test<br>test<br>test<br>test<br>test<br>test<br>test<br>test<br>test<br>test<br>test<br>test<br>test<br>test<br>test<br>test<br>test<br>test<br>test<br>test<br></div>
</div>
<div class="column">
<span>Dynamic Width Content</span>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
jsFiddle demo

Flexbox: scrollable content with sticky footer

I want to make a box (flex-item in this case) which always stays in the middle of it's container. In that box, there is a header, footer and content section. If the size of the content grows too big in height, I want the content section to be scrollable. The header and footer should always be visible and the box should always stay in it's container.
Here is what I have been able to write:
HTML
<div class="flex-container">
<div class="flex-item">
<header>Header</header>
<div class="content">
A
<br>B
<br>C
<br>D
<br>E
<br>F
<br>G
<br>H
<br>I
<br>J
<br>K
</div>
<footer>Footer</footer>
</div>
</div>
CSS
body {
margin: 120px;
}
.flex-container {
display: flex;
width: 200px;
height: 200px; /* We can assume that the container's height is hardcoded in this example, but the end solution should work even if this value is changed*/
border: 1px solid black;
justify-content: center;
}
.flex-item {
box-sizing: border-box;
width: 150px;
border: 5px solid blue;
align-self: center;
background-color: red;
display: flex;
flex-flow: column;
max-height: 100%;
}
.content {
/* It should be possible to scroll this element when it get too big in height*/
background-color: grey;
flex: 1;
}
The code is hosted on JSFiddle: https://jsfiddle.net/9fduhpev/3/
To explain the same thing visually, here is the current situation:
Here is what I want:
Use overflow-y: auto;.
Read this: http://www.w3schools.com/cssref/css3_pr_overflow-y.asp
body {
margin: 120px;
}
.flex-container {
display: flex;
width: 200px;
height: 200px;
border: 1px solid black;
justify-content: center;
}
.flex-item {
box-sizing: border-box;
width: 150px;
border: 5px solid blue;
align-self: center;
background-color: red;
display: flex;
flex-flow: column;
max-height: 100%;
}
.content {
background-color: grey;
flex: 1;
overflow-y: auto;
}
<div class="flex-container">
<div class="flex-item">
<header>Header</header>
<div class="content">
A
<br>B
<br>C
<br>D
<br>E
<br>F
<br>G
<br>H
<br>I
<br>J
<br>K
<br>L
</div>
<footer>Footer</footer>
</div>
</div>
I suggest you give it overflow: auto. With that it will be scrollable when needed.
body {
margin: 20px;
}
.flex-container {
display: flex;
width: 200px;
height: 200px;
border: 1px solid black;
justify-content: center;
}
.flex-item {
box-sizing: border-box;
width: 150px;
border: 5px solid blue;
align-self: center;
background-color: red;
display: flex;
flex-flow: column;
max-height: 100%;
}
.content {
background-color: grey;
flex: 1;
overflow: auto;
}
<div class="flex-container">
<div class="flex-item">
<header>Header</header>
<div class="content">
A
<br>B
<br>C
<br>D
<br>E
<br>F
<br>G
<br>H
<br>I
<br>J
<br>K
<br>L
</div>
<footer>Footer</footer>
</div>
</div>
I would do something like this:
.content {
height: 100%;
overflow:auto;
background-color: grey;
flex: 1;
}
https://jsfiddle.net/9fduhpev/4/

Wrap element to new line/row using flexbox

I have trouble forcing an item into the next row in a flexbox layout.
How can I do something like the following image?
This is what I got so far:
#wrap {
display: flex;
width: 86vw;
height: auto;
box-sizing: border-box;
margin: 0 auto;
}
.item1,
.item2 {
width: 50%;
height: 24.5vw;
background: #4add69;
}
.item1 {
margin-right: 10px;
}
.item2 {
margin-left: 10px;
}
.item3 {
width: 60%;
height: 40vw;
background: #d56c6c;
}
<div id="wrap">
<div class="item1"></div>
<div class="item2"></div>
<div class="item3"></div>
</div>
Your code is fine but missing two things.
Use flex-wrap: wrap to
create a new row. Modify the width of the first two items to be
present in a single row.
For the last two items, you need to nest it inside a container and
then wrap them again.
Manipulate the dimension(width, height) and margin values to achieve the perfect/suitable layout.
JSfiddle Demo
* {
margin: 0;
padding: 0;
}
body {
background: #232323;
padding: 10px;
}
#wrap {
display: flex;
width: 86vw;
height: auto;
box-sizing: border-box;
margin: 0 auto;
flex-wrap: wrap;
background: #232323;
/* Added */
}
.item1,
.item2 {
width: 48%;
/* Modified */
height: 24.5vw;
background: #4add69;
margin-bottom: 10px;
}
.item1 {
margin-right: 10px;
}
.item2 {
margin-left: 10px;
}
.item3 {
width: 55%;
height: 40vw;
background: #d56c6c;
margin-right: 10px;
}
.nested-items {
display: flex;
width: 42%;
flex-wrap: wrap;
align-content: space-between;
}
.item4,
.item5 {
background: lightblue;
width: 100%;
height: 49%;
}
<div id="wrap">
<div class="item1"></div>
<div class="item2"></div>
<div class="item3"></div>
<div class="nested-items">
<div class="item4"></div>
<div class="item5"></div>
</div>
</div>
Essentially you need an extra wrapping div for the two 'small' elements like so:
* {
margin: 0;
padding: 0;
box-sizing: border-box;
}
.wrap {
width: 75%;
margin: 1em auto;
border: 1px solid green;
padding: .25em;
display: flex;
flex-wrap: wrap;
}
.wrap div {
border: 1px solid grey;
margin-bottom: 1px;
}
.box {
height: 80px;
background: lightblue;
flex: 0 0 50%;
}
.tall {
flex: 0 0 65%;
height: 160px;
}
.col {
flex: 0 0 35%;
display: flex;
flex-wrap: wrap;
}
.mini {
flex: 0 0 100%;
height: 80px;
background: pink;
}
<div class="wrap">
<div class="box"></div>
<div class="box"></div>
<div class="box tall"></div>
<div class="box col">
<div class="mini"></div>
<div class="mini"></div>
</div>
</div>
I've used a single overall element here with wrapping but the image suggests that this would be much simpler with actual rows and the extra wrapper mentioned before.
Codepen Demo of 2nd option with rows.