Flexbox child expands container instead of overflowing - html

I'm trying to create a layout using flexbox but I'm stumped as to why I can't force a particular section of my UI to overflow with scrollbars. Everything seems to work great until a large child is added which seems to expand everything.
Here's the pen: http://codepen.io/tuckwat/pen/NNWRaB?
Notice that scrollbars appear on the whole page, I want scrollbars to appear on the #view container (dark blue) when a child gets too big.
Here's a pen with the overflow: auto added to #view - http://codepen.io/tuckwat/pen/VawKyp
How can I get this layout to work? I don't want to use absolute positioning on the view because the sidebar or appbar can dynamically resize.
HTML
<div id="body">
<div id="appbar">appbar</div>
<div id="main">
<div id="sidebar">side</div>
<div id="content">
<div id="navbar">nav</div>
<div id="view">
This view container should scroll
<div id="view-content">
This content makes the view grow too large
</div>
</div>
</div>
</div>
</div>
CSS
#body{
background: #ccc;
display:flex;
flex-direction: column;
position:absolute;
left: 0px;
right: 0px;
bottom: 0px;
top:0px;
}
#appbar{
height:55px;
}
#main{
display: flex;
flex:1;
background: #ddd;
}
#sidebar{
height:100%;
background:#660099;
width:50px;
flex-shrink:0;
}
#content{
display:flex;
flex:1;
flex-direction:column;
}
#navbar{
height:20px;
background:#3cd;
}
#view{
flex:1;
background:#126;
overflow: auto;
}
#view-content{
width:1500px;
height:1500px;
background: #ff6600;
}

Another wrinkle... I found a similar blog post that outlines the issue with a solution: http://geon.github.io/programming/2016/02/24/flexbox-full-page-web-app-layout
When applied to my codepen it works great in Chrome and IE but scrollbars don't show up in Firefox. I thought the days of fighting browser quirks were over...
http://codepen.io/tuckwat/pen/qZBrya
#body{
overflow: hidden;
...
}
#content{
overflow: hidden;
...
}
Finally - solution
I was close, but Firefox requires min-height on Flexbox items. Here's a pen that works across IE, Chrome, and Firefox: http://codepen.io/tuckwat/pen/oxNZJW

