How to make flex container fill browser window height (with scrolling complications) - html

I have a flex container <main> between a <header> and a <footer>, and in that container I have a number of columns. I have set up horizontal scrolling of <main> to hanle the case of too many columns to display at once, and I've also enabled vertical scrolling on a sub-division of the columns. The intent is that the header is anchored at the top of the window, the footer at the bottom of the window, and the space between is used to display the columns, with scrolling as needed.
<header>HEADER</header>
<main class="columns">
<div class="column">
<h3>column 1</h3>
<div class="content">
long content that would scroll
</div>
</div>
<div class="column"><h3>col2</h3><div class="content">...</div></div>
<div class="column"><h3>col3</h3><div class="content">...</div></div>
<div class="column"><h3>col4</h3><div class="content">...</div></div>
<div class="column"><h3>col5</h3><div class="content">...</div></div>
</main>
<footer>FOOTER</footer>
/* trimmed css */
header,
footer { }
main {
display: flex;
column-gap: 3px;
width: 100%;
height: 600px;
overflow-x: auto;
}
.column {
width: 200px;
min-width: 200px;
}
.column .content {
height: 570px;
overflow-y: scroll;
}
I've got most of all that working here https://codepen.io/ericscheid/pen/mdMwyEE
The demo currently hard-codes a height: 600px; for the columns. (Also the div.column div.content is set to height: 570px;, which is an unsatisfactory magic number hack to get scrolling working right, and which breaks if any of the div.column h3 elements spills onto two lines.)
However, I can't figure out how to get the columns container element to fill the available height of the browser window. I've tried setting various heights to 100%, setting using display:inline-block ... but at this point I'm only poking guesses into a black box.
How can I get the columns to fill the available height? And have the scolling work correctly (e.g. if any have an extra large <h3>). (I'd rather not involve javascript to dynamically calculate heights, etc, if at all reasonably possible).

Related

CSS/Bootstrap: fixed max-width for content layout

I have noticed, that many websites (SO included) don't shrink to the whole width of the screen, preferring to render content column either of fixed-width or setting max-width property for it. Merriam-Webster dictionary website is a good example for the latter.
Is it possible to create such a layout using Bootstap? I have managed to limit content column width inside it's col-8-md div, but there is a huge gap between content and right sidebar on big displays now.
Live demo: https://codepen.io/anon/pen/dNprzm
HTML:
<div class="row">
<div class="col-md-8">
<div class="content-block">
CONTENT
</div>
</div>
<div class="col-md-4 right-bar">
RIGHT_BAR
</div>
</div>
CSS:
.content-block {
height: 1000px;
max-width: 1000px;
background-color: lightgreen;
margin-left: auto;
margin-right: auto;
}
.right-bar {
background-color: pink;
width: 400px;
}
If I'm understanding your question correctly, you just want to be sure to have a fixed width for your content but get rid of the space that's happening to the right of it on large screens?
Remove your margin-right: auto;. Once you get to a screen size where it's larger than 1000px, it's trying to "center" your .content-block

How do i force a table row with 100% width to use a scroll bar if it's children are overflowing?

I have a CSS layout problem. Here's a fiddle
I want a header and footer on the page, with the "content" taking up the rest of the available space. I was doing it with a JQUery plugin that calculated and set the height of the relevant element, but it wasn't playing nicley with some knockout things i had going on on the page so I decided screw that and use CSS.
Setting the sections to be table rows seemed to solve the problem of vertical expansion and the whole thing now nicley fills the page, but i have a table which is causing some issues.
When it has data in it it expands the width of the columns (i don't want the text to wrap). And that means the width of my wrappers also expand (thanks tables) I can't seem to hang a scrollbar on anywhere to prevent it happening.
My question is two fold:
Is there a better way of achieving the header/footer thing?
Can i get my scroll bar back?
The ideal solution would be in CSS rather than using JavaScript. I must support all browsers, including IE down to IE 8, and preferably IE 7.
The HTML:
<body>
<div class="page-wrapper">
<div class="section-wrapper">
<P>I want this at the top</P>
</div>
<div class="content-section section-wrapper">
<P>This is in the middle - taking up all the remaining space.</P>
<P>Making the wrapper a table-row solves the problem nicely...</P>
<div class="table-wrapper">
<table>
<thead>...</thead>
<tbody>
<tr>
But: In this table I have some data which causes the table to overflow the edge of the screen.
</tr>
<tr>
How do I make it have a scroll bar instead?
</tr>
</tbody>
</table>
<p>Ideally the scroll bar would go at the bottom of this section.</p>
</div>
</div>
<div class="section-wrapper">
<P>This goes at the bottom</P>
</div>
</div>
</body>
The CSS:
body, html{
width: 100%;
height: 100%;
}
.page-wrapper{
display: table;
height: 100%;
}
.section-wrapper{
display: table-row;
width: 100%;
background-color: lightGrey;
}
.content-section.section-wrapper{
height: 100%;
background-color: white;
}
table{
white-space: nowrap;
border-spacing: 20px 0;
border-collapse: separate;
}
.table-wrapper{
overflow: auto;
display: inline-block;
}
You could set a max width of the wrapper to the screen with, and make it a block display, then it should show a scroll bar if the table is wider than the available screen. Not sure if that was your question.
.table-wrapper{
max-width: 100vw;
overflow: auto;
display: block;
}
Also, to have the footer at the bottom, you could use flexbox on the page-wrapper.
.page-wrapper {
height: 100vh;
display: flex;
flex-flow: column nowrap;
}
.section-wrapper {
flex-grow: 1;
}
Updated fiddle: https://jsfiddle.net/211sgmjv/

CSS column layout - DIV with dynamic width and same height as sibling

I've really hit the wall on this one and need some help. I'm trying to create a two column layout with both widths and heights adjusted to the contents of the left column. It seems to be a rather basic layout, but I'm starting to think it can't be done (without resorting to JS).
This fiddle describes what I'm trying to do. It's a container DIV with two DIVs inside, aligned horizontally. The left inner DIV should adjust its size (both width and height) to its content. The right inner DIV (which contains a Google Map) should have the same height as the left one while filling up the remaining width of the container.
<div id="container">
<div id="left">
This DIV should adjust<br/>
both its width and height<br/>
to its content, not taking up<br/>
more space than needed!<br/>
<br/><br/><br/>
More content here...
</div>
<div id="right">
Google Map here.
</div>
</div>
I've tried everything I know and all tricks I've found, but no success!
#container {
background-color: #EEE;
overflow: hidden;
}
#container div {
border: 1px solid black;
padding: 5px;
}
#left {
background-color: lightblue;
display: inline-block;
float: left;
}
#right {
background-color: lightgreen;
height: 100%; /* THIS IS WHAT I WANT, BUT IT WON'T WORK, OF COURSE */
overflow: hidden;
}
I've found many similar questions, but in all those cases the left DIV/column had a fixed width, which makes it a whole lot easier.
Any input is much appreciated, especially if it works in IE9+ (and modern browsers)!
Edit
Some clarification. The purpose of the right column is to hold a Google map and consequently the map is supposed to fill up the entire DIV. Try setting a fixed height (e.g. 100px) for #right in the fiddle that I link to above and you will see the map showing up.
jsfiddle demo
css :
.container {
overflow: hidden;
background-color: #EEE;
}
.column {
float: left;
background-color: grey;
padding-bottom: 1000px;
margin-bottom: -1000px;
}
p {
padding: 10px;
margin-top: 10px;
width: 50%;
}
html
<script src="//maps.googleapis.com/maps/api/js?sensor=false"></script>
<div class="container">
<div class="column">
This DIV should adjust<br/>
both its width and height<br/>
to its content, not taking up<br/>
more space than needed!<br/>
<br/><br/><br/>
More content here...
</div>
<div class="column">
<div id="map"></div>
</div>
</div>
<p>
The right DIV (which contains a Google Map)
should be the same height as the left DIV,
while filling up the remaining width.
</p>
<p>How to do that?</p>
Here what I came up with -> link
When you remove the overflow property of your #right div it stretches as expected. However in this case you won't be able to hide the overflowed content.
CSS
#right {
background-color: lightgreen;
height: 100%; /* THIS WON'T WORK */ // height works as expected
}

