This question already has answers here:
How can I vertically align elements in a div?
(28 answers)
How can I vertically center a div element for all browsers using CSS?
(48 answers)
Flexbox: center horizontally and vertically
(14 answers)
Closed 3 years ago.
The Height of parent and child will be given at run time, I have tried vertical-align but it didn't work, margin/top property won't be correct because height is dynamic. Please provide proper way to fix this.
Expected: Child should be center of parent. Width should remain same
Update: Solution of #xmastertje is working, but if i change my child height it breaks. This question is part of big problem so I can't use calc here. In real time I have nested elements each should center of its parent.
:root {
--parent-height: 500px;
--child-height: 200px;
}
html,
body {
width: 100%;
height: 100%;
}
.parent {
height: var(--parent-height);
background-color: #bada55;
position: relative;
}
.child {
height: var(--child-height);
background-color: goldenrod;
}
<div class="parent">
Parent Has 500px Height
<div class="child">
child has 200px height
</div>
</div>
You can use flexbox for it like this:
.parent {
height: var(--parent-height);
background-color: #bada55;
position: relative;
display: flex;
justify-content: center;
flex-direction: column;
}
If you just want the child to be centered and the width will be the same, you could use the margin-top with calc() to calculate the top margin of the child with the parent
Something like this
margin-top: calc((var(--parent-height) - var(--child-height)) * 0.5);
Hope this help....
Use margin-top and position:absolute. With this you can fix it easy.
:root{
--parent-height: 500px;
--child-height: 200px;
}
html, body{
width: 100%;
height: 100%;
}
.parent{
height: var(--parent-height);
background-color: #bada55;
position: relative;
}
.child{
height: var(--child-height);
background-color: goldenrod;
position: absolute;
top: 50%;
width: 100%;
margin-top: -6em;
}
<div class="parent">
Parent Has 500px Height
<div class="child">
child has 200px height
</div>
</div>
EDIT
You have to use transform. This solution keeps working even if you change child or parent height.
:root{
--parent-height: 500px;
--child-height: 200px;
}
html, body{
width: 100%;
height: 100%;
}
.parent{
height: var(--parent-height);
background-color: #bada55;
position: relative;
}
.child{
height: var(--child-height);
background-color: goldenrod;
position: absolute;
top: 50%; left: 50%;
transform: translate(-50%,-50%);
width:100%;
}
<div class="parent">
Parent Has 500px Height
<div class="child">
child has 200px height
</div>
</div>
Hi i think the best way to do that is using table cell property.No matter what is the height of parent the child will be always align center.
But if you want the parent to be full width you can use flex properties.I Hope that will work fine.
:root {
--parent-height: 500px;
--child-height: 200px;
}
html,
body {
width: 100%;
height: 100%;
}
.parent {
height: var(--parent-height);
background-color: #bada55;
position: relative;
display: flex;
justify-content: center;
align-items:center;
width:100%;
}
.child {
height: var(--child-height);
background-color: goldenrod;
}
<div class="parent">
Parent Has 500px Height
<div class="child">
child has 200px height
</div>
</div>
I have used the flexbox to make the child become center. Try the below code.
:root {
--parent-height: 500px;
--child-height: 200px;
}
html,
body {
width: 100%;
height: 100%;
}
.parent {
height: var(--parent-height);
background-color: #bada55;
position: relative;
display:flex;
display: -ms-flexbox!important;
flex-wrap:wrap;
-webkit-flex-wrap: wrap;
}
.child {
height: var(--child-height);
background-color: goldenrod;
-ms-flex-align: center!important;
align-items: center!important;
width:100%;
}
<div class="parent">
Parent Has 500px Height
<div class="child">
child has 200px height
</div>
</div>
You can do it easily with flex box
:root {
--parent-height: 500px;
--child-height: 200px;
}
html,
body {
width: 100%;
height: 100%;
}
.parent {
height: var(--parent-height);
background-color: #bada55;
position: relative;
display: flex;
justify-content:center;
flex-direction: column;
align-items: center;
}
.child {
height: var(--child-height);
background-color: goldenrod;
width:100%;
}
<div class="parent">
<p>Parent Has 500px Height</p>
<br>
<div class="child">
<p>child has 200px height</p>
</div>
</div>
Related
I'm trying to add a vertical rule in a flex row whose height is not fixed (it is sized to fit its other contents).
I would like for the vertical rule to stretch the full height of the container (excluding the padding). I have tried align-items: stretch on the flex row, align-self: stretch on the vertical rule div, and height: 100% on the vertical rule div, but no matter what I do, the vertical rule only ever seems to have a height of 0px:
.row {
display: flex;
flex-direction: row;
background-color: orange;
width: max-content;
align-items: stretch;
margin-bottom: 12px;
padding: 12px;
height: max-content;
}
.vr {
height: 100%;
width: 1px;
background-color: black;
align-self: stretch;
}
.purple {
background-color: purple;
height: 80px;
width: 50px;
}
.lightblue {
background-color: lightblue;
height: 80px;
width: 50px;
}
.red {
background-color: red;
height: 120px;
width: 50px;
}
.blue {
background-color: blue;
height: 120px;
width: 50px;
}
<div class="row">
<div class="red"></div>
<div class="vr"></div>
<div class="blue"></div>
</div>
<div class="row">
<div class="purple"></div>
<div class="vr"></div>
<div class="lightblue"></div>
</div>
Is there any way that I can have my .vr div stretch to the full height of the container without giving the container a fixed height?
Removing the height: 100% from the .vr rules did the trick for me.
I need to avoid the overlapping of the div's when the browser window is shrinked vertically in the following piece of code:
`
<html>
<body>
<style>
#box {
display: flex;
flex-direction: column;
align-items: center;
}
#top {
background-color: red;
height: 560px;
width: 400px;
}
#bottom {
background-color: green;
height: 100px;
width: 400px;
position: absolute;
bottom: 0
}
</style>
<div id="box">
<div id="top">
</div>
<div id="bottom">
</div>
</div>
<body>
</html>
`
Why are the div's getting overlapped. is there a way that this overlapping can be avoided and having the same initial structure? The bottom div acts as a footer in the real scenario. Thanks in advance!
Use min-height on the box, remove absolute positioning from the bottom and both div's heights will be kept.
When the margin-top: auto is set on a flex column item, it will push it to the bottom of is parent, which you can see on bigger screens.
body {
margin: 0;
display: flex; /* IE bug fix */
}
#box {
flex-grow: 1; /* fill body's width */
display: flex;
flex-direction: column;
align-items: center;
min-height: 100vh;
}
#top {
background-color: red;
height: 560px;
width: 400px;
border: 1px solid black;
}
#bottom {
margin-top: auto; /* push it to the bottom on big screen */
background-color: green;
height: 100px;
width: 400px;
border: 1px solid black;
}
<div id="box">
<div id="top">
</div>
<div id="bottom">
</div>
</div>
If they at some point they need to shrink, with this sample the red div does, where the height is fixed to full viewport.
It works like that, that the green is given flex-shrink: 0, which prevent it from shrink and keep its set height.
html, body {
margin: 0;
}
#box {
display: flex;
flex-direction: column;
align-items: center;
height: 100vh;
}
#top {
background-color: red;
height: 560px;
width: 400px;
border: 1px solid black;
}
#bottom {
margin-top: auto;
flex-shrink: 0;
background-color: green;
height: 100px;
width: 400px;
border: 1px solid black;
}
<div id="box">
<div id="top">
</div>
<div id="bottom">
</div>
</div>
You need to set position: relative; to parent, in this case to body element, it will solve the issue. When the parent's position is relative, and the child's position is absolute, the child will respect parent and will be positioned relatively to the parent:
body {
position: relative;
}
#box {
display: flex;
flex-direction: column;
align-items: center;
}
#top {
background-color: red;
height: 560px;
width: 400px;
}
#bottom {
background-color: green;
height: 100px;
width: 400px;
position: absolute;
bottom: 0
}
<div id="box">
<div id="top">
</div>
<div id="bottom">
</div>
</div>
I have a parent div with display: flex. I would like for one of the child div to ignore that.
For example I want something like this:
Child div1
Child div2, Child div3, Child div4
I want the first Child div1 to be on top without having any other elements in it's line. I know I can make this happen if I just take the child div1 outside of it's parent, but it would be nice to know another way.
/* Parent div */
.boxContainer {
display: flex;
height: 500px;
width: 100%;
}
/* Child div1 */
.headerBox {
height: 100px;
}
/* more child div */
.imgBox {
margin-top: 100px;
height: 375px;
width: 375px;
}
I want the first Child div1 to be on top without having any other
elements in it's line.
The simplest way would be to set flex-basis: 100% on the 1st child.
With that it will take full width and push the rest items down, and it is fully responsive.
Also, you need to add flex-wrap: wrap;
/* Parent div */
.boxContainer {
display: flex;
flex-wrap: wrap; /* added */
align-content: flex-start; /* added, so they align at the top */
height: 500px;
width: 100%;
}
/* Child div1 */
.headerBox {
flex-basis: 100%; /* added */
height: 100px;
background: lightblue;
margin: 2px;
}
/* more child div */
.imgBox {
height: 175px;
width: 175px;
background: lightgray;
margin: 2px;
}
<div class="boxContainer">
<div class="headerBox">Header box</div>
<div class="imgBox">Image box</div>
<div class="imgBox">Image box</div>
<div class="imgBox">Image box</div>
</div>
To take the item completely outside the flexbox flow, you can set it's position
to absolute, and then move it where you want with top, left, etc...
Set position: absolute on the child, and position: relative on the parent:
.boxContainer {
/** Parent div **/
position: relative;
display: flex;
height: 500px;
width: 100%;
}
.headerBox {
/** Child div1 **/
position: absolute;
top: -50px;
/** move it up **/
height: 100px;
}
.imgBox {
/** more child div **/
margin-top: 100px;
height: 375px;
width: 375px;
}
If you just need the 1st item apart you can use flex wrap, and set margin-right: 100% on the 1st element:
/* Parent div */
.boxContainer {
display: flex;
height: 200px; /** I've changed the dimensions to fit the demo windows **/
width: 100%;
flex-wrap: wrap;
}
/* Child div1 */
.headerBox {
margin-right: 100%;
height: 100px;
}
/* more child div */
.imgBox {
height: 75px;
/** I've changed the dimensions to fit the demo windows **/
width: 75px;
/** I've changed the dimensions to fit the demo windows **/
}
<div class="boxContainer">
<div class="headerBox">headerBox</div>
<div class="imgBox">imgBox</div>
<div class="imgBox">imgBox</div>
<div class="imgBox">imgBox</div>
<div class="imgBox">imgBox</div>
<div class="imgBox">imgBox</div>
<div class="imgBox">imgBox</div>
<div class="imgBox">imgBox</div>
<div class="imgBox">imgBox</div>
</div>
The first child element doesn't need to ignore flex. If flex-basis is set to 100% it will take up the full width. And then using flex-wrap: wrap; for the rest of the child elements to follow on a new line.
.parent {
display: flex;
flex-wrap: wrap;
}
.parent > div:first-child {
flex: 1 0 100%;
}
/* flex is shorthand for flex-grow + flex-shrink + flex-basis */
See demo here: https://codepen.io/eystein/pen/qXmVPo
You can use absolute positioning
.boxContainer {
display: flex;
height: 500px;
width: 100%;
background: blue;
margin-top: 120px;
position: relative;
}
.headerBox {
height: 100px;
width: 100%;
background: red;
position: absolute;
top: -110px;
left: 0;
}
.imgBox {
margin-top: 100px;
height: 375px;
width: 375px;
background: green;
}
<div class="boxContainer">
<div class="headerBox"></div>
<div class="imgBox"></div>
</div>
To me it seems like you don't really want a flexbox. I'd use float: left for this. Use clear: left on a div that is width: 0 to get the next ones to wrap to the next line. Flexbox is nice, but if the older tech works better for you then use it.
Edit: After looking at the post again I didn't realize you wanted the first div to also take up 100% of the width. This is better done with a flexbox, setting the flex-basis as other answers have stated. Going to leave this answer for others to find though.
Example:
.container{
width: 100%;
}
.container .img{
width: calc(25% - 20px);
height: 100px;
background-color: lightblue;
margin: 10px;
float: left;
}
.clear-left{
clear: left;
width: 0;
}
<div class="container">
<div class="img"></div>
<div class="clear-left"></div>
<div class="img"></div>
<div class="img"></div>
<div class="img"></div>
Looking for a specific stacking order inside a flex container. Pretty basic footer split into 3 sections, so you have left and right Divs 100% height and 20% width. The middle would flex to fill the difference BUT middle needs to be split in half. So top and bottom Divs inside at 50% height each. I can’t seem to figure out the positions with absolute, fixed, ect. Or floating whatever works best.
Thanks
Ok sorry, here is the CSS inside flex container
.footer_left_box {
position: absolute;
display: inline-block;
float:left;
left:0;
width: 10%;
height: 100%;
background-color:#C9D329;
}
.footer_middle_top_box {
position: relative;
display: inline-block;
width: 80%;
height: 50%;
background-color:#2BB851;
}
.footer_middle_bottom_box {
position: relative;
display: inline-block;
width: 80%;
height: 50%;
background-color:#3954D4;
}
.footer_right_box {
position: absolute;
right:0;
width: 10%;
height: 100%;
background-color:#E33538;
}
This is an example of what I need
Flexbox can do that but you may need to adapt the structure.
footer {
height: 150px;
display: flex;
}
.left,
.right {
flex: 0 0 20%;
}
.left {
background: rebeccapurple;
}
.right {
background: #bada55;
}
.middle {
flex: 1;
border: 2px solid red;
display: flex;
flex-direction: column;
}
.top {
flex: 0 0 50%;
background: #c0c0ae;
}
.bottom {
flex: 0 0 50%;
background: #c0ffee;
}
<footer>
<div class="left"></div>
<div class="middle">
<div class="top"></div>
<div class="bottom"></div>
</div>
<div class="right"></div>
</footer>
If I make a flexbox with 2 children and column flow and set the second child to flex-grow 1 the second child expands to fill the flexbox. This works
(ps: Didn't want to clutter the example with safari support so use Chrome or Firefox)
* {
box-sizing: border-box;
}
html, body {
margin: 0;
width: 100%;
height: 100%;
color: white;
}
#outer {
display: flex;
flex-flow: column;
height: 100%;
}
#top {
background-color: red;
}
#bottom {
background-color: blue;
flex: 1 0 auto;
}
<div id="outer">
<div id="top">top</div>
<div id="bottom">bottom (blue)</div>
</div>
But, if I then put a child #inside inside #bottom and set its height to 100% it doesn't increase its height to match even though the flexbox has stretched #bottom.
added css
#inside {
background-color: green;
height: 100%;
}
html
<div id="outer">
<div id="top">top</div>
<div id="bottom">
<div id="inside">inside</div> <!- added ->
</div>
</div>
* {
box-sizing: border-box;
}
html, body {
margin: 0;
width: 100%;
height: 100%;
color: white;
}
#outer {
display: flex;
flex-flow: column;
height: 100%;
}
#top {
background-color: red;
}
#bottom {
background-color: blue;
flex: 1 0 auto;
}
#inside {
background-color: green;
height: 100%;
}
<div id="outer">
<div id="top">top</div>
<div id="bottom">
<div id="inside">inside (green)</div>
</div>
</div>
So I add a height: 100% to #bottom but now bottom is as big as #outer instead of the flex stretched size.
#bottom {
background-color: blue;
flex: 1 0 auto;
height: 100%; /* added */
}
* {
box-sizing: border-box;
}
html, body {
margin: 0;
width: 100%;
height: 100%;
color: white;
}
#outer {
display: flex;
flex-flow: column;
height: 100%;
}
#top {
background-color: red;
}
#bottom {
background-color: blue;
flex: 1 0 auto;
height: 100%;
}
#inside {
background-color: green;
height: 100%;
}
<div id="outer">
<div id="top">top</div>
<div id="bottom">
<div id="inside">inside (green) (would not scroll if working)</div>
</div>
</div>
How do I get #bottom to stretch to fit the flexbox and also get a the child #inside to be 100% height of its container #bottom?
Flex has a quirk where you need to set the height to 0.
Change the #bottom rule's height property to this height: 0;
For the inside to work I changed it to "position: absolute" and as well added a position:relative to the bottom
Update
If you don't want to use absolute position, you can set these 2 css rules like this:
(Note though, that this propagates the original issue if a new inner div is used like the first one)
#bottom {
position: relative;
background-color: blue;
flex: 1 0 auto;
height: 0;
display: flex;
}
#inside {
background-color: green;
flex: 1 0 auto;
}
Sample using "position: absolute"
* {
box-sizing: border-box;
}
html, body {
margin: 0;
width: 100%;
height: 100%;
color: white;
}
#outer {
display: flex;
flex-flow: column;
height: 100%;
}
#top {
background-color: red;
}
#bottom {
position: relative;
background-color: blue;
flex: 1 0 auto;
height: 0;
}
#inside {
background-color: green;
position: absolute;
left: 0;
top: 0;
right: 0;
bottom: 0;
}
<div id="outer">
<div id="top">top</div>
<div id="bottom">
<div id="inside">inside (would not scroll if working)</div>
</div>
</div>
How do I get #bottom to stretch to fit the flexbox and also get a the child #inside to be 100% height of its container #bottom?
Just add two lines of code to the CSS.
CSS
#bottom {
background-color: blue;
flex: 1 0 auto;
display: flex; /* NEW */
}
#inside {
flex: 1; /* NEW */
background-color: green;
}
DEMO: http://jsfiddle.net/wf2L8dse/
Here's what's happening:
You have a flex container (#outer) with two flex items (#top and #bottom).
#outer is in column alignment.
#bottom has flex: 1 (i.e., flex-grow: 1), so it occupies all available height in the container.
A new element (#inside) is made a child of #bottom and must occupy the same height as parent.
Solution:
Make #bottom a (nested) flexbox. This activates default flex rules.
One such rule is align-items: stretch, which tells flex items (#inside) to stretch the full height of their container. (Height, in this case, because the flex-direction is row, by default.)
Then apply flex: 1 (or flex-grow: 1) to #inside, so it expands the full width of the container.
Addressing the height: 100% issue
I'm not sure there's anything wrong with your code. You have applied height: 100% to #inside and, as required by the spec when using percentage heights, specified a height for all parent elements including body and the root element (html).
The only thing you may want to consider (to remove the vertical scrollbar on the browser window), is applying overflow: hidden to body.
DEMO: http://jsfiddle.net/wf2L8dse/1/