This is rather odd.
All three of your codepens are missing "overflow: auto;" for the view class. Adding it adds does exactly what you wanted, as shown in the absolutely positioned codepen.
What browser are you using?
(I would do this in a comment, but I don't have enough rep yet.)

Related

Place DIV in new column when end of page reached

I have some DIVs on a page. How can I make the DIVs create a new column on the right when the bottom of the page is reached. So I have some small fixed height DIVs with images inside them. After every DIV, there is a line and then the next div and so on. On smaller displays, the screen requires scrolling to see the DIVs. So I added overflow: hidden to the body, to disable the scrolling. Now the DIVs at the very bottom are cut out, so I want the DIVs that are cut out, to create a new column to the right.
Example: .
body {
overflow: hidden;}
#icon {
background: #000;
color:#fff;
height:50px;
width:50px;
}
<body>
<div id=icon>1</div><br>
<div id=icon>2</div><br>
<div id=icon>3</div><br>
<div id=icon>4</div><br>
<div id=icon>5</div><br>
<div id=icon>6</div><br>
<div id=icon>7</div><br>
<div id=icon>8</div><br>
<div id=icon>9</div>
There's a lot of solutions to this and all run into polyfill issues. Columns are notorious for this.
A good option with decent coverage is to use flexboxes. Flexboxes were pretty much made for this kind of stuff.
Wrap all the divs in another div (i used section) and give the wrapping container some flexbox rules:
body {
overflow: hidden;}
.wrap {
display: flex;
flex-direction: column;
flex-wrap: wrap;
height: 100vh; /*the height will need to be customized*/
width: 50px;
}
#icon {
background: #000;
color:#fff;
height:50px;
width:50px;
margin-left: 10px;
}
<section class="wrap">
<div id=icon>1</div><br>
<div id=icon>2</div><br>
<div id=icon>3</div><br>
<div id=icon>4</div><br>
<div id=icon>5</div><br>
<div id=icon>6</div><br>
<div id=icon>7</div><br>
<div id=icon>8</div><br>
<div id=icon>9</div>
</section>
You'll need to give height and width rules to the wrapper, however. If it's in another container with a set height, you should be able to give it height: 100% and it will reach the bottom of the page.
Word of warning: columns and flexboxes are notorious for having cross-browser compatability issues, though mobile browsers are somewhat better at this. A good solution is to use a library with a focus on responsive or mobile design, like Bootstrap or SpaceBase (though the latter is a SASS library)
#samuel-denty are you looking for CSS Columns ?
here is jsfiddle: https://jsfiddle.net/zk7578vj/
try using class (.) icon instead of id (#) on css, like this:
body {
overflow: hidden;
-webkit-columns: 50px 2;
-moz-columns: 50px 2;
columns: 50px 2;
}
.icon {
background: #000;
color:#fff;
height:50px;
width:50px;
}
<body>
<div class="icon">1</div><br>
<div class="icon">2</div><br>
<div class="icon">3</div><br>
<div class="icon">4</div><br>
<div class="icon">5</div><br>
<div class="icon">6</div><br>
<div class="icon">7</div><br>
<div class="icon">8</div><br>
<div class="icon">9</div>
</body>

Cannot hide scroll, though overflow is hidden?

<div class="main">
<div class="content">
<div class="left_container">
</div>
</div>
</div>
In the code above, I have added a scroll to the left_container div.
But I want to hide it! Referring to other questions and answer, I found out to set overflow:hidden in the parent div class.
But still the scroll is not hidden in the child class?
CSS:
.content
{
background-color: white;
width:100%;
height:auto;
margin-top:10%;
position: absolute;
overflow: hidden;
}
.left_container
{
background-color:;
margin-left:5%;
margin-top:5%;
width:70%;
height:1000px;
overflow:auto;
}
Well I have also tried to set it hidden in the body! still not working..?
There is actually a simple way.
.left_container { overflow: hidden }
Now give left_container a child div and apply the following styles
.left_container-child {
height: 100%;
overflow-x: scroll;
width: 101%;
}
What this does is push the scrollbar out of sight.
You really want to check this over on differnet browsers and make sure you get the sweet spot that your content doesnt get cut off.
You can see a working example here (change the width on left_container-child to experiment pushing the scrollbar out).
Example
You have not used overflow:hidden in .left_container.
Try:
.left_container {
background-color:;
margin-left:5%;
margin-top:5%;
width:70%;
height:1000px;
overflow:hidden;
}
I think can't hide scroll bar for overflow hidden content.
you can try using scroll bar plugin http://nicescroll.areaaperta.com/demo.html

Body and html height 100% makes appear scrollbars

I know this questionhas already been asked, but the solutions I found don't work. Here is my code :
body, html {
height: 100%;
background-color: white;
}
body {
margin: 0;
padding: 0;
}
The problem is that a vertical scrollbar appears... Have you got any idea of how I could resolve this ?
Thank you in advance
You can prevent scrollbars appearing on any element with the following css:
overflow: hidden
There is a 'hackish' way of doing it without using overflow:hidden; if you want to know but I think overflow:hidden itself is already good enough. Check out the code : http://jsfiddle.net/rj3jecc1/
<div class="container">
<div class="content">Content</div>
<div class="content">Content</div>
<div class="content">Content</div>
</div>
body,html{
height:100%;
margin:0;
padding:0;
}
body{
background:#ddd;
}
.container{
padding-top:1px;
}
.content{
background:#fff;
padding:20px;
margin:20px;
}
The problem when you set the body to 100% height is, if you have an immediate child container with margin-top, it will 'push' and exceed the 100% height, causing a scrollbar to appear. That's why I have added another container with 1px (or even 0.1 as long as it's > zero) top padding to prevent that and this solution works across latest version of major browsers.
I don't know why you need the body height to be 100% but I would try not to specify its height unless I know my content will be too 'short' to fit through the height (which isn't a common scenario).

3 row layout in CSS

