max-height 100% breaks out of 100vh - html

I want to have a footer fixed at the bottom of my page, with the contents conforming to my view height.
Good: This CodePen has nicely contained contents. Notice that no matter how long the menu gets, the footer stays inside the red box.
Bad: This CodePen has contents where the red box breaks out of the viewport, and you need to scroll to the footer.
Can anyone suggest CSS which makes bad CodePen behave correctly?
Since StackOverflow requires code, here is the HTML and CSS for each CodePen:
Good HTML:
<div class="container">
<div class="nav">
<h1>Top Nav Bar</h1>
</div>
<div class="sidebar">
<h2>Menu</h2>
<ul>
<li>Item 1</li>
<li>Item 2</li>
<li>Item 3</li>
<li>Item 4</li>
<li>Item 5</li>
<li>Item 1</li>
<li>Item 2</li>
<li>Item 3</li>
<li>Item 4</li>
<li>Item 5</li>
<li>Item 1</li>
<li>Item 2</li>
<li>Item 3</li>
<li>Item 4</li>
<li>Item 5</li>
<li>Item 1</li>
<li>Item 2</li>
<li>Item 3</li>
<li>Item 4</li>
<li>Item 5</li>
<li>Item 1</li>
<li>Item 2</li>
<li>Item 3</li>
<li>Item 4</li>
<li>Item 5</li>
<li>Item 1</li>
<li>Item 2</li>
<li>Item 3</li>
<li>Item 4</li>
<li>Item 5</li>
<li>Item 1</li>
<li>Item 2</li>
<li>Item 3</li>
<li>Item 4</li>
<li>Item 5</li>
<li>Item 1</li>
<li>Item 2</li>
<li>Item 3</li>
<li>Item 4</li>
<li>Item 5</li>
<li>Item 1</li>
<li>Item 2</li>
<li>Item 3</li>
<li>Item 4</li>
<li>Item 5</li>
<li>Item 1</li>
<li>Item 2</li>
<li>Item 3</li>
<li>Item 4</li>
<li>Item 5</li>
<li>Item 1</li>
<li>Item 2</li>
<li>Item 3</li>
<li>Item 4</li>
<li>Item 5</li>
<li>Item 1</li>
<li>Item 2</li>
<li>Item 3</li>
<li>Item 4</li>
<li>Item 5</li>
<li>Item 1</li>
<li>Item 2</li>
<li>Item 3</li>
<li>Item 4</li>
<li>Item 5</li>
<li>Item 1</li>
<li>Item 2</li>
<li>Item 3</li>
<li>Item 4</li>
<li>Item 5</li>
<li>Item 1</li>
<li>Item 2</li>
<li>Item 3</li>
<li>Item 4</li>
<li>Item 5</li>
<li>Item 1</li>
<li>Item 2</li>
<li>Item 3</li>
<li>Item 4</li>
<li>Item 5</li>
<li>Item 1</li>
<li>Item 2</li>
<li>Item 3</li>
<li>Item 4</li>
<li>Item 5</li>
<li>Item 1</li>
<li>Item 2</li>
<li>Item 3</li>
<li>Item 4</li>
<li>Item 5</li>
<li>Item 1</li>
<li>Item 2</li>
<li>Item 3</li>
<li>Item 4</li>
<li>Item 5</li>
<li>Item 1</li>
<li>Item 2</li>
<li>Item 3</li>
<li>Item 4</li>
<li>Item 5</li>
<li>Item 1</li>
<li>Item 2</li>
<li>Item 3</li>
<li>Item 4</li>
<li>Item 5</li>
<li>Item 1</li>
<li>Item 2</li>
<li>Item 3</li>
<li>Item 4</li>
<li>Item 5</li>
<li>Item 1</li>
<li>Item 2</li>
<li>Item 3</li>
<li>Item 4</li>
<li>Item 5</li>
<li>Item 1</li>
<li>Item 2</li>
<li>Item 3</li>
<li>Item 4</li>
<li>Item 5</li>
</ul>
</div>
<div class="main">
<p>Hello World</p>
</div>
<div class="footer">This is the footer</div>
</div>
Good CSS:
body,html{ margin: 0; padding: 0; }
*{ margin: 0; padding: 0; box-sizing: border-box; }
.container{ display: grid; height: 100vh; border: 3px solid red;
grid-template-areas: "nav nav"
"sidebar main"
"footer footer";
grid-template-rows: auto
1fr
auto;
grid-template-columns: 200px 1fr; }
.nav{ grid-area: nav; border-bottom: 1px solid #AAA; }
.sidebar{ grid-area: sidebar; border-right: 1px solid #AAA; max-height: 100%; overflow-y: scroll; }
.footer{ grid-area: footer; text-align: center; background-color: lightgreen; }
Bad HTML:
<div class="container">
<div class="nav">
<h1>Top Nav Bar</h1>
</div>
<div class="sidebar">
<h2>Menu</h2>
<ul>
<li>Item 1</li>
<li>Item 2</li>
<li>Item 3</li>
<li>Item 4</li>
<li>Item 5</li>
</ul>
</div>
<div class="main">
<div class="main-main">
<div class="area-left">
<p>Some text</p><p>Some text</p><p>Some text</p><p>Some text</p><p>Some text</p><p>Some text</p><p>Some text</p><p>Some text</p><p>Some text</p><p>Some text</p><p>Some text</p><p>Some text</p><p>Some text</p><p>Some text</p><p>Some text</p><p>Some text</p><p>Some text</p><p>Some text</p><p>Some text</p><p>Some text</p><p>Some text</p><p>Some text</p><p>Some text</p><p>Some text</p><p>Some text</p><p>Some text</p><p>Some text</p><p>Some text</p><p>Some text</p><p>Some text</p><p>Some text</p><p>Some text</p><p>Some text</p><p>Some text</p><p>Some text</p><p>Some text</p><p>Some text</p><p>Some text</p><p>Some text</p><p>Some text</p><p>Some text</p><p>Some text</p><p>Some text</p><p>Some text</p><p>Some text</p><p>Some text</p><p>Some text</p><p>Some text</p><p>Some text</p><p>Some text</p><p>Some text</p><p>Some text</p><p>Some text</p><p>Some text</p><p>Some text</p><p>Some text</p><p>Some text</p><p>Some text</p><p>Some text</p><p>Some text</p><p>Some text</p><p>Some text</p><p>Some text</p><p>Some text</p><p>Some text</p><p>Some text</p><p>Some text</p><p>Some text</p><p>Some text</p><p>Some text</p><p>Some text</p><p>Some text</p><p>Some text</p><p>Some text</p><p>Some text</p><p>Some text</p><p>Some text</p><p>Some text</p><p>Some text</p><p>Some text</p><p>Some text</p><p>Some text</p><p>Some text</p><p>Some text</p><p>Some text</p><p>Some text</p><p>Some text</p><p>Some text</p><p>Some text</p><p>Some text</p>
</div>
<div class="area-right">
<div>Large Area</div>
</div>
</div>
</div>
<div class="footer">This is the footer</div>
</div>
Bad CSS:
body,html{ margin: 0; padding: 0; }
*{ margin: 0; padding: 0; box-sizing: border-box; }
.container{ display: grid; height: 100vh; border: 3px solid red;
grid-template-areas: "nav nav"
"sidebar main"
"footer footer";
grid-template-rows: auto
1fr
auto;
grid-template-columns: 200px 1fr; }
.nav{ grid-area: nav; border-bottom: 1px solid #AAA; }
.sidebar{ grid-area: sidebar; border-right: 1px solid #AAA; }
.footer{ grid-area: footer; text-align: center; background-color: lightgreen; }
.main{ grid-area: main; display: grid;
grid-template-areas: "main-main";
grid-template-rows: 1fr
auto }
.main-main{ grid-area: main-main; display: grid; border-top: 1px solid #AAA;
grid-template-areas: "area-left area-right";
grid-template-columns: 200px 1fr; max-height: 100%; overflow-y: auto; }
.area-left{ grid-area: area-left; max-height: 100%; overflow-y: scroll; }
.area-right{ grid-area: area-right; max-height: 100%; overflow-y: scroll; }

Here is the fixed version of the Bad CSS - https://codepen.io/spandzcodepen/pen/xxbRYWq
body,html{ margin: 0; padding: 0; }
*{ margin: 0; padding: 0; box-sizing: border-box; }
.container{ display: grid; height: 100vh; border: 3px solid red;
grid-template-areas: "nav nav"
"sidebar main"
"footer footer";
grid-template-rows: auto
1fr
auto;
grid-template-columns: 200px 1fr; }
.nav{ grid-area: nav; border-bottom: 1px solid #AAA; }
.sidebar{ grid-area: sidebar; border-right: 1px solid #AAA; }
.footer{ grid-area: footer; text-align: center; background-color: lightgreen; }
.main{ grid-area: main; display: grid;
grid-template-areas: "main-main";
grid-template-rows: 1fr
auto;
max-height: 100%; overflow-y: auto;}
.main-main{ grid-area: main-main; display: grid; border-top: 1px solid #AAA;
grid-template-areas: "area-left area-right";
grid-template-columns: 200px 1fr; }
.area-left{ grid-area: area-left; max-height: 100%; overflow-y: scroll; }
.area-right{ grid-area: area-right; max-height: 100%; overflow-y: scroll; }
Modified the bad css to switch the max height and overflow on the 'main' holder instead of 'main-main'.

You need to add overflow-y: scroll; and a semicolon in the property grid-template-rows to .main, just 2 lines of code but take a lot of effort to find :)), here is the full version of .main:
https://codepen.io/loia5tqd001/pen/RwNoQEB
.main {
grid-area: main;
display: grid;
grid-template-areas: 'main-main';
grid-template-rows: 1fr auto; /* You can also delete this line because there's only one child element */
overflow-y: scroll;
}

Related

Overflow-y changes the color of the text

I am learning HTML and CSS and I have the following issue, I have a long list of items and I am applying overflow-y with external CSS. The problem is that it changes the font color of the list. I would also be grateful for any info on how to style the scrollbar and only be visible when scrolling.
#main-div {
position: relative;
}
#container-div {
position: absolute;
right: 0;
margin-top: 15%;
margin-right: 10%;
overflow-y: auto;
width: 600px;
height: 350px;
}
.main-text {
color: aliceblue;
mix-blend-mode: difference;
}
<div id="main-div">
<div id="container-div">
<div id="list" class="main-text">
<h4>title 1</h4>
<ul>
<li>item 1</li>
<li>item 1</li>
<li>item 1</li>
</ul>
<h4>title 2</h4>
<ul>
<li>item 1</li>
<li>item 1</li>
<li>item 1</li>
</ul>
<h4>title 3</h4>
<ul>
<li>item 1</li>
<li>item 1</li>
<li>item 1</li>
</ul>
<h4>title 4</h4>
<ul>
<li>item 1</li>
<li>item 1</li>
<li>item 1</li>
</ul>
<h4>title 5</h4>
<ul>
<li>item 1</li>
<li>item 1</li>
<li>item 1</li>
</ul>
<h4>title 6</h4>
<ul>
<li>item 1</li>
<li>item 1</li>
<li>item 1</li>
</ul>
</div>
</div>
</div>
I didn't see the font-color changing. But to style the scrollbar, check the css snippet below.
#main-div {
position: relative;
}
#container-div {
position: absolute;
right: 0;
margin: 10%;
overflow-y: auto;
width: 600px;
height: 300px;
background: lightblue;
}
/* Styling Scroll Bar */
::-webkit-scrollbar {
width: 10px;
}
/* Track */
::-webkit-scrollbar-track {
background: #f1f1f1;
}
/* Handle */
::-webkit-scrollbar-thumb {
background: #c1c1c1;
}
/* Handle on hover */
::-webkit-scrollbar-thumb:hover {
background: #555;
}
<div id="main-div">
<div id="container-div">
<div id="list">
<h4>title 1</h4>
<ul>
<li>item 1</li>
<li>item 1</li>
<li>item 1</li>
</ul>
<h4>title 2</h4>
<ul>
<li>item 1</li>
<li>item 1</li>
<li>item 1</li>
</ul>
<h4>title 3</h4>
<ul>
<li>item 1</li>
<li>item 1</li>
<li>item 1</li>
</ul>
<h4>title 4</h4>
<ul>
<li>item 1</li>
<li>item 1</li>
<li>item 1</li>
</ul>
<h4>title 5</h4>
<ul>
<li>item 1</li>
<li>item 1</li>
<li>item 1</li>
</ul>
<h4>title 6</h4>
<ul>
<li>item 1</li>
<li>item 1</li>
<li>item 1</li>
</ul>
</div>
</div>
</div>
I think you just made it with the wrong class.
since you set the height on the container-div, you should use your mix-blend-mode on the same one.
Try this:
#main-div {
position: relative;
}
#container-div {
position: absolute;
right: 0;
margin-top: 15%;
margin-right: 10%;
overflow-y: auto;
width: 300px;
height: 150px;
background-color: #e2e2e2;
color: aliceblue;
mix-blend-mode: difference;
}
<div id="main-div">
<div id="container-div">
<div id="list">
<h4>title 1</h4>
<ul>
<li>item 1</li>
<li>item 1</li>
<li>item 1</li>
</ul>
<h4>title 2</h4>
<ul>
<li>item 1</li>
<li>item 1</li>
<li>item 1</li>
</ul>
<h4>title 3</h4>
<ul>
<li>item 1</li>
<li>item 1</li>
<li>item 1</li>
</ul>
<h4>title 4</h4>
<ul>
<li>item 1</li>
<li>item 1</li>
<li>item 1</li>
</ul>
<h4>title 5</h4>
<ul>
<li>item 1</li>
<li>item 1</li>
<li>item 1</li>
</ul>
<h4>title 6</h4>
<ul>
<li>item 1</li>
<li>item 1</li>
<li>item 1</li>
</ul>
</div>
</div>
</div>
I've added a background to see the aliceblue color

