Please consider this style:
.root {
display: flex;
flex-direction: column;
height: 100%;
}
.header {
width: 100%;
background-color: red;
display: flex;
height: 100px;
justify-content: space-between;
.logo-pane {
width: 100px;
height: 100px;
background-color: green;
}
.user-actions {
width: 100px;
height: 100px;
background-color: blue;
}
}
.content {
flex-grow: 1;
background-color: pink;
}
What I want to achieve is that the content element will take the remaining height of the viewport, but it takes only his content height.
HTML:
<div class="root">
<div class="header">
<div class="logo-pane">Logo</div>
<div class="user-actions">User Actions</div>
</div>
<div class="content">
content
</div>
</div>
Codepen
The problem is the surrounding .root. You have to increase the height of the .root to the remaining space. So you have to set the height:100vh; on .root. Try the following solution:
body, html {
margin:0;
padding:0;
}
.root {
display: flex;
flex-direction: column;
height: 100vh;
align-items:stretch;
align-content:stretch;
}
.header {
width: 100%;
background-color: red;
display: flex;
height: 100px;
justify-content: space-between;
}
.logo-pane {
width: 100px;
height: 100px;
background-color: green;
}
.user-actions {
width: 100px;
height: 100px;
background-color: blue;
}
.content {
flex-grow:1;
background-color: pink;
}
<div class="root">
<div class="header">
<div class="logo-pane">Logo</div>
<div class="user-actions">User Actions</div>
</div>
<div class="content">content</div>
</div>
.content {
flex-grow: 1;
background-color: pink;
height: 100vh;
}
Set the :root to 100vh (100% of the viewport height) instead 100%
You can simply add
height: 100% to html, body
add height to 20% for root div
add height to 80% for content div
will solve your problem
html,body {
height: 100%;
}
Here is the jsFiddle
Hope it helps :)
I think your misunderstanding what flex does. Flex is used to align its children, not to fill a viewport. Heres another solution.
https://jsfiddle.net/rob_primacy/1wnpr50s/
<div class="root">
<div class="header">
<div class="logo-pane">Logo</div>
<div class="user-actions">User Actions</div>
</div>
</div>
<div class="content">
content
</div>
and the css
.root {
display: flex;
flex-direction: column;
height: 100%;
position: relative;
}
.header {
width: 100%;
background-color: red;
display: flex;
height: 100px;
justify-content: space-between;
position: relative;
}
.user-actions {
width: 100px;
height: 100px;
background-color: blue;
}
.logo-pane {
width: 100px;
height: 100px;
background-color: green;
}
.content {
background-color: pink;
position: absolute;
height: 100%;
left: 8px;
right: 8px;
}
Use like this
<!DOCTYPE html>
<html>
<head>
<meta content="text/html; charset=utf-8" http-equiv="Content-Type">
<title>Untitled 1</title>
<style type="text/css">
body{
margin:0;
}
.root {
display: flex;
flex-direction: column;
height: 100%;
}
.header {
width: 100%;
background-color: red;
display: flex;
height: 100px;
justify-content: space-between;
.logo-pane {
width: 100px;
height: 100px;
background-color: green;
}
.user-actions {
width: 100px;
height: 100px;
background-color: blue;
}
}
.content {
flex-grow: 1;
background-color: pink;
height:100%;
width:100%;
position: fixed;
}
</style>
</head>
<body>
<div class="root">
<div class="header">
<div class="logo-pane">Logo</div>
<div class="user-actions">User Actions</div>
</div>
<div class="content">
content
</div>
</div>
</body>
</html>
Your codepen linked works fine. I do not understand where you get stuck.
You could basicly build your template from 2 containers :example with header and main
html,
body {
height: 100%;/* or just : 100vh; for body only */
margin: 0;
}
body {
display: flex;
flex-direction: column;
/* width and margin:auto is avalaible */
}
header {
/* height: 50px;or do not set any and let grow from its content */
background: gray;
}
main {
flex: 1;/* will fill up all space left */
background: lightblue;
/* overflow:auto; optionnal if you do not want html to scroll and keep header fixed */
}
<header>
whatever <br/> sizes me
</header>
<main>
content
</main>
Make it simple to start with :)
Related
How do I get the .top_box to be fixed in the head of the .content?
With the current code, the .top_box always scrolls along with the .content.
.wrapper {
height: 160px;
display: flex;
flex-direction: column;
}
.title_container {
background: pink;
}
.content {
height: 0;
flex: auto;
position: relative;
overflow-y: auto;
overflow-x: hidden;
background-color: bisque;
}
.top_box {
position: absolute;
top: 0;
left: 0;
width: 300px;
height: 16px;
background: royalblue;
}
.scroll_fill {
height: 500px;
}
<div class="wrapper">
<div class="title_container">anyString</div>
<div class="content">
<div class="top_box"></div>
<div class="scroll_fill"></div>
</div>
</div>
You can just change the order of the HTML-Elements in the code and write .top before .item. If you do that, you can also remove most of the CSS because it’s unnecessary.
Here‘s a full example:
.box1 {
height: 600px;
display: flex;
flex-direction: column;
}
.box2 {
background: pink;
}
.box3 {
background-color: red;
}
.top {
width: 300px;
height: 5px;
background: blue;
}
.item {
height: 1000px;
}
<div class="box1">
<div class="box2">anyString</div>
<div class="box3">
<div class="top"></div>
<div class="item"></div>
</div>
</div>
Also a few other things: I wouldnt recommend just using divs and naming them like box1, box2, box3, .... Instead, give them names wich describe their use and meaning like wrapper, top_container, bottom_container, top_item, content, ...:
CSS Naming Conventions.
You can also use specific tags with semantic meanings: Sematic HTML5 Elements
Hope that helps
.wrapper {
height: 160px;
display: flex;
flex-direction: column;
}
.title_container {
background: pink;
}
.content {
height: 0;
flex: auto;
position: relative;
overflow: hidden;
background-color: bisque;
}
.contentInner {
height: 100%;
width: 100%;
overflow-y: auto;
overflow-x: hidden;
}
.top_box {
position: absolute;
top: 0;
left: 0;
width: 300px;
height: 16px;
background: royalblue;
}
.scroll_fill {
height: 500px;
}
<div class="wrapper">
<div class="title_container">anyString</div>
<div class="content">
<div class="top_box"></div>
<div class="contentInner">
<div class="scroll_fill"></div>
</div>
</div>
</div>
https://i.stack.imgur.com/e2n5o.png
I want to achieve a layout like this by flexbox. body is flex container and there are only two flex items, one card and one footer. Here is a simplified codepen link. How can I make the footer at the bottom of the page while the card position center as it is now.
body {
display: flex;
flex-direction: column;
align-items: center;
justify-content: center;
height: 100vh;
}
.container {
width: 400px;
height: 300px;
background-color: green;
}
.footer {
margin-bottom: 20px;
background-color: yellow;
width: 200px;
height: 50px;
}
<div class="container"></div>
<div class="footer"></div>
if I add margin-top:auto, the footer's position will be right, but the container will go to the top.
if I add gap to body, the container will not be at the center
Use another element for the green card and make the .container fill all the available space using flex-grow: 1.
Use display: flex and align-items:center on the .container to center the card vertically.
body{
display:flex;
flex-direction:column;
align-items:center;
height:100vh;
}
.container{
flex-grow: 1;
display: flex;
align-items: center;
}
.card {
width:400px;
height:300px;
background-color:green;
}
.footer{
margin-bottom:20px;
background-color:yellow;
width: 200px;
height:50px;
}
<div class="container">
<div class="card"></div>
</div>
<div class="footer"></div>
The body does not need justify-content:center; so you should remove it too.
Another approach if you want that .container to have 100% width.
body {
display: flex;
flex-wrap: wrap;
height: 100vh;
}
.container {
width: 100%; /* NEW */
flex-grow: 1;
display: flex;
align-items: center;
justify-content: center; /* NEW */
}
.card {
width: 400px;
height: 300px;
background-color: green;
}
.footer {
margin-bottom: 20px;
background-color: yellow;
width: 200px;
height: 50px;
margin: auto; /* NEW */
}
<div class="container">
<div class="card"></div>
</div>
<div class="footer"></div>
You can use grid to center the container, and position to stick the footer.
body {
display: grid;
place-content: center; /* center the container */
height: 100vh;
margin: 0;
}
.container {
width: 400px;
height: 300px;
background-color: green;
}
.footer {
justify-self: center; /* center the footer */
margin-bottom: 20px;
background-color: yellow;
width: 200px;
height: 50px;
/* push the footer to the bottom */
position: sticky;
top: 100vh;
}
<div class="container"></div>
<div class="footer"></div>
In the snippet below you can see that the green .bottom stops at the width of the screen using a width of 100%. Can I force the width to match exactly the parent width? In this case 1000px.
The problem is that the red .top is a variable width so setting a fixed width for the green .bottom is not an option.
.parent {
width: 700px;
}
div.container {
overflow: auto;
background-color: yellow;
display: flex;
flex-direction: column;
height: 100px;
}
div.top {
background-color: red;
height: 40px;
width: 1000px;
}
div.bottom {
background-color: green;
height: 20px;
width: 100%;
}
<div class="parent">
<div class="container">
<div class="top"></div>
<div class="bottom"></div>
</div>
</div>
Use CSS grid instead of flexbox:
.parent {
width: 700px;
}
div.container {
overflow: auto;
background-color: yellow;
display: grid;
align-content: start; /* don't forget this */
height: 100px;
}
div.top {
background-color: red;
height: 40px;
width: 1000px;
}
div.bottom {
background-color: green;
height: 20px;
}
<div class="parent">
<div class="container">
<div class="top"></div>
<div class="bottom"></div>
</div>
</div>
I want to create a layout where we have a header (responsive, with any height), footer (responsive, with any height), and content that fills the rest of space. Content should have two columns - first(right) that fits the content and second(left) that is very long and should have overflow with y-axis scrolling.
Detailed snipped with HTML and CSS attached.
I have problem with making them work inside of flexible height. I know how to make it work when I have only two columns, but with a responsive footer and header, I have problems.
I also have a code snippet inside of codepen
Thanks in advance for any help :)
html,
body {
height: 100%;
width: 100%;
}
.container {
height: 100%;
display: flex;
flex-direction: column;
}
.column {
background-color: white;
display: flex;
flex-direction: column;
flex-basis: 100%;
flex: 1;
color: black;
border: 5px purple solid;
}
.column-with-overflow {
overflow: auto;
max-height: 100%;
flex-grow: 1;
}
.column-with-overflow-content {
height: 1000px;
background-color: blue;
display: flex;
}
.columns {
display: flex;
flex-direction: row;
background-color: yellow;
width: 100%;
max-height: 100%;
}
.content {
background-color: blue;
flex-grow: 1;
}
.box {
text-align: center;
color: white;
display: flex;
justify-content: center;
}
.header {
background-color: green;
height: 60px; // assume that It's not known - any height
}
.footer {
background-color: red;
height: 60px; // assume that It's not known - any height
}
<div class="container">
<div class="box header">Header</div>
<div class="box content">
<div class="columns">
<div class='column column-with-overflow'>
<div class='column-with-overflow-content'>
box 1
</div>
</div>
<div class='column'>box 2</div>
</div>
</div>
<div class="box footer">Footer</div>
</div>
Set a fixed height to your .box.content div element.
And use min-height in .column-with-overflow-content insted of height
html,
body {
height: 100%;
width: 100%;
}
.container {
height: 100%;
display: flex;
flex-direction: column;
}
.column {
background-color: white;
display: flex;
flex-direction: column;
flex-basis: 100%;
flex: 1;
color: black;
border: 5px purple solid;
}
.column-with-overflow {
overflow: auto;
max-height: 100%;
flex-grow: 1;
}
.column-with-overflow-content {
min-height: 1000px; /* use min-height */
background-color: blue;
display: flex;
}
.columns {
display: flex;
flex-direction: row;
background-color: yellow;
width: 100%;
max-height: 100%;
}
.content {
background-color: blue;
flex-grow: 1;
}
.box.content { height: 100px; } /* set height to columns container */
.box {
text-align: center;
color: white;
display: flex;
justify-content: center;
}
.header {
background-color: green;
height: 60px; // assume that It's not known - any height
}
.footer {
background-color: red;
height: 60px; // assume that It's not known - any height
}
<div class="container">
<div class="box header">Header</div>
<div class="box content">
<div class="columns">
<div class='column column-with-overflow'>
<div class='column-with-overflow-content'>
box 1
</div>
</div>
<div class='column'>box 2</div>
</div>
</div>
<div class="box footer">Footer</div>
</div>
I need to have a 100% height flexbox with just a children footer with 50px.
Is possible without have the calc(100% - 50px) ?
here my try:
body, html{
height:100%;
}
.container {
height: 100%;
display: flex;
flex-direction: column;
background-color:red;
}
.flex-1 {
background-color: yellow;
}
.flex-A {
background-color: blue;
display: flex;
flex-direction: column;
height: 100%;
}
.flex-1-child {
background-color: purple;
overflow-y: auto;
height: calc(100% - 50px);
}
.flex-2-child {
background-color: green;
height: 50px;
}
.text{
height: 500px;
}
<div class="container">
<div class="flex-1">test</div>
<div class="flex-A">
<div class="flex-1-child">
<div class="text">test2</div>
</div>
<div class="flex-2-child">
<div>test</div>
</div>
</div>
</div>
I don't have the 100% height.
Thank you for your help.
Change height: calc(100% - 50px); to flex: 1; and it will expand its height maximally.
I guess this is what you want?
https://jsfiddle.net/shuding/3ss44wuk/1
Simply use flex: 1 on the dynamic element.
body, html{
height:100%;
}
.container {
height: 100%;
display: flex;
flex-direction: column;
background-color:red;
}
.flex-1 {
background-color: yellow;
}
.flex-A {
background-color: blue;
display: flex;
flex-direction: column;
height: 100%;
}
.flex-1-child {
background-color: purple;
overflow-y: auto;
flex: 1;
}
.flex-2-child {
background-color: green;
height: 50px;
}
.text{
height: 500px;
}
<div class="container">
<div class="flex-1">test</div>
<div class="flex-A">
<div class="flex-1-child">
<div class="text">test2</div>
</div>
<div class="flex-2-child">
<div>test</div>
</div>
</div>
</div>