I need to get 3 row layout in HTML + CSS in my Angular.js app.
It should work like this:
My problem is when I resize my middle div get onto my top bar.
Here's some of my code:
.top-pos {
&.small {
padding-bottom: 130px;
}
&.big {
padding-bottom: 170px;
}
}
.bottom-pos {
bottom: 10px;
right: 0;
width: 100%;
position: absolute;
}
.middle {
#include align(vertical);
width: 100%;
}
HTML
<div class="top-pos small">
<div class="position-container">
<div class="top">
<h1 class="title">Some title</h1>
</div>
<div class="middle">
<input type="text" />
<input type="text" />
</div>
</div>
</div>
<div class="bottom-pos">
<button class="submit">Search</button>
</div>
Generally the top bar div should be always on top of the page, the bottom bar should be ALWAYS on bottom and the middle should be always on the middle between top and bottom bar. And the scrollbar should appear when all the elements are like on the second picture.
If older browser support is not an issue you could use css3 flex box to achieve something like this (not exact replica of the images):
#container{
display:flex;
flex-flow:column;
justify-content:space-around;
align-items:center;
width:50%;
height:100%;
}
#container div {
width:90%;
color:#fff;
background:black;
}
#top,#bottom{
height:50px;
}
#middle{
height:100px;
}
Demo
I have created a Fiddle which uses media queries to solve your problem. Hope that helps
CSS:
#media (min-width:400px) {
.top,.middle{
margin-bottom:20px
}
}
#media (max-width:399px) {
.top,.middle{
margin-bottom:2px;
}
h1{
margin:0;
}
}
For creating grid-like layouts that respond to window size changes, you should really consider Bootstrap. It allows you to very easily define layouts that are responsive to the window size. It also really nicely works together with Angular, since Angular defined directives that replace the Javascript part of Bootstrap. However, if you are only interested in the Grid layout part of Bootstrap, you do not need any Javascript at all, since it is all defined in CSS. See this link for more info on the Grid layout of Bootstrap:
http://getbootstrap.com/examples/grid/

How can an html element fill out 100% of the remaining screen height, using css only?