Svg display probems with column-count property

I have a list of blocks I want to display in multiple columns (at least 2 columns).
In my blocks I have a header with a title and a svg icon.
If I use the css property "column-count" to split content in columns, some svg disapear on Google Chrome. (no problem with Firefox)
Here is a demo :
section {
width: 500px;
margin-right: 100px;
float: left;
}
.container {
border: 1px solid black;
margin: 0 auto;
padding: 0.25em;
margin-top: 1.25em;
}
.container.withcolumns {
column-count: 2;
column-gap: 2em;
}
.block {
break-inside: avoid-column;
}
.block header {
font-weight: bold;
padding: 0.5em 0;
border-bottom: 1px solid grey;
}
.block header svg {
width: 15px;
height: 15px;
margin-right: 0.5em;
}
ul,
li {
margin: 0;
padding: 0;
list-style-type: none;
}
li {
margin: 0.25em 0;
}
<section>
<h1>First block without columns</h1>
<div class='container'>
<div class='block'>
<header>
<svg><use href="#svg-capacity" xlink:href="#svg-capacity"></use></svg>
Block 1</header>
<ul>
<li>Item 1</li>
<li>Item 2</li>
<li>Item 3</li>
</ul>
</div>
<div class='block'>
<header><svg><use href="#svg-capacity" xlink:href="#svg-capacity"></use></svg>Block 2</header>
<ul>
<li>Item 1</li>
<li>Item 2</li>
</ul>
</div>
<div class='block'>
<header><svg><use href="#svg-capacity" xlink:href="#svg-capacity"></use></svg>Block 3</header>
<ul>
<li>Item 1</li>
<li>Item 2</li>
</ul>
</div>
<div class='block'>
<header><svg><use href="#svg-capacity" xlink:href="#svg-capacity"></use></svg>Block 4</header>
<ul>
<li>Item 1</li>
<li>Item 2</li>
<li>Item 3</li>
<li>Item 4</li>
<li>Item 5</li>
</ul>
</div>
</div>
</section>
<section>
<h1>Same code with columns</h1>
<div class='container withcolumns'>
<div class='block'>
<header>
<svg><use href="#svg-capacity" xlink:href="#svg-capacity"></use></svg>
Block 1</header>
<ul>
<li>Item 1</li>
<li>Item 2</li>
<li>Item 3</li>
</ul>
</div>
<div class='block'>
<header><svg><use href="#svg-capacity" xlink:href="#svg-capacity"></use></svg>Block 2</header>
<ul>
<li>Item 1</li>
<li>Item 2</li>
</ul>
</div>
<div class='block'>
<header><svg><use href="#svg-capacity" xlink:href="#svg-capacity"></use></svg>Block 3</header>
<ul>
<li>Item 1</li>
<li>Item 2</li>
</ul>
</div>
<div class='block'>
<header><svg><use href="#svg-capacity" xlink:href="#svg-capacity"></use></svg>Block 4</header>
<ul>
<li>Item 1</li>
<li>Item 2</li>
<li>Item 3</li>
<li>Item 4</li>
<li>Item 5</li>
</ul>
</div>
</section>
</div>
<svg xmlns="http://www.w3.org/2000/svg" style="display: none;">
<symbol id="svg-capacity" viewBox="0 0 17.293 20">
<path d="M2674.323,1341a2.012,2.012,0,1,0-1.437-.575,2,2,0,0,0,1.437.575Zm1.52,1h-3.053a2.012,2.012,0,0,0-2.027,2v5.494h1.52V1357h4.067v-7.507h1.533V1344a2.022,2.022,0,0,0-2.039-2Zm-11.693-1a2,2,0,1,0-2.027-2,2.023,2.023,0,0,0,2.027,2Zm1.52,1h-3.04a2.015,2.015,0,0,0-2.04,2v5.493h1.533V1357h4.067v-7.507h1.52V1344a2.015,2.015,0,0,0-2.04-2Z" transform="translate(-2660.59 -1337)"></path>
</symbol>
</svg>
Does anyone have an idea how to fix this?
Regards
I had the exact same problem and finally after searching for a while, the following made Chrome render my SVGs correctly:
-webkit-backface-visibility: hidden;
In your code above if you add the following, it works:
.block header {
font-weight: bold;
padding: 0.5em 0;
border-bottom: 1px solid grey;
-webkit-backface-visibility: hidden;
}
It's for sure a bug but here is a different code using the SVG as background to achieve the same without the bug:
section {
width: 500px;
margin-right: 100px;
float: left;
}
.container {
border: 1px solid black;
margin: 0 auto;
padding: 0.25em;
margin-top: 1.25em;
}
.container.withcolumns {
column-count: 2;
column-gap: 2em;
}
.block {
break-inside: avoid-column;
}
.block header {
font-weight: bold;
padding: 0.5em 18px;
border-bottom: 1px solid grey;
background:url('data:image/svg+xml;utf8,<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 17.293 20" width="15"> <path d="M2674.323,1341a2.012,2.012,0,1,0-1.437-.575,2,2,0,0,0,1.437.575Zm1.52,1h-3.053a2.012,2.012,0,0,0-2.027,2v5.494h1.52V1357h4.067v-7.507h1.533V1344a2.022,2.022,0,0,0-2.039-2Zm-11.693-1a2,2,0,1,0-2.027-2,2.023,2.023,0,0,0,2.027,2Zm1.52,1h-3.04a2.015,2.015,0,0,0-2.04,2v5.493h1.533V1357h4.067v-7.507h1.52V1344a2.015,2.015,0,0,0-2.04-2Z" transform="translate(-2660.59 -1337)"></path></svg>') left top 0.5em/15px 15px no-repeat;
}
ul,
li {
margin: 0;
padding: 0;
list-style-type: none;
}
li {
margin: 0.25em 0;
}
<section>
<h1>First block without columns</h1>
<div class='container'>
<div class='block'>
<header>
Block 1</header>
<ul>
<li>Item 1</li>
<li>Item 2</li>
<li>Item 3</li>
</ul>
</div>
<div class='block'>
<header>Block 2</header>
<ul>
<li>Item 1</li>
<li>Item 2</li>
</ul>
</div>
<div class='block'>
<header>Block 3</header>
<ul>
<li>Item 1</li>
<li>Item 2</li>
</ul>
</div>
<div class='block'>
<header>Block 4</header>
<ul>
<li>Item 1</li>
<li>Item 2</li>
<li>Item 3</li>
<li>Item 4</li>
<li>Item 5</li>
</ul>
</div>
</div>
</section>
<section>
<h1>Same code with columns</h1>
<div class='container withcolumns'>
<div class='block'>
<header>
Block 1</header>
<ul>
<li>Item 1</li>
<li>Item 2</li>
<li>Item 3</li>
</ul>
</div>
<div class='block'>
<header>Block 2</header>
<ul>
<li>Item 1</li>
<li>Item 2</li>
</ul>
</div>
<div class='block'>
<header>Block 3</header>
<ul>
<li>Item 1</li>
<li>Item 2</li>
</ul>
</div>
<div class='block'>
<header>Block 4</header>
<ul>
<li>Item 1</li>
<li>Item 2</li>
<li>Item 3</li>
<li>Item 4</li>
<li>Item 5</li>
</ul>
</div>
</section>
</div>
There is an error in your markup where you are closing the section before closing the last block. Still this is not fixing the problem.
This probably is a bug. In order to make it work I've removed the transformation and recalculated the d attribute.
section {
width: 500px;
margin-right: 100px;
float: left;
}
.container {
border: 1px solid black;
margin: 0 auto;
padding: 0.25em;
margin-top: 1.25em;
}
.container.withcolumns {
column-count: 2;
column-gap: 2em;
}
.block {
break-inside: avoid-column;
}
.block header {
font-weight: bold;
padding: 0.5em 0;
border-bottom: 1px solid grey;
}
.block header svg {
width: 15px;
height: 15px;
margin-right: 0.5em;
}
ul,
li {
margin: 0;
padding: 0;
list-style-type: none;
}
li {
margin: 0.25em 0;
}
<svg xmlns="http://www.w3.org/2000/svg" style="display: none;">
<symbol id="svg-capacity" viewBox="0 0 17.293 20">
<path d="M13.73,4a2.012,2.012,0,1,0,-1.437,-0.575a2,2,0,0,0,1.437,0.575zm1.52,1h-3.053a2.012,2.012,0,0,0,-2.027,2v5.494h1.52v7.506h4.067v-7.507h1.533v-5.493a2.022,2.022,0,0,0,-2.039,-2zm-11.693,-1a2,2,0,1,0,-2.027,-2a2.023,2.023,0,0,0,2.027,2zm1.52,1h-3.04a2.015,2.015,0,0,0,-2.04,2v5.493h1.533v7.507h4.067v-7.507h1.52v-5.493a2.015,2.015,0,0,0,-2.04,-2z" ></path>
</symbol>
</svg>
<section>
<h1>Same code with columns</h1>
<div class='container withcolumns'>
<div class='block'>
<header>
<svg><use href="#svg-capacity" xlink:href="#svg-capacity"></use></svg>
Block 1</header>
<ul>
<li>Item 1</li>
<li>Item 2</li>
<li>Item 3</li>
</ul>
</div>
<div class='block'>
<header><svg><use href="#svg-capacity" xlink:href="#svg-capacity"></use></svg>Block 2</header>
<ul>
<li>Item 1</li>
<li>Item 2</li>
</ul>
</div>
<div class='block'>
<header><svg><use href="#svg-capacity" xlink:href="#svg-capacity"></use></svg>Block 3</header>
<ul>
<li>Item 1</li>
<li>Item 2</li>
</ul>
</div>
<div class='block'>
<header><svg><use href="#svg-capacity" xlink:href="#svg-capacity"></use></svg>Block 4</header>
<ul>
<li>Item 1</li>
<li>Item 2</li>
<li>Item 3</li>
<li>Item 4</li>
<li>Item 5</li>
</ul>
</div>
</div>
</section>

