I am trying to align the footer at the bottom, leave the space at the top. but not works. any one help me to know the correct way?
.parent {
border: 1px solid red;
display: flex;
}
.child {
border: 1px solid green;
min-height: 100px;
flex: 1;
align-items:bottom;
}
.footer{
background:#808080;
}
<div class="parent">
<div class="child">
<div class="footer">Footer</div>
</div>
<div class="child">
<div class="footer">Footer</div>
</div>
<div class="child">
<div class="footer">Footer-will be in bottom!!</div>
</div>
</div>
First of all, to align items to the bottom the correct way is align-items: flex-end;
I also declared display:flex; on .child, and gave it a width.
.parent {
border: 1px solid red;
display: flex;
}
.child {
border: 1px solid green;
min-height: 100px;
display: flex;
width: 33.333%;
align-items: flex-end;
}
.footer{
background:#808080;
width: 100%;
}
<div class="parent">
<div class="child">
<div class="footer">Footer</div>
</div>
<div class="child">
<div class="footer">Footer</div>
</div>
<div class="child">
<div class="footer">Footer-will be in bottom!!</div>
</div>
</div>
In this example your .child also needs to have display: flex and .footer needs align-items: bottom.
Why? This is actually multiple nested flex layouts.
As per the code you have provided. This can be a possible solution.
.parent {
border: 1px solid red;
display: flex;
}
.child {
border: 1px solid green;
min-height: 100px;
flex: 1;
display: inline-flex;
align-items: flex-end;
flex-direction: row;
}
.footer {
display: inline-block;
width: 100%;
background:#808080;
}
<div class="parent">
<div class="child">
<div class="footer">Footer</div>
</div>
<div class="child">
<div class="footer">Footer</div>
</div>
<div class="child">
<div class="footer">Footer-will be in bottom!!</div>
</div>
</div>
But in a more optimized way. Let me show you another sample:
.parent {
border: 1px solid red;
display: flex;
}
.child {
flex: 1;
border: 1px solid green;
min-height: 100px;
display: flex;
flex-direction: column;
}
.content {
flex: 1;
}
.footer{
background:#808080;
}
<div class="parent">
<div class="child">
<div class="content">Content</div>
<div class="footer">Footer</div>
</div>
<div class="child">
<div class="content">Content</div>
<div class="footer">Footer</div>
</div>
<div class="child">
<div class="content">Content</div>
<div class="footer">Footer-will be in bottom!!</div>
</div>
</div>
If you don't want to change the HTML tags and use the same as in the question, you can go with the first solution. Otherwise, the second one will serve better.
Remove line-height from the .child and add height for the .parent.
Updated :
.parent {
border: 1px solid red;
display: flex;
align-items: flex-end;
height: 100px;
}
.child {
border: 1px solid green;
flex: 1;
align-items:bottom;
}
.footer{
background:#808080;
}
<div class="parent">
<div class="child">
<div class="footer">Footer</div>
</div>
<div class="child">
<div class="footer">Footer</div>
</div>
<div class="child">
<div class="footer">Footer-will be in bottom!!</div>
</div>
</div>
Related
I have been trying so hard to find a solution to this but I couldnt achieve the desired solution.
I want to have the following:
and this is what I have tried so far:
#outer-div {
width: 100%;
text-align: left;
background-color: #027DB4;
}
#inner-div {
display: inline-block;
margin: auto;
padding: 3px;
}
<div id="outer-div">
<div id="inner-div" class="input-group">
<label>1</label>
<select>
</select>
</div>
<div id="inner-div" class="input-group">
<label>2</label>
<input>
</div>
</div>
<div id="outer-div">
<div id="inner-div" class="input-group">
<label>3</label>
<input>
</div>
</div>
<div id="outer-div">
<div id="inner-div" class="input-group">
<label>4</label>
<input>
</div>
</div>
P.S. I don't want to use float because it ruins everything else in that page.
use flexbox for this kind of stuff
#container {
display: flex;
}
#left {
display: flex;
flex-direction: column;
}
#right {
display: flex;
flex: 1;
margin-left: 5vw;
flex-direction: column;
}
div {
border: solid 2px black;
}
<div id='container'>
<div id='left'>
<div> one</div>
<div> two</div>
<div> three</div>
</div>
<div id='right'>
<div>right</div>
<div>another right</div>
</div>
</div>
DCR is right on with flexbox. You can also use CSS grid and avoid nesting items https://developer.mozilla.org/en-US/docs/Web/CSS/CSS_Grid_Layout.
#outer-div {
text-align: left;
background-color: #027DB4;
display: grid;
}
.right-column {
grid-column: 2 / 2;
grid-row: 1 / 4;
}
<div id="outer-div">
<div class="input-group">1</div>
<div class="input-group">2</div>
<div class="input-group">3</div>
<div class="input-group right-column">4</div>
</div>
.box1{
display:flex;
justify-content: space-between;
}
<div class="box1">
<div class="box2">
<div class="div1">1</div>
<div class="div2">2</div>
<div class="div3">3</div>
</div>
`<div class="div4">4</div>`
</div>
If you do want to try CSS Grid, this is a route to try. .right and .left class properties are added to allow more targeted styling, if needed, and borders are added to the parent and container elements to highlight them.
.outer-div {
display: grid;
grid-template-columns: auto auto;
grid-gap: 1em;
padding: 1em;
border: 1px solid red;
}
.inner-div.left {
grid-column: 1;
border: 1px solid blue;
}
.inner-div.right {
grid-column: 2;
grid-row: 1 / span 3;
border: 1px solid green;
}
<div class="outer-div">
<div class="inner-div left">
<label>1</label>
<select>
</select>
</div>
<div class="inner-div left">
<label>2</label>
<input>
</div>
<div class="inner-div left">
<label>3</label>
<input>
</div>
<div class="inner-div right">
<label>4</label>
<input>
</div>
</div>
I stumbled upon an issue with image centering within a flexbox with direction:column.
Imagine you have two elements within a flexbox, where the first one contains an image:
<div class="container">
<div class="image-container">
<img class="img" src="https://interactive-examples.mdn.mozilla.net/media/examples/firefox-logo.svg">
</div>
<div class="another-flex-child">
Random content here
</div>
</div>
.container {
height: 300px;
background-color: green;
display: flex;
flex-direction: column;
.image-container {
flex: 1;
align-self: center;
.img {
height: 100%;
}
}
.another-flex-child {
flex: none;
background-color: red;
}
}
I would expect the image to be center horizontally within the div, but it appears the left border of the image is exactly at the center of the div.
When I replace the image with another div which contains some text it is placed as expected.
Can anybody explain to me whats happening there?
Checkout this fiddle
Because your <div> that contains the image (and has align-self: center on it) is by default a block-level element, and has a width of 100% by default. As such, it is constrained in relation to the parent.
In order to have your image centered correctly, you'll want to add display: contents with:
container .image-container {
display: inline;
}
This can be seen in the following:
.container {
height: 300px;
background-color: green;
display: flex;
flex-direction: column;
}
.container .image-container {
flex: 1;
align-self: center;
display: contents;
}
.container .image-container .img {
height: 100%;
}
.another-flex-child {
flex: none;
background-color: red;
}
.spacer {
height: 20px;
}
<div class="container">
<div class="image-container">
<img class="img" src="https://interactive-examples.mdn.mozilla.net/media/examples/firefox-logo.svg">
</div>
<div class="another-flex-child">
Random content here
</div>
</div>
<div class="spacer"></div>
<div class="container">
<div class="image-container">
<div>Properly centered content</div>
</div>
<div class="another-flex-child">
Random content here
</div>
</div>
The issue is that you are using an SVG with no intrinsic dimension and only an intrinsic ratio so it's like your image has a width equal to 0 which make its centred container with a width equal to 0, too.
Here is before using height:100%
.container {
height: 300px;
background-color: green;
display: flex;
flex-direction: column;
}
.image-container {
flex: 1;
align-self: center;
border:2px solid blue;
}
.img {
/*height: 100%;*/
}
.another-flex-child {
flex: none;
background-color: red;
}
.spacer {
height: 20px;
}
<div class="container">
<div class="image-container">
<img class="img" src="https://interactive-examples.mdn.mozilla.net/media/examples/firefox-logo.svg">
</div>
<div class="another-flex-child">
Random content here
</div>
</div>
<div class="spacer"></div>
<div class="container">
<div class="image-container">
<div>Properly centered content</div>
</div>
<div class="another-flex-child">
Random content here
</div>
</div>
After setting height:100% the image will fill all the space and will keep its ratio but you will have an overflow because the browser will not go back to calculate the width of the container again:
.container {
height: 300px;
background-color: green;
display: flex;
flex-direction: column;
}
.image-container {
flex: 1;
align-self: center;
border:2px solid blue;
}
.img {
height: 100%;
}
.another-flex-child {
flex: none;
background-color: red;
}
.spacer {
height: 20px;
}
<div class="container">
<div class="image-container">
<img class="img" src="https://interactive-examples.mdn.mozilla.net/media/examples/firefox-logo.svg" >
</div>
<div class="another-flex-child">
Random content here
</div>
</div>
<div class="spacer"></div>
<div class="container">
<div class="image-container">
<div>Properly centered content</div>
</div>
<div class="another-flex-child">
Random content here
</div>
</div>
To avoid this give the image a width and make sure to add min-height:0 to the container to allow it to shrink
.container {
height: 300px;
background-color: green;
display: flex;
flex-direction: column;
}
.image-container {
flex: 1;
align-self: center;
border:2px solid blue;
min-height:0;
}
.img {
height: 100%;
}
.another-flex-child {
flex: none;
background-color: red;
}
.spacer {
height: 20px;
}
<div class="container">
<div class="image-container">
<img class="img" src="https://interactive-examples.mdn.mozilla.net/media/examples/firefox-logo.svg" width="250">
</div>
<div class="another-flex-child">
Random content here
</div>
</div>
<div class="spacer"></div>
<div class="container">
<div class="image-container">
<div>Properly centered content</div>
</div>
<div class="another-flex-child">
Random content here
</div>
</div>
If you were initially using an image with intrinsic dimension you won't have this issue and you don't need to define a width. You will only need to add min-height:0 to avoid the overflow:
.container {
height: 300px;
background-color: green;
display: flex;
flex-direction: column;
}
.image-container {
flex: 1;
align-self: center;
border:2px solid blue;
min-height:0;
}
.img {
height: 100%;
}
.another-flex-child {
flex: none;
background-color: red;
}
.spacer {
height: 20px;
}
<div class="container">
<div class="image-container">
<img class="img" src="https://picsum.photos/id/1/400/400">
</div>
<div class="another-flex-child">
Random content here
</div>
</div>
<div class="spacer"></div>
<div class="container">
<div class="image-container">
<div>Properly centered content</div>
</div>
<div class="another-flex-child">
Random content here
</div>
</div>
Note that the above doesn't work the same way in Firefox and you will need to add text-aling:center to make sure it works the same everywhere:
.container {
height: 300px;
background-color: green;
display: flex;
flex-direction: column;
}
.image-container {
flex: 1;
align-self: center;
border:2px solid blue;
text-align:center;
min-height:0;
}
.img {
height: 100%;
}
.another-flex-child {
flex: none;
background-color: red;
}
.spacer {
height: 20px;
}
<div class="container">
<div class="image-container">
<img class="img" src="https://picsum.photos/id/1/400/400">
</div>
<div class="another-flex-child">
Random content here
</div>
</div>
<div class="spacer"></div>
<div class="container">
<div class="image-container">
<div>Properly centered content</div>
</div>
<div class="another-flex-child">
Random content here
</div>
</div>
You will notice that the difference is related to the width calculation of the container which a bit complex due to the use of height:100%
Things may get worse if the size of the image is very small:
.container {
height: 300px;
background-color: green;
display: flex;
flex-direction: column;
}
.image-container {
flex: 1;
align-self: center;
border:2px solid blue;
text-align:center;
min-height:0;
}
.img {
height: 100%;
}
.another-flex-child {
flex: none;
background-color: red;
}
.spacer {
height: 20px;
}
<div class="container">
<div class="image-container">
<img class="img" src="https://picsum.photos/id/1/50/50">
</div>
<div class="another-flex-child">
Random content here
</div>
</div>
<div class="spacer"></div>
<div class="container">
<div class="image-container">
<div>Properly centered content</div>
</div>
<div class="another-flex-child">
Random content here
</div>
</div>
In Firefox text-align:center will do nothing and you may need a nested flexbox container
.container {
height: 300px;
background-color: green;
display: flex;
flex-direction: column;
}
.image-container {
flex: 1;
align-self: center;
justify-content:center;
border:2px solid blue;
display:flex;
min-height:0;
}
.img {
height: 100%;
}
.another-flex-child {
flex: none;
background-color: red;
}
.spacer {
height: 20px;
}
<div class="container">
<div class="image-container">
<img class="img" src="https://picsum.photos/id/1/50/50">
</div>
<div class="another-flex-child">
Random content here
</div>
</div>
<div class="spacer"></div>
<div class="container">
<div class="image-container">
<div>Properly centered content</div>
</div>
<div class="another-flex-child">
Random content here
</div>
</div>
The below is almost the same issue you were having with the initial SVG that can fixed with this same code but it won't remove the overflow:
.container {
height: 300px;
background-color: green;
display: flex;
flex-direction: column;
}
.image-container {
flex: 1;
align-self: center;
display:flex;
justify-content:center;
border:2px solid blue;
}
.img {
height: 100%;
}
.another-flex-child {
flex: none;
background-color: red;
}
.spacer {
height: 20px;
}
<div class="container">
<div class="image-container">
<img class="img" src="https://interactive-examples.mdn.mozilla.net/media/examples/firefox-logo.svg" >
</div>
<div class="another-flex-child">
Random content here
</div>
</div>
<div class="spacer"></div>
<div class="container">
<div class="image-container">
<div>Properly centered content</div>
</div>
<div class="another-flex-child">
Random content here
</div>
</div>
Another intresting thing to note is that your initial code may work fine if you add height:100% to the container making the calculation of the nested height easier:
.container {
height: 300px;
background-color: green;
display: flex;
flex-direction: column;
}
.image-container {
flex: 1;
align-self: center;
border:2px solid blue;
box-sizing:border-box;
height:100%;
}
.img {
height: 100%;
display:block;
}
.another-flex-child {
flex: none;
background-color: red;
}
.spacer {
height: 20px;
}
<div class="container">
<div class="image-container">
<img class="img" src="https://interactive-examples.mdn.mozilla.net/media/examples/firefox-logo.svg" >
</div>
<div class="another-flex-child">
Random content here
</div>
</div>
<div class="spacer"></div>
<div class="container">
<div class="image-container">
<div>Properly centered content</div>
</div>
<div class="another-flex-child">
Random content here
</div>
</div>
Add the justify-content like below:
.image-container {
flex: 1;
align-self: center;
justify-content:center;
}
it should works
firstly sorry for my English,
I ask me if we can change the style of a last child in flex div when this one goes to the line (wrap).
What I want precisely is to modify the last child (.flexChild in demo) to change the justify-content at space-around or to add padding when the user is on mobile or he resize the window
(without mediaqueries)
DEMO Here
.parent {
display: flex;
align-items: center;
flex-wrap: wrap;
width: 100%;
height: 100px;
background: red;
}
.child {
padding: 0 20px;
background: green;
border: 1px solid black;
}
.flexChild {
background: yellow;
display: flex;
min-width: 200px;
flex-wrap: wrap;
flex: 1 1 auto;
justify-content: space-between;
}
<div class="parent">
<div class="child">
Testtestesttest
</div>
<div class="child">
testtesttestt
</div>
<div class="child">
testesttestest
</div>
<div class="child flexChild">
<div class="left">
<button>1</button>
<button>2</button>
</div>
<div class="right">
<button>3</button>
</div>
</div>
</div>
hey I'm new in Flexbox and I'm trying to get it as best as I can. However i faces a problem with some heights and orders, maybe some here could help out.
Note: Don't suggest using Grid/tables please.
this is what I have right now:
this is what I want to get:
html:
<div class="movie-container">
<div class="upper-container">
<div class="image">Image</div>
<div class="title">Title</div>
<div class="more">More</div>
</div>
<div class="lower-container">
<div class="runtime">Runtime</div>
<div class="description">Description</div>
<div class="director">Director</div>
</div>
</div>
css:
.movie-container{
display:flex;
flex-flow: column wrap;
}
.upper-container {
display: flex;
width:80%;
margin:0 auto;
flex-flow: raw wrap;
}
.upper-container div {
border: 1px solid black;
padding: 10px;
}
.lower-container {
display: flex;
width:80%;
margin:0 auto;
flex-flow: column wrap;
}
.lower-container div {
border: 1px solid black;
padding: 10px;
}
.image {
flex: 1;
}
.title {
flex: 3;
}
.more {
flex: 0.1;
}
.runtime{
}
.description{
}
.director{
}
Maybe other stuff need to be added beside flexbox I'm not sure, that's why I ask here. Any solution will be helpful!
If you change your HTML structure slightly you can accomplish this fairly easily:
<div class="movie-container">
<div class="upper-container">
<div class="image">Image</div>
<div class="side-container">
<div class="title">Title</div>
<div class="more">More</div>
<div class="runtime">Runtime</div>
<div class="description">Description</div>
</div>
</div>
<div class="lower-container">
<div class="director">Director</div>
</div>
</div>
JSFiddle
Flex isn't very good at stretching across multiple rows / columns like tables or Grid is, while you state you don't want that solution it is typically a better option in cases like this.
I find it easiest to work with flexbox on a row-by-row basis instead of using wrapping (although you can certainly do that too).
As a starting point, I think this snippet is what you're going for?
div {
flex: 1 1 auto;
}
.box {
border: 1px solid black;
}
.flex {
display: flex;
}
.image {
width: 120px;
flex: 0 0 auto;
}
.more {
flex: 0 0 auto;
}
<div class="flex upper">
<div class="box flex image">Image</div>
<div class="upper-detail">
<div class="flex title-container">
<div class="box title">Title</div>
<div class="box more">More</div>
</div>
<div class="box runetime">Runtime</div>
<div class="box director">Director</div>
</div>
</div>
<div class="box description">Description</div>
<div class="box other">Other stuff...</div>
Hope this helps.
.upper-container{
display: flex;
height: 200px;
}
.upper-left{
background: #ddd;
flex: 1;
display: flex;
align-items: center;
justify-content: center;
}
.upper-right{
flex: 3;
display: flex;
flex-direction: column;
height: 100%;
}
.title-more, .runtime, .director{
flex: 1;
border: 1px solid #222;
display: flex;
align-items: center;
}
.lower-container{
border: 1px solid #222;
padding: 10px;
}
.title-more{
justify-content: space-between;
}
.more-button{
height: 30px;
width: 100px;
border: 1px solid #333;
margin-right: 5px;
display: flex;
align-items: center;
justify-content: center;
}
<div class="movie-container">
<div class="upper-container">
<div class="upper-left">
Image
</div>
<div class="upper-right">
<div class="title-more">
<div class="title-container">
Title
</div>
<div class="more-button">
More
</div>
</div>
<div class="runtime">Runtime</div>
<div class="director">Director</div>
</div>
</div>
<div class="lower-container">
Description
</div>
</div>
The key is to add some divs and remove some others:
.movie-container *{padding:.5em;}
.upper-container {
display: flex;
padding:0;
}
.image {
border: 1px solid;
flex: 1 1 25%;
}
.tmrd{flex: 1 1 75%;padding:0}
.title-more {
display: flex;
padding:0;
}
.title{flex: 1 1 75%;border: 1px solid;}
.more{flex: 1 1 25%;border: 1px solid;}
.runtime,.description,.director{border: 1px solid;}
<div class="movie-container">
<div class="upper-container">
<div class="image">Image</div>
<div class="tmrd">
<div class="title-more">
<div class="title">Title</div>
<div class="more">More</div>
</div>
<div class="runtime">Runtime</div>
<div class="description">Description</div>
</div>
</div>
<div class="director">Director</div>
</div>
I'm displaying a list of same sized items in a flex div. I've aligned them to the left. However I'd like the list to be centred as a whole. Any suggestions about how to do this?
Please try to snipped below.
$('button').click(function(){
$('.list').toggleClass('hack')
});
.item {
width: 40px;
height: 40px;
background-color: skyblue;
border: 1px solid black;
}
.list-container {
width: 100px;
background-color: grey;
flex-direction: row;
display: flex;
}
.spacer {
flex: 1;
}
.list.hack {
width: 84px;
}
.list {
display: inline-flex;
flex-direction: row;
flex-wrap: wrap;
background-color: yellow;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div class='list-container'>
<div class='spacer'></div>
<div class='list'>
<div class='item'></div><div class='item'></div>
<div class='item'></div><div class='item'></div>
<div class='item'></div>
</div>
<div class='spacer'></div>
</div>
<button>Toggle fixed list width (hack)</button>
I believe the best way is to insert the "item" elements to a new div, setting:
<div style="margin:0 auto;width: 85px;">
<div class="item"></div>
<div class="item"></div>
<div class="item"></div>
<div class="item"></div>
<div class="item"></div>
</div>
and also applying .item{float:left;}
It's not enough when you set justify-content: center; to .list?
Then if you need to make the standalone item to be aligned to left, you can set its margin-right: 42px; (to compensate the space next to it)
You can do the same without using flex
HTML
<div class='list'>
<div class='item'>item 1</div><div class='item'>item 2</div>
<div class='item'>item 3</div><div class='item'>item 4</div>
<div class='item'>item 5</div>
</div>
CSS
.list{
display:inline-block;
background-color: grey;
width:100px;
clear:both;
justify-content: center;
}
.list .item{
float:left;
width:48%;
background-color: skyblue;
height: 40px;
border: 1px solid black;
}
.list .item:last-child{
margin-left:25%;
}
Click here for JSFiddle sample