I have a header element and a content element:
#header
#content
I want the header to be of fixed height and the content to fill up all the remaining height available on the screen, with overflow-y: scroll;.
It this possible without Javascript?
forget all the answers, this line of CSS worked for me in 2 seconds :
height:100vh;
1vh = 1% of browser screen height
source
For responsive layout scaling, you might want to use :
min-height: 100vh
[update november 2018]
As mentionned in the comments, using the min-height might avoid having issues on reponsive designs
[update april 2018] As mentioned in the comments, back in 2011 when the question was asked, not all browsers supported the viewport units.
The other answers were the solutions back then -- vmax is still not supported in IE, so this might not be the best solution for all yet.
The trick to this is specifying 100% height on the html and body elements.
Some browsers look to the parent elements (html, body) to calculate the height.
<html>
<body>
<div id="Header">
</div>
<div id="Content">
</div>
</body>
</html>
html, body
{
height: 100%;
}
#Header
{
width: 960px;
height: 150px;
}
#Content
{
height: 100%;
width: 960px;
}
Actually the best approach is this:
html {
height:100%;
}
body {
min-height:100%;
}
This solves everything for me and it helps me to control my footer and it can have the fixed footer no matter if page is being scrolled down.
Technical Solution - EDITED
Historically, 'height' is tricky thing to mold with, compared to 'width', the easiest. Since css focus on <body> for styling to work. The code above - we gave <html> and <body> a height. This is where magic comes into picture - since we have 'min-height' on playing table, we are telling browser that <body> is superior over <html> because <body> holds the min-height. This in turn, allows <body> to override <html> because <html> had height already earlier. In other words, we are tricking browser to "bump" <html> off the table, so we could style independently.
You can use vh on the min-height property.
min-height: 100vh;
You can do as follows, depending on how you are using the margins...
min-height: calc(100vh - 10px) //Considering you're using some 10px margin top on an outside element
The accepted solution will not actually work.
You will notice that the content div will be equal to the height of its parent, body.
So setting the body height to 100% will set it equal to the height of the browser window. Let's say the browser window was 768px in height, by setting the content div height to 100%, the div's height will in turn be 768px. Thus, you will end up with the header div being 150px and the content div being 768px. In the end you will have content 150px below the bottom of the page. For another solution, check out this link.
With HTML5 you can do this:
CSS:
body, html{ width:100%; height:100%; padding: 0; margin: 0;}
header{ width:100%; height: 70px; }
section{ width: 100%; height: calc(100% - 70px);}
HTML:
<header>blabablalba </header>
<section> Content </section>
For me, the next worked well:
I wrapped the header and the content on a div
<div class="main-wrapper">
<div class="header">
</div>
<div class="content">
</div>
</div>
I used this reference to fill the height with flexbox. The CSS goes like this:
.main-wrapper {
display: flex;
flex-direction: column;
min-height: 100vh;
}
.header {
flex: 1;
}
.content {
flex: 1;
}
For more info about the flexbox technique, visit the reference
Please let me add my 5 cents here and offer a classical solution:
html {height:100%;}
body {height:100%; margin:0;}
#idOuter {position:relative; width:100%; height:100%;}
#idHeader {position:absolute; left:0; right:0; border:solid 3px red;}
#idContent {position:absolute; overflow-y:scroll; left:0; right:0; border:solid 3px green;}
<div id="idOuter">
<div id="idHeader" style="height:30px; top:0;">Header section</div>
<div id="idContent" style="top:36px; bottom:0;">Content section</div>
</div>
This will work in all browsers, no script, no flex. Open snippet in full page mode and resize browser: desired proportions are preserved even in fullscreen mode.
Note:
Elements with different background color can actually cover
each other. Here I used solid border to ensure that elements are placed
correctly.
idHeader.height and idContent.top are adjusted to include border,
and should have the same value if border is not used. Otherwise
elements will pull out of the viewport, since calculated width does
not include border, margin and/or padding.
left:0; right:0; can be replaced by width:100% for the same
reason, if no border used.
Testing in separate page (not as a snippet) does not require any
html/body adjustment.
In IE6 and earlier versions we must add padding-top and/or
padding-bottom attributes to #idOuter element.
To complete my answer, here is the footer layout:
html {height:100%;}
body {height:100%; margin:0;}
#idOuter {position:relative; width:100%; height:100%;}
#idContent {position:absolute; overflow-y:scroll; left:0; right:0; border:solid 3px green;}
#idFooter {position:absolute; left:0; right:0; border:solid 3px blue;}
<div id="idOuter">
<div id="idContent" style="bottom:36px; top:0;">Content section</div>
<div id="idFooter" style="height:30px; bottom:0;">Footer section</div>
</div>
And here is the layout with both header and footer:
html {height:100%;}
body {height:100%; margin:0;}
#idOuter {position:relative; width:100%; height:100%;}
#idHeader {position:absolute; left:0; right:0; border:solid 3px red;}
#idContent {position:absolute; overflow-y:scroll; left:0; right:0; border:solid 3px green;}
#idFooter {position:absolute; left:0; right:0; border:solid 3px blue;}
<div id="idOuter">
<div id="idHeader" style="height:30px; top:0;">Header section</div>
<div id="idContent" style="top:36px; bottom:36px;">Content section</div>
<div id="idFooter" style="height:30px; bottom:0;">Footer section</div>
</div>
You can also set the parent to display: inline. See http://codepen.io/tommymarshall/pen/cECyH
Be sure to also have the height of html and body set to 100%, too.
The accepted answer does not work. And the highest voted answer does not answer the actual question. With a fixed pixel height header, and a filler in the remaining display of the browser, and scroll for owerflow. Here is a solution that actually works, using absolute positioning. I also assume that the height of the header is known, by the sound of "fixed header" in the question. I use 150px as an example here:
HTML:
<html>
<body>
<div id="Header">
</div>
<div id="Content">
</div>
</body>
</html>
CSS:(adding background-color for visual effect only)
#Header
{
height: 150px;
width: 100%;
background-color: #ddd;
}
#Content
{
position: absolute;
width: 100%;
top: 150px;
bottom: 0;
background-color: #aaa;
overflow-y: scroll;
}
For a more detailed look how this works, with actual content inside the #Content, have a look at this jsfiddle, using bootstrap rows and columns.
In this instance I want my main content div to be liquid height so that the whole page takes up 100% of the browser height.
height: 100vh;
Unless you need to support IE 9 and below, I would use flexbox
body { display: flex; flex-direction: column; }
.header { height: 70px; }
.content { flex: 1 1 0 }
You also need to get body to fill the whole page
body, html{ width:100%; height:100%; padding: 0; margin: 0;}
CSS PLaY | cross browser fixed header/footer/centered single column layout
CSS Frames, version 2: Example 2, specified width | 456 Berea Street
One important thing is that although this sounds easy, there's going to be quite a bit of ugly code going into your CSS file to get an effect like this. Unfortunately, it really is the only option.
#Header
{
width: 960px;
height: 150px;
}
#Content
{
min-height:100vh;
height: 100%;
width: 960px;
}
The best solution I found so far is setting a footer element at the bottom of the page and then evaluate the difference of the offset of the footer and the element we need to expand.
e.g.
The html file
<div id="contents"></div>
<div id="footer"></div>
The css file
#footer {
position: fixed;
bottom: 0;
width: 100%;
}
The js file (using jquery)
var contents = $('#contents');
var footer = $('#footer');
contents.css('height', (footer.offset().top - contents.offset().top) + 'px');
You might also like to update the height of the contents element on each window resize, so...
$(window).on('resize', function() {
contents.css('height', (footer.offset().top -contents.offset().top) + 'px');
});
Have you tried something like this?
CSS:
.content {
height: 100%;
display: block;
}
HTML:
<div class=".content">
<!-- Content goes here -->
</div>