Horizontally Align ULs In Different

I have the below code which displays list items horizontally.
However, the horizontal alignment gets broken up between the ULs. Is it possible to have all of the list items aligned across the ULs? ie so that item 6 appears below item 2 etc.
div,
ul,
li {
margin: 0;
padding: 0;
}
li {
width: 24%;
display: inline-block;
border: 1px solid red;
margin-bottom: 20px;
}
ul {
width: 100%;
display: inline-block;
}
.container {
width: 1400px;
}
<div class="container">
<div class="firstdiv">
<ul class="firstul">
<li>Item 1</li>
<li>Item 2</li>
<li>Item 3</li>
<li>Item 4</li>
<li>Item 5</li>
</ul>
</div>
<div class="seconddiv">
<ul class="secondul">
<li>Item 6</li>
<li>Item 7</li>
<li>Item 8</li>
</ul>
</div>
<div class="thirddiv">
<ul class="thirdul">
<li>Item 9</li>
<li>Item 10</li>
<li>Item 11</li>
<li>Item 12</li>
<li>Item 13</li>
<li>Item 14</li>
</ul>
</div>
</div>
Assumming that you need to keep your HTML structure like that, apply display: inline to your lists and their div wrappers:
div,
ul,
li {
margin: 0;
padding: 0;
}
li {
width: 24%;
display: inline-block;
border: 1px solid red;
margin-bottom: 20px;
}
.container div,
.container ul {
display: inline;
}
<div class="container">
<div class="firstdiv">
<ul class="firstul">
<li>Item 1</li>
<li>Item 2</li>
<li>Item 3</li>
<li>Item 4</li>
<li>Item 5</li>
</ul>
</div>
<div class="seconddiv">
<ul class="secondul">
<li>Item 6</li>
<li>Item 7</li>
<li>Item 8</li>
</ul>
</div>
<div class="thirddiv">
<ul class="thirdul">
<li>Item 9</li>
<li>Item 10</li>
<li>Item 11</li>
<li>Item 12</li>
<li>Item 13</li>
<li>Item 14</li>
</ul>
</div>
</div>
A future alternative may be to apply display:grid to your container and display: contents to its descendant <div> and <ul> elements. Granted, the support for display: contents is limited at the moment.
.container {
display: grid;
grid-template-columns: repeat(4, calc(25% - 7.5px));
grid-gap: 20px 10px;
}
.container div,
.container ul {
display: contents;
}
.container li {
list-style: none;
outline: 1px solid #f00;
}
<div class="container">
<div class="firstdiv">
<ul class="firstul">
<li>Item 1</li>
<li>Item 2</li>
<li>Item 3</li>
<li>Item 4</li>
<li>Item 5</li>
</ul>
</div>
<div class="seconddiv">
<ul class="secondul">
<li>Item 6</li>
<li>Item 7</li>
<li>Item 8</li>
</ul>
</div>
<div class="thirddiv">
<ul class="thirdul">
<li>Item 9</li>
<li>Item 10</li>
<li>Item 11</li>
<li>Item 12</li>
<li>Item 13</li>
<li>Item 14</li>
</ul>
</div>
</div>

