Reputation: 65
I asked a question yesterday on setting up a flex layout for my scenario, Make inner div fill remaining height using flex, and it worked great in my larger project. I now am running into an issue where the items within that flex div extend past the page and the other container stretches further. I'd ideally like to have the items stay inside the container, and have the container have a scrollbar inside of it so the main portion of the page doesn't have to scroll - only the inside of the container. Any ideas why this doesn't work automatically?? I've tried moving some of the flex around and other various properties but no luck.
HTML/CSS:
<!DOCTYPE html>
<html>
<head>
<style>
*{
margin: 0;
padding: 0;
box-sizing: border-box;
}
.home-content {
display: flex;
border: 1px solid black;
height:100vh;
flex-flow: column;
}
.container {
flex: 1;
border: 1px solid red;
display: flex;
flex-direction: column;
}
#listItems {
border: 1px solid green;
height: 100%;
}
#listItems > ul {
display: flex;
flex-flow: row wrap;
list-style: none;
}
.item {
border: 1px solid purple;
width: 200px;
height: 200px;
margin-left: 4px;
}
</style>
</head>
<body>
<div class="home-section">
<div class="home-content">
<div class="container">
<form>
<label for="example">Input</label>
<input type="text" name="example">
</form>
<div id="listItems">
<ul>
<li class="item">Item</li>
<li class="item">Item</li>
<li class="item">Item</li>
<li class="item">Item</li>
<li class="item">Item</li>
<li class="item">Item</li>
<li class="item">Item</li>
<li class="item">Item</li>
<li class="item">Item</li>
<li class="item">Item</li>
<li class="item">Item</li>
<li class="item">Item</li>
<li class="item">Item</li>
<li class="item">Item</li>
<li class="item">Item</li>
<li class="item">Item</li>
<li class="item">Item</li>
<li class="item">Item</li>
<li class="item">Item</li>
<li class="item">Item</li>
<li class="item">Item</li>
<li class="item">Item</li>
<li class="item">Item</li>
<li class="item">Item</li>
<li class="item">Item</li>
<li class="item">Item</li>
<li class="item">Item</li>
<li class="item">Item</li>
<li class="item">Item</li>
<li class="item">Item</li>
<li class="item">Item</li>
<li class="item">Item</li>
<li class="item">Item</li>
<li class="item">Item</li>
<li class="item">Item</li>
<li class="item">Item</li>
<li class="item">Item</li>
<li class="item">Item</li>
</ul>
</div>
</div>
</div>
</div>
</body>
</html>
EDIT: Technically I don't want a scroll on the main portion of the page, but would like the div with the green border to not extend past the page and have the items in it not extend past its border as well as when there's lots of items that are more than its height, I can just scroll within that div of listItems
that has the green border. Kind of like if that listItems
div were to just be a photo gallery and can scroll inside of it to view all of the images
Upvotes: 2
Views: 3261
Reputation: 341
I just stumbled upon a similar situation earlier today, and I would like to share what worked for me.
Basically, we have a nested flexbox used to split the document in two parts, with the bottom part containing a list of items that should fill the screen but never go past it, a condition the code in question fails to enforce.
Now, in order to achieve this effect, we can make use of the <div>
containing the <ul>
list in order to setup a relative/absolute positioning combo.
position: relative;
to #listItems
. Currently, this <div>
element is taking up all the screen space it has available because of the flexbox it's part of, so it is a reliable anchor for positioning the <ul>
list.position: absolute; top: 0; bottom: 0; left: 0; right: 0;
to #listItems > ul
, in order to anchor our list to its container #listItems
; and then we add overflow: auto;
in order to allow for scrolling when necessary.This is how the result looks:
<!DOCTYPE html>
<html>
<head>
<style>
*{
margin: 0;
padding: 0;
box-sizing: border-box;
}
.home-content {
display: flex;
flex-flow: column;
border: 1px solid black;
height: 100vh;
}
.container {
flex: 1;
border: 1px solid red;
display: flex;
flex-direction: column;
}
#listItems {
border: 2px solid green;
height: 100%;
position: relative;
}
#listItems > ul {
display: flex;
flex-flow: row wrap;
list-style: none;
position: absolute;
top: 0; bottom: 0;
left: 0; right: 0;
overflow: auto;
}
.item {
border: 1px solid purple;
width: 200px;
height: 200px;
margin-left: 4px;
}
</style>
</head>
<body>
<div class="home-section">
<div class="home-content">
<div class="container">
<form>
<label for="example">Input</label>
<input type="text" name="example">
</form>
<div id="listItems">
<ul>
<li class="item">Item</li>
<li class="item">Item</li>
<li class="item">Item</li>
<li class="item">Item</li>
<li class="item">Item</li>
<li class="item">Item</li>
<li class="item">Item</li>
<li class="item">Item</li>
<li class="item">Item</li>
<li class="item">Item</li>
<li class="item">Item</li>
<li class="item">Item</li>
<li class="item">Item</li>
<li class="item">Item</li>
<li class="item">Item</li>
<li class="item">Item</li>
<li class="item">Item</li>
<li class="item">Item</li>
<li class="item">Item</li>
<li class="item">Item</li>
<li class="item">Item</li>
<li class="item">Item</li>
<li class="item">Item</li>
<li class="item">Item</li>
<li class="item">Item</li>
<li class="item">Item</li>
<li class="item">Item</li>
<li class="item">Item</li>
<li class="item">Item</li>
<li class="item">Item</li>
<li class="item">Item</li>
<li class="item">Item</li>
<li class="item">Item</li>
<li class="item">Item</li>
<li class="item">Item</li>
<li class="item">Item</li>
<li class="item">Item</li>
<li class="item">Item</li>
</ul>
</div>
</div>
</div>
</div>
</body>
</html>
This method was the one that worked for my particular use case. Compared to Caleb's, this approach is simpler and it relies on the flexbox sizing instead of several viewport height reads, so it can be used for viewports that don't fill the entire screen as well.
TL;DR: Just apply the sizing you want to a parent <div>
, then attach the positioning of your viewport to it by mixing relative and absolute positioning, and slap overflow: auto
on it to make it scroll.
Upvotes: 0
Reputation: 383
Here try this:
<!DOCTYPE html>
<html>
<head>
<style>
*{
margin: 0;
padding: 0;
box-sizing: border-box;
}
.home-section {
display: flex;
border: 3px solid black;
height:100vh;
flex-flow: column;
max-height: 99vh;
}
.container {
flex: 1;
border: 3px solid red;
display: flex;
flex-direction: column;
height: fit-content;
max-height: 99vh;
overflow: auto;
}
#listItems {
border: 3px solid green;
height: 99vh;
overflow-y: auto;
}
#listItems > ul {
display: flex;
flex-flow: row wrap;
list-style: none;
}
.item {
border: 3px solid purple;
width: 200px;
height: 200px;
margin-left: 4px;
}
</style>
</head>
<body>
<div class="home-section">
<div class="home-content">
<div class="container">
<form>
<label for="example">Input</label>
<input type="text" name="example">
</form>
<div id="listItems">
<ul>
<li class="item">Item</li>
<li class="item">Item</li>
<li class="item">Item</li>
<li class="item">Item</li>
<li class="item">Item</li>
<li class="item">Item</li>
<li class="item">Item</li>
<li class="item">Item</li>
<li class="item">Item</li>
<li class="item">Item</li>
<li class="item">Item</li>
<li class="item">Item</li>
<li class="item">Item</li>
<li class="item">Item</li>
<li class="item">Item</li>
<li class="item">Item</li>
<li class="item">Item</li>
<li class="item">Item</li>
<li class="item">Item</li>
<li class="item">Item</li>
<li class="item">Item</li>
<li class="item">Item</li>
<li class="item">Item</li>
<li class="item">Item</li>
<li class="item">Item</li>
<li class="item">Item</li>
<li class="item">Item</li>
<li class="item">Item</li>
<li class="item">Item</li>
<li class="item">Item</li>
<li class="item">Item</li>
<li class="item">Item</li>
<li class="item">Item</li>
<li class="item">Item</li>
<li class="item">Item</li>
<li class="item">Item</li>
<li class="item">Item</li>
<li class="item">Item</li>
</ul>
</div>
</div>
</div>
</div>
</body>
</html>
I made it where the container is not bigger than the screen height, by adding a max-height
. You can test it out by adding more code outside the container, and it will add another scrollbar. Also to change the max height go the the container and change the max height of it, and it will change the height. I made the borders a bit thicker so that it would be easier to visualize it.
Upvotes: 1
Reputation: 76
add overflow-flow: scroll; to .home-content/container and change the height on .home-content from 100vh to a pixel or percentage value. run the snippet
<!DOCTYPE html>
<html>
<head>
<style>
*{
margin: 0;
padding: 0;
box-sizing: border-box;
}
.home-content {
margin:0 auto;
width: 70%;
padding: 50px;
display: flex;
border: 1px solid black;
height:250px;
flex-flow: column;
overflow: scroll;
}
.container {
flex: 1;
border: 1px solid red;
display: flex;
flex-direction: column;
}
#listItems {
border: 1px solid green;
height: 100%;
}
#listItems > ul {
display: flex;
flex-flow: row wrap;
list-style: none;
}
.item {
border: 1px solid purple;
width: 200px;
height: 200px;
margin-left: 4px;
}
</style>
</head>
<body>
<div class="home-section">
<div class="home-content">
<div class="container">
<form>
<label for="example">Input</label>
<input type="text" name="example">
</form>
<div id="listItems">
<ul>
<li class="item">Item</li>
<li class="item">Item</li>
<li class="item">Item</li>
<li class="item">Item</li>
<li class="item">Item</li>
<li class="item">Item</li>
<li class="item">Item</li>
<li class="item">Item</li>
<li class="item">Item</li>
<li class="item">Item</li>
<li class="item">Item</li>
<li class="item">Item</li>
<li class="item">Item</li>
<li class="item">Item</li>
<li class="item">Item</li>
<li class="item">Item</li>
<li class="item">Item</li>
<li class="item">Item</li>
<li class="item">Item</li>
<li class="item">Item</li>
<li class="item">Item</li>
<li class="item">Item</li>
<li class="item">Item</li>
<li class="item">Item</li>
<li class="item">Item</li>
<li class="item">Item</li>
<li class="item">Item</li>
<li class="item">Item</li>
<li class="item">Item</li>
<li class="item">Item</li>
<li class="item">Item</li>
<li class="item">Item</li>
<li class="item">Item</li>
<li class="item">Item</li>
<li class="item">Item</li>
<li class="item">Item</li>
<li class="item">Item</li>
<li class="item">Item</li>
</ul>
</div>
</div>
</div>
</div>
</body>
</html>
Upvotes: 0
Reputation: 19
you can use
flex-wrap: wrap; this will keep everything under the limit of the screen size
Upvotes: 0
Reputation: 76
add a overflow: scroll; to the container you don't want overflown.
Upvotes: 0