I have the following layout.
<div class="container">
<div class="content">
<div class="post">post</div>
<div class="image">image</div>
</div>
<div class="footer">footer</div>
</div>
http://jsbin.com/xicatoq/4/edit?html,css,output
The thing I want to achieve is to make the footer stick to the bottom (I don't want to use absolute positioning) and make the .content stretch from the top to the footer, like in the image below.
Can someone explain how I can achieve this?
In your code, the div with class content is a flex container. That makes the child elements (.post and .image) flex items.
However, your div with class container is not a flex container. So .content and .footer are not flex items, and cannot accept flex properties.
So, first step, add this:
.container {
display: flex;
flex-direction: column;
}
Then use flex auto margins to stick the footer to the bottom of the container:
.footer {
margin-top: auto;
}
Here's the full code:
body {
font-family: monospace;
color: #fff;
text-align:center;
}
.container {
width: 100%;
height: 800px;
background: red;
display: flex; /* NEW */
flex-direction: column; /* NEW */
}
.content {
/* float: left; */
width: 100%;
display: flex;
align-items: center;
}
.post {
width: 70%;
background: pink;
line-height: 300px;
}
.image {
width: 30%;
height: 500px;
background: green;
}
.footer {
background: blue;
line-height: 70px;
text-align: center;
/* float: left; */
width: 100%;
margin-top: auto; /* NEW */
}
<div class="container">
<div class="content">
<div class="post">post</div>
<div class="image">image</div>
</div>
<div class="footer">footer</div>
</div>
Revised Demo
Note that I commented out the floats. They aren't working. In a flex container floats are ignored.
Learn more about auto margins here: https://stackoverflow.com/a/33856609/3597276
Check this : http://jsbin.com/dojitevoye/edit?html,css,output
body {
font-family: monospace;
color: #fff;
text-align:center;
}
.container {
width: 100%;
height: 800px;
background: red;
}
.content {
float: left;
width: 100%;
height: 100%;
display: flex;
align-items: center;
}
.post {
width: 70%;
background: pink;
line-height: 300px;
align-self: flex-start;
}
.image {
width: 30%;
height: 500px;
background: green;
align-self: flex-start;
}
.footer {
background: blue;
line-height: 70px;
text-align: center;
float: left;
width: 100%;
align-self:flex-end;
}
Set the height for the .content class to 100%, which will take the height of it's parent ( which is .container ), which will be 800px in this case.
Now align both .post and .image to the top of the parent flexbox with align-self: flex-start;
Now, similarly set the .footer to the bottom of flexbox using align-self:flex-end;
Just use height: 100%; to .content will make footer stick to bottom.
Working JSBin
Related
This question already has answers here:
Flexbox: center horizontally and vertically
(14 answers)
How can I vertically center a div element for all browsers using CSS?
(48 answers)
How can I vertically align elements in a div?
(28 answers)
Closed 2 years ago.
Lets say I have this simple html page:
<div class="main">
<div class="header">
<h1>HEADER</h1>
</div>
<div class="content">
<div class="box">
</div>
</div>
</div>
My header is fixed and the content should be beneath it and with height 100% of what ever left of the body.
I've already done that with this style:
*{
margin-left: 0;
margin-top: 0;
}
body,
html {
height: 100%;
width: 100%;
margin: 0;
}
.header {
background-color: red;
text-align: center;
position: fixed;
width: 100%;
}
.content {
background-color: antiquewhite;
padding-top: 38px;
}
h1 {
margin-bottom: 0;
}
.main {
display: flex;
flex-direction: column;
height: 100vh;
}
.content {
flex: 1;
}
.box {
width: 150px;
height: 150px;
background-color: yellow;
}
Here's how the page looks for now: https://elbargho.github.io/sudoku/centerdiv.html
now I'm trying to center the box div horizontally and vertically in relative to the full body - the header size
what I've tried to do:
margin-top: 50% - for some reason the box went all the way down to the bottom
setting the position of content div to relative, and of box div to absolute - the content div overlapped the fixed header
You can set content class as
.content {
/* flex: 1; */
display: flex;
justify-content: center;
align-items: center;
width: 100%;
height: 100%;
}
*{
margin-left: 0;
margin-top: 0;
}
body,
html {
height: 100%;
width: 100%;
margin: 0;
}
.header {
background-color: red;
text-align: center;
position: fixed;
width: 100%;
}
.content {
background-color: antiquewhite;
padding-top: 38px;
}
h1 {
margin-bottom: 0;
}
.main {
display: flex;
flex-direction: column;
height: 100vh;
}
.content {
/*flex: 1; */
display: flex;
justify-content: center;
align-items: center;
width: 100%;
height: 100%;
}
.box {
width: 150px;
height: 150px;
background-color: yellow;
}
<div class="main">
<div class="header">
<h1>HEADER</h1>
</div>
<div class="content">
<div class="box">
</div>
</div>
</div>
This is probably what you need. Documented in the code.
* {
margin-left: 0;
margin-top: 0;
}
body,
html {
height: 100%;
width: 100%;
margin: 0;
}
/* Modified */
.header {
background-color: red;
text-align: center;
/* position: fixed; */
position: sticky;
width: 100%;
}
.content {
background-color: antiquewhite;
padding-top: 38px;
}
h1 {
margin-bottom: 0;
}
/* Modified */
.main {
display: flex;
flex-direction: column;
height: 100vh;
align-items: center;
}
/* Modified */
.content {
/*flex: 1;*/
display: flex;
align-items: center;
height: inherit;
}
.box {
width: 150px;
height: 150px;
background-color: yellow;
}
<div class="main">
<div class="header">
<h1>HEADER</h1>
</div>
<div class="content">
<div class="box">
</div>
</div>
</div>
Here solution:
.content {
display: flex;
flex: 1;
justify-content: center;
align-items: center;
}
One way is to use CSS Transform.
.box {
position: relative;
top: 50%;
transform: translateY(-50%);
/* horizontal center */
margin: 0 auto;
}
Check out this website for all CSS centering help:
http://howtocenterincss.com/
This question already has answers here:
Why don't flex items shrink past content size?
(5 answers)
Closed 2 years ago.
I have a simple layout: header + sidebar + content + footer.
The root element has a flex display with row direction; root = sidebar + wrapper. The wrapper = header + content + footer. The wrapper is displayed as flex and has flex direction of column.
When the content is a single word, the footer is visible just fine, however once I replace the content with a lot of text, the footer disappears (pics below).
JsFiddle with little content: https://jsfiddle.net/3mfdu8ey/1/
JsFiddle with a lot of content: https://jsfiddle.net/3mfdu8ey/2/
And once I scroll the second fiddle to the end:
The footer is gone. I tried fixing it with
height: calc(100vh - 200);
on #content-wrapper, but it didn't work.
My code:
html:
<div id = "app">
<div id = "custom-sidebar">
Sidebar
</div>
<div id = "content-wrapper">
<div id = "header">
Header
</div>
<div id = "content">
Content
</div>
<div id = "footer">
Footer
</div>
</div>
</div>
css:
#content-wrapper {
display: flex;
flex-direction: column;
justify-content: space-between;
width: 100%;
height: calc(100vh - 200);
}
#content {
padding: 30px;
}
#app {
background-color: gray;
display: flex;
height: 100vh;
font-family: 'Source Sans Pro', sans-serif;
padding: 0;
}
#header {
width: 100%;
display: flex;
flex-direction: column;
justify-content: center;
align-items: flex-end;
padding-bottom: 20px;
}
#sidebar {
width: 12%;
float: left;
display: flex;
flex-direction: column;
justify-content: center;
}
#footer {
height: 200px;
width: 100%;
}
/*
Colors
*/
#custom-sidebar {
background-color: orange;
}
#footer {
background-color: green;
}
#header {
background-color: red;
}
#content {
background-color: silver;
}
You need to set overflow on your content to prevent it from pushing footer down. See my example.
Edit: You need to set min-height instead of height. See this fiddle: https://jsfiddle.net/z9qt1cwr/
I include the minimal amount of styles you'll need to achieve this.
body,
html {
margin: 0;
box-sizing: border-box;
}
#app {
display: flex;
min-height: 100vh;
}
#content-wrapper {
display: flex;
flex-direction: column;
justify-content: space-between;
width: 100%;
}
#custom-sidebar {
width: 12%;
}
#content {}
#header {}
#footer {
height: 200px;
}
#custom-sidebar, #header, #content, #footer {
padding: 1rem 2rem;
}
/*
Colors
*/
#app {
background-color: gray;
}
#custom-sidebar {
background-color: orange;
}
#footer {
background-color: green;
}
#header {
background-color: red;
}
#content {
background-color: silver;
}
I'm working on project which includes a login/register page. It's basically a white div in body which should be centered verticaly and horizontally, but sometimes can be bigger than body.
When div is small everything is okay, but when its bigger than body then I just want it to have small padding on top and bottom.
How can I achieve that ? I have been searching for answer whole day and finally I'm here. Help me people :C
#wrap {
height: 300px;
width: 150px;
display: flex;
justify-content: center;
align-items: center;
background: #DDD;
}
#content {
background: #000;
width: 100px;
height: 400px;
}
<div id="wrap">
<div id="content">
</div>
</div>
You can use min-height instead of height and a small top and bottom padding on the wrapper as shown below. When the inner element is higher than the wrapper, it will extend the wrapper and additionally keep the padding .
#wrap {
min-height: 300px;
padding: 10px 0;
width: 150px;
display: flex;
justify-content: center;
align-items: center;
background: #DDD;
}
#content {
background: #000;
width: 100px;
height: 400px;
}
<div id="wrap">
<div id="content">
</div>
</div>
Use min-height instead of height, and add padding to top and bottom. Use box-sizing: border-box to prevent the padding from changing the height:
.wrap {
box-sizing: border-box;
min-height: 300px;
width: 150px;
padding: 20px;
display: flex;
justify-content: center;
align-items: center;
background: #DDD;
}
.content {
background: #000;
width: 100px;
height: 400px;
}
/** for the demo **/
.content--small {
height: 100px;
}
body {
display: flex;
justify-content: space-around;
align-items: flex-start;
}
<div class="wrap">
<div class="content">
</div>
</div>
<!-- for the demo -->
<div class="wrap">
<div class="content content--small">
</div>
</div>
This question already has answers here:
Center and bottom-align flex items
(3 answers)
Closed 5 years ago.
I'm trying to get one flex item to be centered vertically and horizontally.
I'd like for some text to be fixed to the bottom of the flex container.
margin-top:auto on the text just shoves the inner box to the top. Ideas?
.container {
background: lightblue;
width: 300px;
height: 300px;
display: flex;
justify-content: center;
flex-direction: column;
align-items: center;
padding: 10px;
}
.container .box {
background: goldenrod;
height: 30px;
width: 30px;
}
<div class="container">
<div class="box"></div>
<span>Text</span>
</div>
Here's the codepen.
Try the below instead:
.box {
background:goldenrod;
height: 30px;
width: 30px;
margin: auto;
}
Here is one way of doing it.
Add position: relative to your .container CSS rule, and then use absolute positioning on .box to position the span to the bottom of the parent container.
You can center the text by allowing .box to have 100% width and then using text-align: center.
.container {
background: lightblue;
width: 300px;
height: 300px;
display: flex;
justify-content: center;
flex-direction: column;
align-items: center;
padding: 10px;
position: relative;
}
.box {
background: goldenrod;
height: 30px;
width: 30px;
}
span {
position: absolute;
left: 0;
bottom: 0;
width: 100%;
text-align: center;
}
<div class="container">
<div class="box"></div>
<span>Text</span>
</div>
Since flexbox alignment involves the distribution of free space in the container, margin-top: auto won't work in this case because there's no counterweight on the other side.
Therefore, one method for centering the box and bottom-aligning the text involves creating a duplicate of the text element and placing it on the opposite side of the box. This will create a counterweight.
With equal balance on both ends, flex alignment properties (including auto margins) can work.
In this case, even justify-content: space-between would work.
Of course, you'll need to apply visibility: hidden to the duplicate element.
.container {
background: lightblue;
width: 300px;
height: 300px;
display: flex;
justify-content: center;
flex-direction: column;
align-items: center;
padding: 10px;
}
.box {
background: goldenrod;
height: 30px;
width: 30px;
margin: auto 0; /* or instead use justify-content: space-between on .container */
}
span:first-child {
visibility: hidden;
}
<div class="container">
<span>Text</span>
<div class="box"></div>
<span>Text</span>
</div>
OR, instead of a duplicate element, use a pseudo-element.
A less intrusive and more semantically proper method would use a pseudo-element as the duplicate. However, for this method to work, you would need to know the height of the actual element, because you would need to match it precisely.
Something like this will work to create equal balance:
.container::before {
content: "";
height: 15px; /* must match actual element's height */
}
.container {
background: lightblue;
width: 300px;
height: 300px;
display: flex;
justify-content: space-between;
flex-direction: column;
align-items: center;
padding: 10px;
}
.box {
background: goldenrod;
height: 30px;
width: 30px;
}
span {
height: 15px;
}
.container::before {
content: "";
height: 15px;
}
<div class="container">
<div class="box"></div>
<span>Text</span>
</div>
I am struggling to vertically align text iside a display: inline-block span.
This span is inside a container which has a height set as percentage of its wrapping container:
<div class="wrap">
<div class ="header">
<span>test</span>
</div>
</div>
and css:
html, body {
height:100%;
max-height: 1440px;
max-width: 1920px;
}
.wrap {
width: 100%;
height: 100%;
max-width: 1920px;
min-width: 1024px;
max-height: 1440px;
min-height: 768px;
background: green;
}
.header {
background: yellow;
height: 4.44%;
}
.header span {
display: inline-block;
line-height:100%;
height: 100%;
vertical-align: middle;
background: orange;
}
and here is the Fiddle
I also tried display:table; and display:table-cell; combo but that didn't work.
Edited:
I also got a question: why line-height:100% doesn't work?
Please help!
Flexbox can do that.
.header span {
display: -webkit-inline-box;
display: -webkit-inline-flex;
display: -ms-inline-flexbox;
display: inline-flex;
height: 100%;
-webkit-box-align: center;
-webkit-align-items: center;
-ms-flex-align: center;
align-items: center;
background: orange;
}
html, body {
height:100%;
max-height: 1440px;
max-width: 1920px;
}
.wrap {
width: 100%;
height: 100%;
max-width: 1920px;
min-width: 1024px;
max-height: 1440px;
min-height: 768px;
background: green;
}
.header {
background: yellow;
height: 4.44%;
}
.header span {
display: inline-flex;
height: 100%;
align-items: center;
background: orange;
}
.mainbody {
background: red;
height: 80%;
}
.footer {
background: blue;
height:10%;
}
<div class="wrap">
<div class ="header">
<span>test</span>
</div>
</div>
>> I also got a question: why line-height:100% doesn't work?
line-height in percentage is relative to the font-size of the element. Refer this.
So, if you want the height and line-height of '.header span' to be the same, you can get the computed height in javascript and then set it for line-height:
let divElement = document.getElementById('divId');
let height = document.defaultView.getComputedStyle(divElement).height;
divElement.style.lineHeight = height;
Just use line-height
CSS
.header span {
display: inline-block;
line-height:2.2em;
}
DEMO HERE