nested flexbox height vs max-height

update: I see this strange behavior on Chrome 72. FireFox 64 is OK!
I have a problem with a nested flexbox.
In the snippet below I added a dummy XL height to .root.container, so that the result is exactly what I want when there are many items that overflow the available max-height.
Conversely, when there are few items, the .root.container should not extend to all available height.
In other terms, I want .root.container height to be auto, but I can't figure how.
Removing its dummy height, the overflow is triggered on .root.content instead of .sub.content.
Please, help me understand how flexbox works in this particular situation.
P.S. fiddle also available here
html, body {
height: 100%;
margin: 0;
padding: 0;
}
* {
box-sizing: border-box;
}
div {
padding: 10px;
}
.container {
display: flex;
flex-direction: column;
}
.content {
flex: 1;
max-height: 100%;
overflow: auto;
}
.root.container {
background-color: red;
max-height: 100%;
height: 999999px; /* i want height to be 'auto' */
}
.sub.container {
background-color: purple;
height: 100%;
}
.root.header {
background-color: lightblue;
}
.sub.header {
background-color: lightgreen;
}
.root.content {
background-color: yellow;
}
.sub.content {
background-color: orange;
}
<div class="root container">
<div class="root header">header</div>
<div class="root content">
<div class="sub container">
<div class="sub header">menu</div>
<div class="sub content">
<ul>
<li>Item 1</li>
<li>Item 2</li>
<li>Item 3</li>
<li>Item 4</li>
<li>Item 5</li>
<li>Item 1</li>
<li>Item 2</li>
<li>Item 3</li>
<li>Item 4</li>
<li>Item 5</li>
<li>Item 1</li>
<li>Item 2</li>
<li>Item 3</li>
<li>Item 4</li>
<li>Item 5</li>
<li>Item 1</li>
<li>Item 2</li>
<li>Item 3</li>
<li>Item 4</li>
<li>Item 5</li>
<li>Item 1</li>
<li>Item 2</li>
<li>Item 3</li>
<li>Item 4</li>
<li>Item 5</li>
<li>Item 1</li>
<li>Item 2</li>
<li>Item 3</li>
<li>Item 4</li>
<li>Item 5</li>
<li>Item 1</li>
<li>Item 2</li>
<li>Item 3</li>
<li>Item 4</li>
<li>Item 5</li>
<li>Item 1</li>
<li>Item 2</li>
<li>Item 3</li>
<li>Item 4</li>
<li>Item 5</li>
<li>Item 1</li>
<li>Item 2</li>
<li>Item 3</li>
<li>Item 4</li>
<li>Item 5</li>
<li>Item 1</li>
<li>Item 2</li>
<li>Item 3</li>
<li>Item 4</li>
<li>Item 5</li>
<li>Item 1</li>
<li>Item 2</li>
<li>Item 3</li>
<li>Item 4</li>
<li>Item 5</li>
</ul>
</div>
</div>
</div>
</div>
Your code is working as expected when setting the big height because max-height:100% in the child element need a reference, if you remove the height the max-height will fail to auto. As a side note, Firefox will have the same output even if you remove max-height so the issue isn't related to max-height. 1
Instead, you can keep the cascading flex container and rely on the default stretch alignment to obtain what you want:
html, body {
height: 100%;
margin: 0;
padding: 0;
}
* {
box-sizing: border-box;
}
div {
padding: 10px;
}
.container {
display: flex;
flex-direction: column;
}
.content {
flex: 1;
max-height: 100%;
overflow: auto;
}
.root.container {
background-color: red;
max-height: 100%;
}
.sub.container {
background-color: purple;
width:100%; /*added this*/
}
.root.header {
background-color: lightblue;
}
.sub.header {
background-color: lightgreen;
}
.root.content {
background-color: yellow;
display:flex; /*added this*/
}
.sub.content {
background-color: orange;
}
<div class="root container">
<div class="root header">header</div>
<div class="root content">
<div class="sub container">
<div class="sub header">menu</div>
<div class="sub content">
<ul>
<li>Item 1</li>
<li>Item 2</li>
<li>Item 3</li>
<li>Item 4</li>
<li>Item 5</li>
<li>Item 1</li>
<li>Item 2</li>
<li>Item 3</li>
<li>Item 4</li>
<li>Item 5</li>
<li>Item 1</li>
<li>Item 2</li>
<li>Item 3</li>
<li>Item 4</li>
<li>Item 5</li>
<li>Item 1</li>
<li>Item 2</li>
<li>Item 3</li>
<li>Item 4</li>
<li>Item 5</li>
<li>Item 1</li>
<li>Item 2</li>
<li>Item 3</li>
<li>Item 4</li>
<li>Item 5</li>
<li>Item 1</li>
<li>Item 2</li>
<li>Item 3</li>
<li>Item 4</li>
<li>Item 5</li>
<li>Item 1</li>
<li>Item 2</li>
<li>Item 3</li>
<li>Item 4</li>
<li>Item 5</li>
<li>Item 1</li>
<li>Item 2</li>
<li>Item 3</li>
<li>Item 4</li>
<li>Item 5</li>
<li>Item 1</li>
<li>Item 2</li>
<li>Item 3</li>
<li>Item 4</li>
<li>Item 5</li>
<li>Item 1</li>
<li>Item 2</li>
<li>Item 3</li>
<li>Item 4</li>
<li>Item 5</li>
<li>Item 1</li>
<li>Item 2</li>
<li>Item 3</li>
<li>Item 4</li>
<li>Item 5</li>
</ul>
</div>
</div>
</div>
</div>
To better see the issue let's remove some properties and keep only the needed ones that will trigger the different behavior:
html, body {
height: 100%;
margin: 0;
padding: 0;
}
* {
box-sizing: border-box;
}
div {
padding: 10px;
}
.container {
display: flex;
flex-direction: column;
}
.content {
flex: 1;
overflow: auto;
}
.root.container {
background-color: red;
max-height: 100%;
}
.sub.container {
background-color: purple;
height: 100%;
}
.root.header {
background-color: lightblue;
}
.sub.header {
background-color: lightgreen;
}
.root.content {
background-color: yellow;
}
.sub.content {
background-color: orange;
}
<div class="root container">
<div class="root header">header</div>
<div class="root content">
<div class="sub container">
<div class="sub header">menu</div>
<div class="sub content">
<ul>
<li>Item 1</li>
<li>Item 2</li>
<li>Item 3</li>
<li>Item 4</li>
<li>Item 5</li>
<li>Item 1</li>
<li>Item 2</li>
<li>Item 3</li>
<li>Item 4</li>
<li>Item 5</li>
<li>Item 1</li>
<li>Item 2</li>
<li>Item 3</li>
<li>Item 4</li>
<li>Item 5</li>
<li>Item 1</li>
<li>Item 2</li>
<li>Item 3</li>
<li>Item 4</li>
<li>Item 5</li>
<li>Item 1</li>
<li>Item 2</li>
<li>Item 3</li>
<li>Item 4</li>
<li>Item 5</li>
<li>Item 1</li>
<li>Item 2</li>
<li>Item 3</li>
<li>Item 4</li>
<li>Item 5</li>
<li>Item 1</li>
<li>Item 2</li>
<li>Item 3</li>
<li>Item 4</li>
<li>Item 5</li>
<li>Item 1</li>
<li>Item 2</li>
<li>Item 3</li>
<li>Item 4</li>
<li>Item 5</li>
<li>Item 1</li>
<li>Item 2</li>
<li>Item 3</li>
<li>Item 4</li>
<li>Item 5</li>
<li>Item 1</li>
<li>Item 2</li>
<li>Item 3</li>
<li>Item 4</li>
<li>Item 5</li>
<li>Item 1</li>
<li>Item 2</li>
<li>Item 3</li>
<li>Item 4</li>
<li>Item 5</li>
</ul>
</div>
</div>
</div>
</div>
All the issue is related to the inner height:100% used on the .sub.container. Technically and considering the specification this height should fail to auto because the parent height isn't set BUT Firefox seems to be able to evalute this height. Probably due to the nested flex container where we can evaluate the parent height before knowing the content or simply a bug.
Chrome is not doing this and simply ignoring the height which is the logical behavior.
Maybe height: fit-content is what you're looking for? I'm a little confused on what your desired result is.
html, body {
height: 100%;
margin: 0;
padding: 0;
}
* {
box-sizing: border-box;
}
div {
padding: 10px;
}
.container {
display: flex;
flex-direction: column;
}
.content {
flex: 1;
max-height: 100%;
overflow: auto;
}
.root.container {
background-color: red;
max-height: 100%;
height: fit-content;
}
.sub.container {
background-color: purple;
height: 100%;
}
.root.header {
background-color: lightblue;
}
.sub.header {
background-color: lightgreen;
}
.root.content {
background-color: yellow;
}
.sub.content {
background-color: orange;
}
<div class="root container">
<div class="root header">header</div>
<div class="root content">
<div class="sub container">
<div class="sub header">menu</div>
<div class="sub content">
<ul>
<li>Item 1</li>
<li>Item 2</li>
<li>Item 3</li>
<li>Item 4</li>
<li>Item 5</li>
<li>Item 1</li>
<li>Item 2</li>
<li>Item 3</li>
<li>Item 4</li>
<li>Item 5</li>
<li>Item 1</li>
<li>Item 2</li>
<li>Item 3</li>
<li>Item 4</li>
<li>Item 5</li>
<li>Item 1</li>
<li>Item 2</li>
<li>Item 3</li>
<li>Item 4</li>
<li>Item 5</li>
<li>Item 1</li>
<li>Item 2</li>
<li>Item 3</li>
<li>Item 4</li>
<li>Item 5</li>
<li>Item 1</li>
<li>Item 2</li>
<li>Item 3</li>
<li>Item 4</li>
<li>Item 5</li>
<li>Item 1</li>
<li>Item 2</li>
<li>Item 3</li>
<li>Item 4</li>
<li>Item 5</li>
<li>Item 1</li>
<li>Item 2</li>
<li>Item 3</li>
<li>Item 4</li>
<li>Item 5</li>
<li>Item 1</li>
<li>Item 2</li>
<li>Item 3</li>
<li>Item 4</li>
<li>Item 5</li>
<li>Item 1</li>
<li>Item 2</li>
<li>Item 3</li>
<li>Item 4</li>
<li>Item 5</li>
<li>Item 1</li>
<li>Item 2</li>
<li>Item 3</li>
<li>Item 4</li>
<li>Item 5</li>
</ul>
</div>
</div>
</div>
</div>

