Imagine having this situation: a simple 3 rows layout made with flexbox, with the central row filling all the space available. Pretty standard stuff.
<body>
<div class="container">
<div class="flex-container">
<div>header</div>
<div class="content">
<div class="item red">asdasd</div>
<div class="item yellow">asdasd</div>
<div class="item green">asdasd</div>
</div>
<div>footer</div>
</div>
<div>
<body>
Here the CSS:
html,
body,
.container {
height: 100%;
}
.flex-container {
height: 100%;
display: flex;
flex-direction: column;
}
.flex-container .content {
flex: 1;
}
.flex-container .content .item {
height: 100%;
}
(omitting css for background colors, you can guess it).
The problem is that the "content" div does not push down the footer div, keeping it at the bottom of the page, like is position:fixed with bottom: 0.
Scrolling the page show, except for this problem, the correct behavior, with 3 div with different color all sizing 100% the browser window.
What I'm missing?
EDIT: look at this jsfiddle
https://jsfiddle.net/rq1xywng/
I am not sure about what you are looking for. May be it will be help for you.
html,
body {
margin: 0;
padding: 0;
box-sizing: border-box;
height: 100vh;
min-height: 100vh;
}
.container {
height: 100vh;
min-height: 100vh;
background-color: fuchsia;
}
.header, .footer {
height: 30px;
}
.flex-container .content {
display: flex;
height: 100%;
height: calc(100vh - 60px);
}
.flex-container .content .item {
width: 100%;
height: 100%;
}
.red {
background-color: red;
}
.yellow {
background-color: yellow;
}
.green {
background-color: green;
}
<div class="container">
<div class="flex-container">
<div class="header">header</div>
<div class="content">
<div class="item red">asdasd</div>
<div class="item yellow">asdasd</div>
<div class="item green">asdasd</div>
</div>
<div class="footer">footer</div>
</div>
<div>
So you have couple of errors here:
you set EVERY ITEM IN THE CONTAINER to be 100% - this amounts to 300% :)
their parent is "only" 100%
footer will be hidden unless given height
you used vh and % combined in an unhealthy way.
you should have 2 flex components:
.flex-container - to match to screen size
.flex-container .content - to be able to stretch the items
You should set .item to flex: 1;
Here is a working version: https://jsfiddle.net/oj0thmv7/5/
Here is a working example with scroll: https://jsfiddle.net/oyLbxsrc/
If you change the 100% to 100vh this works
.flex-container .content .item {
height: 100vh;
}
Or have I misunderstood the issue?
Related
I have the following html layout:
<div class="wrapper">
<div class="row one">
<div class="col one"><!-- some content here --></div>
<div class="col two"><!-- some content here --></div>
</div>
<div class="row two"><!-- some content here --></div>
</div>
So I have two rows (content and footer) and the first row has two columns.
The footer's (row two) height is not set and is defined from it's content.
How can I force my content area (row one) to stretch so the entire wrapper div takes 100% of screen's height?
Some indicative (not working) css here:
.wrapper {
display: inline-block;
width: 100%;
height: 100%;
}
.row.one {
width: 100%;
display: flex;
}
.row.two {
width: 100%;
}
.row.one .col.one {}
.row.one .col.two {}
Setting the height of the wrapper to the height of the viewport, and then stretching the flexbox contents (column... not row) vertically has always worked well for me.
.wrapper {
display: flex;
flex-flow: column nowrap;
align-items: stretch;
height: 100vh;
width: 100vw; /* or whatever */
}
.row {
flex: auto;
width: 100%;
...
}
Try this:
.wrapper {
display: inline-block;
height: 100vh;
width: 100%;
}
.row.one {
display: flex;
height: 100%;
}
.row.two {
}
.row.one .col.one {}
.row.one .col.two {}
css viewheight will achieve what you want.
100vh applied to .row.one makes the div occupy the full visible height.
.row.one {
background: pink;
height: 100vh;
}
<div class="wrapper">
<div class="row one">
<div class="col one">some content here </div>
<div class="col two">some other content here </div>
</div>
<div class="row two">footer content</div>
</div>
image wireframe
I would like to recreate messaging phone app in html and css. So the app must be full frame without any overflow.
The trick is the bottom part (in red) must be resizable according to the child content. So I used flex (with flex-direction: column) to manage my layout.
The problem is : when the content (in yellow) grow up, the core part will compress the red part. My goal is to overflow, with a scrollbar, the content inside the core part and don't change the size of the red div.
index.html
<body>
<div id="header">
</div>
<div id="core">
<div class="conainer" style="">
<div class="row">
<div class="two columns"></div>
<div class="ten columns">
<div class="msgright">
.
</div>
</div>
</div>
<div class="row">
<div class="ten columns">
<div class="msgright">
.
</div>
</div>
<div class="two columns"></div>
</div>
</div>
</div>
<div id="footer">
</div>
index.css
html, body, div {
margin: 0;
padding: 0;
}
html, body {
height: 100%;
max-height: 100%;
overflow: hidden;
}
body {
display: flex;
flex-direction: column;
}
#header {
height: 50px;
background: #2A9D8F;
flex: 0 0 auto;
}
#core {
background-color: #264653;
flex: 1;
display: flex;
align-items: flex-end;
}
#footer {
height: auto;
background-color: red;
min-height: 50px;
flex: 0 0 auto;
}
.conainer {
flex: 0 0 100%;
}
.row {
margin: 5px;
background-color: yellow;
height: 130px;
}
https://codepen.io/jln_brtn/pen/pobVZBv
Best regards and thank you for your help.
I'm not sure if I understand the problem correctly but since your .row elements have a fixed height: 130px, the element should not be able to grow any further. Overflow styling to .row elements can be added like this:
.row {
overflow-y: scroll;
}
If it is just the #core element, then you can do something like this:
#core {
overflow-y: scroll;
}
For this instance I would suggest to use CSS Grid instead of Flexbox, and giving both <header> and <footer> the space they need, while the <main> gets the rest. This means that both <header> and <footer> stay were they are, even if <main> needs more space for its content, meaning <main> will get a scrollbar.
You can achieve the same by using position: fixed and setting a margin to top and bottom, with fixed heights of <header> and <footer>, and sizing <main> with height: calc(100% - HEIGHT_OF_HEADER - HEIGHT_OF_FOOTER). The problem with this is maintenance, as you would always have to check and revalidate the heights when changing something.
html, body {
margin: 0;
width: 100%;
height: 100%;
}
body {
display: grid;
grid-template-rows: auto 1fr auto;
}
header {
height: 3.125rem;
background: #2A9D8F;
}
main {
padding: 0.3125rem;
display: flex;
flex-flow: column;
gap: 0.3125rem;
background: #264653;
overflow: hidden auto;
}
footer {
height: 3.125rem;
background: red;
}
main > div {
flex-shrink: 0;
height: 8.125rem;
background: yellow;
}
<header></header>
<main>
<div></div>
<div></div>
<div></div>
<div></div>
<div></div>
<div></div>
</main>
<footer></footer>
I'm trying to create a table which will be responsive,
but to make it simple I want to make it scroll horizontally when it has too many columns.
.fixed-table-wrap {
display: flex;
flex-wrap: wrap;
overflow: hidden;
}
.fixed-column {
width: 140px;
}
.standard-column {
width: calc(100% - 140px);
overflow-x: auto;
}
.sc-content {
display: flex;
flex-wrap: wrap;
min-width: 1485px;
width: 100%;
}
<div class="fixed-table-wrap">
<div class="fixed-column">
<div class="fc-content">
</div>
</div>
<div class="standard-column">
<div class="sc-content">
<div class="child"></div>
<div class="child"></div>
<div class="child"></div>
<div class="child"></div>
</div>
</div>
</div>
In order to have the scroll effect I have to use min-width or a fixed width, but I don't want that because I want the table to be responsive, when it is not exceeding the window's width it should just be natural, and when it exceeds, it scrolls.
To get an even better idea of what my problem is:
What my table looks like:
More of what my table looks like:
What happens when I remove the min-width:
What happens when I have less content WITH min-width:
What happens when I have less content WITHOUT min-width:
Try using the CSS overflow-x property and set an element you've wrapped around your table to "scroll". So with HTML like this:
<div id="table-wrapper">
<table>
<!-- table content here -->
</table>
</div>
And CSS like this:
<style type="text/css">
#table-wrapper {
width: 100%;
x-overflow: scroll;
}
</style>
I've found my solution:
.fixed-table-wrap {
display: flex;
flex-wrap: wrap;
overflow: hidden;
width: fit-content;
}
.fixed-column {
width: 140px;
}
.standard-column {
width: calc(100% - 140px);
overflow-x: auto;
}
.sc-content {
display: flex;
flex-wrap: wrap;
width: max-content;
}
.child {
width:140px;
}
Refer to this Fiddle.
I have a top-level div whose height is configured as one screen height (height:100vh). Within this div, there is a fixed-height (60px) child div and another child div I want to grow to fill the remaining height (so as to be responsive with different screen sizes).
This child div has an image and some text. Currently, its width is hard-coded, or else the image fills the entire screen (and exceeds the length of its parent). Setting height:100% (or even calc(100% - 60px)) doesn't scale the div as I'd hoped.
.one-page {
min-height: 100vh;
max-height: 100vh;
background-color: #FF5555;
}
.fixed-size {
height: 60px;
border-style: solid;
}
.main-container {
background-color: #55FF55;
width: 300px;
margin: auto;
}
.subtitle {
text-align: center
}
.other {
background-color: blue;
}
img {
vertical-align: middle;
width: 100%;
height: auto;
}
<body>
<div class="one-page">
<div class="fixed-size">
this div is a fixed size
</div>
<div class="main-container">
<p>
<img src="http://images.clipartpanda.com/square-clip-art-clipart-square-shield-256x256-e296.png">
</p>
<div class="subtitle">
subtitle text
</div>
</div>
</div>
<div class="other">
something else
</div>
</body>
Try to use height:calc(100vh - 60px).
.main-container {
background-color: #ff00ff;
width: 300px;
margin: auto;
padding:0;
height:calc(100vh - 60px);
}
DEMO
Use flexbox to work it out. Run the below snippet and you'll understand. flex-grow: 1 will basically give all the remaining height to the second child.
.p {
height: 100vh;
display: flex;
flex-direction: column;
}
.c1 {
height: 60px;
background-color: green;
}
.c2 {
flex-grow: 1;
background-color: red;
}
<div class="p">
<div class="c1"></div>
<div class="c2"></div>
</div>
Maybe I want something impossible.
I want a website with only a single column styled with flexbox. The purpose is that only one column stretches its height to the footer regardless the size of the content of the column. Something like below structure:
I try to reach that with this code (I am using bootstrap):
<div class="container-fluid">
<div class="row">
<header class="col-md-12">
stuff...
</header>
<div class="col-md-1 col-a">
stuff...
</div>
<div class="col-md-10 col-b">
Stuff...
</div>
<div class="col-md-1 col-c">
<div class="col-c-child">
Stuff..
</div>
</div>
<footer class="col-md-12">
Stuff
</footer>
</div>
</div>
And then adding in the CSS this specific for the col-c and col-c-child:
.col-c {
display: flex;
flex-direction: column;
height: 100%;
}
.col-c-child {
flex: 1;
}
But is not working.
Any idea?
THE SOLUTION:
Create a row for the header, other for the content and other for the footer, that is - don't have everything in the same row.
Build a div-wrapper englobing col-a, col-b and col-c with display:flex and flex-direction: row;
get rid of col-c-child
col-c with flex: 1;
Thanks to #jelleB who elucidated me for part of it.
Put the header and the footer in different rows.
You should build a div below col-a (without content)
Use min-height: 100% on the row where you put col-a/col-b/col-c in
Give this a shot
I suspect your problem lies in the height:100%
If I am not mistaken, you cannot do that unless the parent container has its height defined. If the parent container's height is also defined as a percentage then the parent's parent container's height must also be defined. This hierarchy continues up to the body tag.
If you are able to wrap your middle divs, you can do the following:
html,
body {
height: 100%;
padding: 0;
margin: 0;
}
.container {
display: flex;
flex-direction: column;
height: 100%;
width: 100%;
}
.container #body {
display: flex;
flex-direction: row;
flex-grow: 1;
}
header,
footer {
width: 100%;
}
.left,
.right {
width: 100px; /*change to whatever width you want*/
}
.center {
flex-grow: 1;
}
/*styles for demo*/
header,
footer {
height: 50px;
background: blue;
}
.left,
.right {
background: green;
}
.center {
background: red
}
<div class="container">
<header></header>
<div id="body">
<div class="left"></div>
<div class="center"></div>
<div class="right"></div>
</div>
<footer></footer>
</div>