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>
Related
When creating my dashboard with flexbox css html, I have a scroll problem for example:
In the middle red container if I make it vertical the horizontal one does not work well for me opteniendo results like it expands the container descuadrando the design.
If I work the horizontal scroll does not work the vertical scroll expanding this.
I want it to work like this in the following image:
Desired result
I have tried many things with the flexbox like setting the height or width to 100% and even forcing the scroll, but I can't get the expected effect.
Your question is a bit broad, you should post your current solution next time to see which part is not working. For example, I couldn't really tell if the vertical scrollbar in the middle region is supposed to scroll the top or the middle part. Anyways, if you're set on using flexboxes, here's a way to do it:
body {
margin: 0;
}
main {
display: flex;
width: 100vw;
height: 100vh;
}
.left {
width: 20%;
background-color: cornflowerblue;
}
.left__header {
background-color: lightblue;
}
.middle {
display: flex;
flex-direction: column;
width: 40%;
background-color: salmon;
}
.middle__header {
flex-shrink: 0;
overflow-y: auto;
background-color: lightpink;
}
.middle__body {
overflow-x: auto;
}
.middle__footer {
margin-top: auto;
background-color: white;
}
.right {
width: 40%;
background-color: lightgreen;
}
<main>
<div class="left">
<div class="left__header">1</div>
<div class="left__body"></div>
</div>
<div class="middle">
<div class="middle__header">
<!-- Fixed width to simulate overflowing content -->
<div style="min-width: 2000px">1 2 3 4 5</div>
</div>
<div class="middle__body">
<!-- Fixed height to simulate overflowing content -->
<div style="min-height: 2000px">Content</div>
</div>
<div class="middle__footer">
Pia de Pagina
</div>
</div>
<div class="right">
SideBar Right
</div>
</main>
But if you don't plan on dynamically adding/removing elements or moving stuff around in the base layout (i.e. these regions stay the same during the use of the application) I'd recommend using CSS grid instead:
body {
margin: 0;
}
main {
display: grid;
grid-template:
"left-header middle-header right" min-content
"left-body middle-body right"
"left-body middle-footer right" min-content / 2fr 4fr 4fr;
width: 100vw;
height: 100vh;
}
.left__header {
grid-area: left-header;
background-color: lightblue;
}
.left__body {
grid-area: left-body;
background-color: cornflowerblue;
}
.middle__header {
grid-area: middle-header;
overflow-x: auto;
background-color: lightpink;
}
.middle__body {
grid-area: middle-body;
overflow-y: auto;
background-color: salmon;
}
.middle__footer {
grid-area: middle-footer;
background-color: white;
}
.right {
grid-area: right;
background-color: lightgreen;
}
<main>
<div class="left__header">1</div>
<div class="left__body"></div>
<div class="middle__header">
<!-- Fixed width to simulate overflowing content -->
<div style="min-width: 2000px">1 2 3 4 5</div>
</div>
<div class="middle__body">
<!-- Fixed height to simulate overflowing content -->
<div style="min-height: 2000px">Content</div>
</div>
<div class="middle__footer">
Pia de Pagina
</div>
<div class="right">
SideBar right
</div>
</main>
This results in the same output, but the HTML/CSS is much more readable IMO. It uses the grid-template property, which is fairly new, but should be available in most browsers.
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?
Basically I have this Angular material side nav with expandable navigation items
I want to make the second div scroll able when the items expand beyond the third div and also resizable so when I decrease the window size, it should always resize to fit between div 1 and and div 3.
I managed to implement the scrolling behavior with the following style applied:
title-div {
min-height: 10%;
}
items-div {
height: 80% //To force the info-div to be positioned at the bottom
max-height: 80%
overflow: auto;
}
info-div {
min-height: 10%;
}
However the resizing is not working properly. At a certain height the info-div(3) starts to get cut off instead of the item-div(2) resizing smaller for the info-div to fit in. How can I make this work?
You could easily achieve something like this using flexbox:
<div id="sidenav">
<div>Title</div>
<div class="items">
<div>item</div>
<div>item</div>
<div>item</div>
</div>
<div>Information</div>
</div>
#sidenav{
display: flex;
flex-direction: column;
height: 100%;
}
#sidenav .items{
flex-grow: 1;
overflow-y: auto;
}
https://codepen.io/Ploddy/pen/yLNaLyQ?editors=1100
when you set your second dives height to the relative space it should take and use overflow: auto it should work.
a POC:
* {
box-sizing: border-box;
margin: 0;
}
.container {
width: 100px;
border: solid 2px;
}
.one,
.three {
background: blue;
border: solid 1px;
height: 50px;
padding: 10px;
}
.two {
padding: 10px;
overflow: auto;
height: calc(100vh - 100px);
}
<div class="container">
<div class="one">title</div>
<div class="two">
body<br> body
<br> body
<br> body
<br> body
<br> body
<br> body
<br> body
<br> body
<br> body
<br> body
<br> body
</div>
<div class="three">title</div>
</div>
I have an React application and having a slightly bigger problem with some CSS stuff.
I have an view which is divided in 2 parts. But those two parts are lying in one bigger component. The left part is displaying some contacts and on the right I want to display details of those contacts. Now I want to make the left part scrollable like a list, but the right part just stay fixed on its position. Also the height of the left part should always stay as high as the current screen size. I am using Bulma CSS as my base CSS framework.
This is my HTML:
<div class="pane main-content" id="mainPane">
<div class="contacts-view">
<h1 class="title">My Title</h1>
<div class="">Other Stuff</div>
<div class="columns">
<div class="column is-3">
<div class="columns is-multiline">
<div class="column"></div>
<div class="column"></div>
<div class="column"></div>
</div>
</div>
<div class="column is-9"></div>
</div>
</div>
</div>
This is a quick sketch of how it looks:
Current relevant CSS:
.main-content {
background-color: #fff;
padding: 20px;
}
.pane {
position: relative;
overflow-y: auto;
flex: 1;
}
.columns {
margin-left: -0.75rem;
margin-right: -0.75rem;
margin-top: -0.75rem;
}
.column {
display: block;
-ms-flex-preferred-size: 0;
flex-basis: 0;
-webkit-box-flex: 1;
-ms-flex-positive: 1;
flex-grow: 1;
-ms-flex-negative: 1;
flex-shrink: 1;
padding: 0.75rem;
}
For better explanation. The component with class column is-3 should be scrollable but all other parts should stay fixed with no scroll.
I tried:
.is-3
overflow:hidden;
overflow-y:scroll;
But I found out that I have to set the height of is-3 because otherwise my screen is just expanded to the bottom. But I can not set a fixed height to it, because my screen size is dynamic and depended on the size of #mainPane. But I can also not set it to 100% because then the screen is also expanded at the bottom. Do you have any suggestions how I can solve this with CSS ?
Thanks in advance :)
You can use flexbox layout.
jsFiddle
body {
margin: 0;
}
.container {
height: 100vh;
display: flex;
flex-direction: column;
}
.header {
background: lightblue;
}
.content {
flex: 1;
display: flex;
min-height: 0; /*ADDED 2021*/
}
.sidebar {
background: lightgreen;
overflow: auto;
}
.main {
flex: 1;
background: pink;
overflow: auto;
}
<div class="container">
<div class="header">header</div>
<div class="content">
<div class="sidebar">
<div style="height:200vh;">sidebar</div>
</div>
<div class="main">
<div style="height:200vh;">main</div>
</div>
</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>