Chrome flexbox 100% height inside other 100% height flexbox overflows - html

I am trying to make a full height page using flexboxes, where the content also uses a flexbox. The page should look as follows example of what it should look like. The blue div is dynamic and could change in height and the red content should take up the remaining space of the content div. This works on both Firefox and IE, however on Chrome it overflows. Can somebody explain why it overflows on Chrome?
The HTML is as follows:
<body>
<div class="container">
<div class="navbar">Navbar</div>
<div class="content">
<div class="container">
<div class="fill"></div>
<div class="dynamic">Here is some dynamic content<br>Test</div>
</div>
</div>
</div>
</body>
And the CSS is:
body{
margin:0;
}
.container{
display: flex;
flex-direction: column;
width: 100%;
height: 100%;
}
.navbar{
background-color: #ccc;
flex: none;
}
.content{
background-color: #333;
flex: auto;
padding: 10px;
}
.dynamic{
background-color: #0066ff;
flex: none;
}
.fill{
flex: auto;
background-color: #ff0000;
}

Here is an updated snippet.
Use flex:1 for the container that needs to adjust the height automatically.
body {
margin: 0;
}
.container1 {
display: flex;
flex-direction: column;
width: 100%;
height: 100vh;
}
.navbar {
background-color: #ccc;
}
.content {
flex: 1;
background-color: #ff0000;
border: 10px solid #333;
border-bottom: none;
}
.dynamic {
background-color: #0066ff;
border: 10px solid #333;
border-top: none;
}
<body>
<div class="container1">
<div class="navbar">Navbar</div>
<div class="content">
</div>
<div class="dynamic">Here is some dynamic content
<br>Test</div>
</div>
</body>

Related

Flexbox keep wrapping point while increasing item width

First of all, here is a codepen with the issue I am trying to solve.
This is a simplified version of the problem I have on an actual project. My goal is to keep the grid in the same format with 5 columns and to be able to increase the width of these cells so the content is always visible, but also so that it doesn't wrap before the first row of 5 columns is displayed. Whenever I try to increase the width of the cells the grid wraps and I lose the structure I want.
So, basically, increase width of items, but prevent wrapping, is it possible? It is fine if the content overflows the flex container itself, the goal is to add overflow-x to this grid.
.flex-container {
border: 1px solid silver;
display: flex;
width: 50%;
}
.wrap {
flex-wrap: wrap;
}
.wrap div {
background: gold;
}
.flex-item {
width: 160px;
border-bottom: 1px solid black;
border-right: 1px solid black;
line-height: 100px;
color: black;
font-weight: bold;
font-size: 2em;
text-align: center;
}
<div class="flex-container wrap">
<div class="flex-item">11111111111111</div>
<div class="flex-item">22222222222222</div>
<div class="flex-item">33333333333333</div>
<div class="flex-item">44444444444444</div>
<div class="flex-item">55555555555555</div>
<div class="flex-item">66666666666666</div>
<div class="flex-item">77777777777777</div>
<div class="flex-item">88888888888888</div>
<div class="flex-item">99999999999999</div>
<div class="flex-item">00000000000000</div>
</div>
From the comments, it does look like grid is the option you need, it won't allow content to be wrapping and justify content will stick it on the side if shorter thant the width of the container.
here is the snippet with grid:
/* flex turned into grid */
.flex-container {
border: 1px solid silver;
display: grid;
grid-template-columns:repeat(5,auto);
justify-content:start;
overflow:auto;
width: 80%;
}
.wrap {
}
.wrap div {
background: gold;
}
.flex-item {
border-bottom: 1px solid black;
border-right: 1px solid black;
line-height: 100px;
color: black;
font-weight: bold;
font-size: 2em;
text-align: center;
}
<div class="flex-container wrap">
<div class="flex-item">11111111111111</div>
<div class="flex-item">22222222222222</div>
<div class="flex-item">33333333333333</div>
<div class="flex-item">44444444444444</div>
<div class="flex-item">55555555555555</div>
<div class="flex-item">66666666666666</div>
<div class="flex-item">77777777777777</div>
<div class="flex-item">88888888888888</div>
<div class="flex-item">99999999999999</div>
<div class="flex-item">00000000000000</div>
</div>
I think, if it is allowable, that css grid may be a better candidate for the layout you are proposing...
.grid-container {
border: 1px solid silver;
display: grid;
width: 50%;
grid-template-columns: 20% 20% 20% 20% 20%; /* hard set five columns and no more */
}
.grid-container div {
background: gold;
}
.grid-item {
/* width: 160px; */
border-bottom: 1px solid black;
border-right: 1px solid black;
line-height: 100px;
color: black;
font-weight: bold;
font-size: 2em;
text-align: center;
overflow-x: hidden; /* overflow-x to hide overflow as discussed in question */
}
<div class="grid-container">
<div class="grid-item">11111111111111</div>
<div class="grid-item">22222222222222</div>
<div class="grid-item">33333333333333</div>
<div class="grid-item">44444444444444</div>
<div class="grid-item">55555555555555</div>
<div class="grid-item">66666666666666</div>
<div class="grid-item">77777777777777</div>
<div class="grid-item">88888888888888</div>
<div class="grid-item">99999999999999</div>
<div class="grid-item">00000000000000</div>
</div>
.flex-container {
display: flex;
flex-wrap: wrap;
background-color:red;
}
.flex-container > div {
background-color: #f1f1f1;
width: 100px;
margin: 10px;
text-align: center;
line-height: 75px;
font-size: 30px;
word-wrap: break-word;
}
<!DOCTYPE html>
<html>
<head>
</head>
<body>
<div class="flex-container">
<div>11111111111111</div>
<div>22222222222222</div>
<div>33333333333333</div>
<div>44444444444444</div>
<div>55555555555555</div>
<div>66666666666666</div>
<div>77777777777777</div>
<div>88888888888888</div>
<div>99999999999999</div>
<div>00000000000000</div>
</div>
</body>