DIV not taking parent height 3 columns

<div class='main_container' style='overflow:hidden; height:100%; height: auto !important; min-height:100%; width:100%;'>
<div class='float_left' style='width:100px; height:100%;'>
</div>
<div class='float_right' style='width:100px;'>
</div>
<div class='clear'></div>
<div class='content'>
//elastic content that sometimes makes the page longer or shorter
</div>
</div>
No matter how many tutorials or examples I looked at, nothing is helping me. I've tried many different combinations. As soon as I set main_container to a px height, the sidebars then, correctly, take up 100% of the height. But I can't set a px height for the main container.
EDIT:
example
The content box will not have a static height. So far what happens is that main_container adjusts it's height based on the content box, but the two sidebars don't adjust there height based on the main_containers height.
In addition to Adrift's answer, you are also overriding the height: 100% with the following height: auto !important - the latter overrides the height setting, even though it is not the source of the problem.
Here is a Gist that works on Chrome and most likely also on other modern browsers as well.
This solution uses CSS tables cells that allow the left/right sidebars to take on the height of the central .content panel.
The HTML:
<div class='main_container'>
<div class='left_bar'></div>
<div class='content'>
<p>Elastic content that sometimes makes the page longer or shorter</p>
<p>Lorem ipsum dolor sit amet, ...</p>
</div>
<div class='right_bar'></div>
</div>
The CSS:
.main_container {
display: table;
width: 100%;
}
.left_bar {
display: table-cell;
width: 100px;
background-color: lightgray;
}
.right_bar {
display: table-cell;
width: 100px;
background-color: lightgreen;
}
.content {
padding: 0 20px;
}
Demo Fiddle: http://jsfiddle.net/audetwebdesign/zahPD/
As suggested in other comments, you can specify height: 100% or height: inherit to .main_container as required in your application.
Reference for table-cell: https://developer.mozilla.org/en-US/docs/Web/CSS/display
Backwards Compatibility
Works with IE8 and above.
Div not supports height in percent using xhtml document. You use a trick like this:
.main_container{
position:fixed;
top:0;bottom:0;
right:0;left:0;
}
I've write an example here: http://jsfiddle.net/vF6fY/ take a look to it