Align elements in block with other elements in other block(list)

I have problem with aligning elemnts in div. I have following div:
<div class="lists-wrapper">
<div class="list">
<h4>List 1</h4>
<ul>
<li>item 1</li>
<li>item 2</li>
<li>item 3</li>
</ul>
</div>
<div class="list">
<h4>List 2</h4>
<ul>
<li>item 1</li>
<li>item 2</li>
<li>item 3</li>
<li>item 4</li>
<li>item 5</li>
</ul>
</div>
<div class="list">
<h4>List 3</h4>
<ul>
<li>item 1</li>
<li>item 2</li>
<li>item 3</li>
<li>item 4</li>
</ul>
</div>
<div class="list">
<h4>List 4</h4>
<ul>
<li>item 1</li>
<li>item 2</li>
<li>item 3</li>
<li>item 4</li>
<li>item 5</li>
</ul>
</div>
</div>
SCSS:
.lists-wrapper {
display: flex;
justify-content: space-between;
flex-wrap: wrap;
.list {
width: 20%;
}
h4 {
margin-bottom: 22px;
}
ul {
display: flex;
flex-direction: column;
flex-wrap: wrap;
margin-bottom: 35px;
margin-left: -5px;
}
}
I'm using React and jquery approaches doesn't work for me
The problem is that .list class blocks aligned properly to each other now but when for example h4 width is very long, it splits to the second line and ul doesn't aligned with other ul's in other list blocks because it goes down a bit because of changing the height of h4. I want alignment to work relatively to ul to other ul's in the row, is it possible to do?