Make empty Div in Flex 100% Height

Using the following my .divider <div> is not showing. I guess this is because it is empty. If I add a "." in there, then I see it. Is it possible to make it 100% the height of the .wrapper without adding content?
.wrapper {
display: flex;
background-color: orange;
}
.left {
background-color: gray;
}
.divider {
background-color: green;
cursor: ew-resize;
width: 12px;
height: 100%;
}
.right {
flex-grow: 1;
background-color: yellow;
}
<div class="wrapper">
<div class="left">Left</div>
<div class="divider"></div>
<div class="right">Right</div>
</div>
https://jsfiddle.net/sub7fxk5/
Remove height: 100%; for .divider
.wrapper {
display: flex;
background-color: orange;
}
.left {
background-color: gray;
}
.divider {
background-color: green;
cursor: ew-resize;
width: 12px;
/* height: 100%; */
}
.right {
flex-grow: 1;
background-color: yellow;
}
<div class="wrapper">
<div class="left">Left</div>
<div class="divider"></div>
<div class="right">Right</div>
</div>
Removing the height and adding flex: 1 seems to help.
Is the result of the code below what you expect it to be?
The wrapper has no height, that means that setting a height to 100% would equal setting the height to 0.
the flex: 1 makes the item flexible even though it has no content and it shows.
Of course you can set a width too. So width: 12px would work. As would width: 100%; (which would push the left and right item to the other side)
You might also use a pseudo-element ::after as a divider. That would clean up your html a bit.
.wrapper {
display: flex;
background-color: orange;
}
.left {
background-color: gray;
}
.divider {
background-color: green;
cursor: ew-resize;
flex: 1;
}
.right {
flex-grow: 1;
background-color: yellow;
}
<div class="wrapper">
<div class="left">Left<br/><br/>Left</div>
<div class="divider"></div>
<div class="right">Right</div>
</div>

Problem with flexbox layout and nested scrollbar