How do you make CSS repeat-y repeat over a dynamic height?

I have the following HTML and CSS:
<div class="content">
<div class="leftbg"></div>
<div class="innercontent"><p>Some content goes here</p></div>
<div class="rightbg"></div>
</div>
.content {
overflow: hidden;
}
.leftbg {
background: url("./leftbg.png") repeat-y scroll top left transparent;
margin-left: 0;
float: left;
width: 10px;
}
.innercontent {
width: 600px;
float: left;
margin-left: 0;
}
.rightbg { /* similar to left bg except for the right side */ }
The problem that I am having is the leftbg image is only repeating until it reaches the height of the paragraph in the innercontent div. I am accessing a database to grab the content for the innercontent div and hence the content will be of variable height. Is there any way to make it so that it repeats until it reaches the bottom of the leftbg (and rightbg) div? What I mean by that is for it to repeat until it is at the bottom of the innercontent div without setting the height as static (e.g. height: 200px;) because the height will be variable.
This equal height column layout tutorial from smashing magazine might help you. With lot of explanation of all the whys.
I think the problem you are facing is that leftbg and rightbg don't have any content. The height of the <div class="content"> element equals the height of it's "tallest" child (innercontent in this case).
Maybe if you post a mockup of what you want as a final result I can help you further. Also, the markup would be helpful.