Embedded scroll bars do not work within a simple flexbox container. The browser automatically displays the horizontal scroll bar.
What am I doing wrong on this simple example?
When I remove "display: flex;" on the flexContainer, the embedded scrollbar works. Of course, my entire layout is then destroyed.
I only found the following, but the solution relates to a vertical scrollbar and does not work here:
Stackoverflow nesting-flexbox-inside-flexbox-overflow-how-to-fix-this
.flexContainer {
display: flex;
}
.sidebar {
flex: 1 0 auto;
min-width: 150px;
max-width: 190px;
color: white;
background: blue;
}
.content {
flex: 1 0 auto;
background: green;
}
.scrollableElement {
display: flex;
overflow-x: scroll;
}
.textElement {
color: white;
background: grey;
}
<html>
<body>
<div class="flexContainer">
<div class="sidebar">
<div>Sidebar</div>
</div>
<div class="content">
<div class="scrollableElement">
<div class="textElement">
<div>Content11111111111111111111111111111111111111111111111111111111111111111111111</div>
<div>Content22222222222222222222222222222222222222222222222222222222222222222222222</div>
<div>Content33333333333333333333333333333333333333333333333333333333333333333333333</div>
<div>Content44444444444444444444444444444444444444444444444444444444444444444444444</div>
<div>Content55555555555555555555555555555555555555555555555555555555555555555555555</div>
<div>Content66666666666666666666666666666666666666666666666666666666666666666666666</div>
<div>Content77777777777777777777777777777777777777777777777777777777777777777777777</div>
<div>Content88888888888888888888888888888888888888888888888888888888888888888888888</div>
</div>
</div>
</div>
</div>
</body>
</html>
You need to allow .content to shrink then add min-width:0 or overflow:hidden so its size is calculated at screen inside its parent so overflow works on the children:
.content {
flex: 1 1 auto;/* updated*/
background: green;
min-width:0;/* added */
}
.flexContainer {
display: flex;
}
.sidebar {
flex: 1 0 auto;
min-width: 150px;
max-width: 190px;
color: white;
background: blue;
}
.content {
flex: 1 1 auto;
background: green;
min-width:0;
}
.scrollableElement {
display: flex;
overflow-x: scroll;
}
.textElement {
color: white;
background: grey;
}
<html>
<body>
<div class="flexContainer">
<div class="sidebar">
<div>Sidebar</div>
</div>
<div class="content">
<div class="scrollableElement">
<div class="textElement">
<div>Content11111111111111111111111111111111111111111111111111111111111111111111111</div>
<div>Content22222222222222222222222222222222222222222222222222222222222222222222222</div>
<div>Content33333333333333333333333333333333333333333333333333333333333333333333333</div>
<div>Content44444444444444444444444444444444444444444444444444444444444444444444444</div>
<div>Content55555555555555555555555555555555555555555555555555555555555555555555555</div>
<div>Content66666666666666666666666666666666666666666666666666666666666666666666666</div>
<div>Content77777777777777777777777777777777777777777777777777777777777777777777777</div>
<div>Content88888888888888888888888888888888888888888888888888888888888888888888888</div>
</div>
</div>
</div>
</div>
</body>
</html>
Your flex container has no set width, so it is taking up the entire width of the screen.
You could try setting the width to achieve the behavior you are looking for, for example:
.flexContainer {
display: flex;
width: 500px;
}
OR you could set the width of the .scrollableElement to resize based on the screen:
.scrollableElement {
overflow-x: scroll;
width: 65%;
}

CSS how to use Flex positioning and fill content inside of the div

I have following slider:
I have issues with filling content inside of div. In this case in yellow div we can see button "Kempe2". I used break line (br) to put it in new line. When I use bootstrap:
<div class="row">
<button>Kempe2<button>
</div>
button disappears below and it is hideen. This is the flex, and I don't know how to use it.
This works:
<div class="panes" [#slide]="activePane">
<div firstPane>Hi
<br>Kempe
<br>
<button>Kempe2</button>
</div>
<div secondPane>2</div>
<div thirdPane>3</div>
<div fourthPane>4</div>
</div>
This doesn't work:
<div class="panes" [#slide]="activePane">
<div firstPane>Hi
<br>Kempe
<br>
<div class="row">
<button>Kempe2</button></div>
</div>
<div secondPane>2</div>
<div thirdPane>3</div>
<div fourthPane>4</div>
</div>
Here, button disappears and is probably pushed to bottom:
How can I use flex to put rows with bootstrap?
CSS:
:host {
display: block;
overflow: hidden;
}
.panes {
height: 100%;
width: 400%;
display: flex;
align-items: center;
}
.panes div {
flex: 1;
height:100%;
}
[firstPane] {
background-color: #FFF897;
width:100%;
}
[secondPane] {
background-color: #6CE6CB;
width:100%;
}
[thirdPane] {
background-color: brown;
width:100%;
}
[fourthPane] {
background-color: purple;
width:100%;
}
button {
font-size: 24px;
margin-top: 16px;
}
slide-panel {
/* max-width: 500px; */
height: 450px;
}
slide-panel div {
font: 20px sans-serif;
height: 100%;
display: flex;
align-items: center;
justify-content: center;
}
slide-panel .panes {
border: 6px dashed #4990E2;
/* box-sizing: border-box; */
}

Background of div does not scroll with the contents

I have the following snippet of html that forms an X-Y scrollable listbox
* {
font-family: "consolas";
}
.listbox {
border: 1px solid black;
padding: 4px;
width: 150px;
height: 200px;
display: flex;
flex-direction: column;
}
.caption {
font-weight: bold;
background-color: #aaf;
padding: 10px;
}
.content {
flex-grow: 1;
overflow: scroll;
}
.item {
background-color: #ddd;
padding: 2px;
padding-left: 6px;
margin-top: 4px;
white-space: nowrap;
}
<div class="listbox">
<div class="caption">Caption</div>
<div class="content">
<div class="item">One</div>
<div class="item">Two</div>
<div class="item">Three (this has a longer bit)</div>
<div class="item">Four</div>
<div class="item">Five</div>
<div class="item">Six</div>
<div class="item">Seven</div>
<div class="item">Eight (so does this)</div>
<div class="item">Nine</div>
<div class="item">Ten</div>
</div>
</div>
It's working fine, with one problem, as the user scrolls from left to right, the background of the div seems to get left behind. It's as though the actual div only stretches the width of its parent, and the scrolling/overflow thing is "faked" somehow.
Why is this the case?
How do I address the problem? The behaviour I want is for all the items to appear to be the same width as the largest one.
Try adding a container <div class="items"> around the items set it to display:inline-block.
.items {
display: inline-block;
}
* {
font-family: "consolas";
}
.listbox {
border: 1px solid black;
padding: 4px;
width: 150px;
height: 200px;
display: flex;
flex-direction: column;
}
.caption {
font-weight: bold;
background-color: #aaf;
padding: 10px;
}
.content {
flex-grow: 1;
overflow: scroll;
}
.items {
display: inline-block;
}
.item {
background-color: #ddd;
padding: 2px;
padding-left: 6px;
margin-top: 4px;
white-space: nowrap;
}
<div class="listbox">
<div class="caption">Caption</div>
<div class="content">
<div class="items">
<div class="item">One</div>
<div class="item">Two</div>
<div class="item">Three (this has a longer bit)</div>
<div class="item">Four</div>
<div class="item">Five</div>
<div class="item">Six</div>
<div class="item">Seven</div>
<div class="item">Eight (so does this)</div>
<div class="item">Nine</div>
<div class="item">Ten</div>
</div>
</div>
</div>
Explanation: by default a block level element takes 100% width of the container no more than that, however an inline block will expand to content length if available e.g. in a scrollable container.
Also apply .items {min-width: 100%;} in case you want the background to grow full width even with less text in every row.