I am trying to use "vertical-align: bottom;" to have DIVs go from the bottom of the wrapper/parent DIV to the top. The only problem is that I would like the first DIVs to be displayed at the bottom, NOT at the top like they usually are by default. This is only because I always want the bottom row to be full by having the first ones entered at the very bottom.
The order of the DIVs are not actually essential but I really want the very bottom "row" to be completely filled with the top row the only one which sometimes will only have 1 or 2 boxes on top for example. By adding new boxes on the top rather than at the bottom it would result in the layout I've described. I hope that makes sense.
Also the code I have added below shows gaps in between each "column" which I have been trying to remove. It might not matter if I have to change all the code to fix the first problem but if anyone knows why this is and lets me know, that would be great :)
Thanks!
Here is what I have so far:
div.wrapper {
display: table-cell;
vertical-align: bottom;
height: 500px;
width: 640px;
background-color: lightgrey;
}
div.wrapper div {
width: 200px;
height: 50px;
display: inline-block;
}
div.wrapper div p {
margin: 0px;
padding: 0px;
}
<div class="wrapper">
<div style="background-color: #7E7ECC;">
<p>1</p>
</div>
<div style="background-color: #FFA347;">
<p>2</p>
</div>
<div style="background-color: #80E680;">
<p>3</p>
</div>
<div style="background-color: #FF99C2;">
<p>4</p>
</div>
<div style="background-color: #A6DBEE;">
<p>5</p>
</div>
</div>
And this is what I want to create:
This would also be acceptable:
You can do it with CSS3 flexbox layout. flex-wrap: wrap-reverse is the key property here as it allows the items to wrap in opposite direction of the flex-direction: row
align-content: flex-start is used instead of *-end since the wrap order was reversed.
div.wrapper {
/* Added Properties */
display: flex;
flex-direction: row;
flex-wrap: wrap-reverse;
align-content: flex-start;
/* ^ Added Properties */
background-color: lightgrey;
height: 150px;
vertical-align: bottom;
width: 640px;
}
div.wrapper div {
width: 200px;
height: 50px;
display: inline-block;
}
div.wrapper div p {
margin: 0px;
padding: 0px;
}
<div class="wrapper">
<div style="background-color: #7E7ECC;">
<p>1</p>
</div>
<div style="background-color: #FFA347;">
<p>2</p>
</div>
<div style="background-color: #80E680;">
<p>3</p>
</div>
<div style="background-color: #FF99C2;">
<p>4</p>
</div>
<div style="background-color: #A6DBEE;">
<p>5</p>
</div>
</div>
You can solve this problem adding flex layout to wrapper and display items in row, which you want to reverse it to get the stacking effect. See the css below:
div.wrapper {
display: table-cell;
vertical-align: bottom;
height: 500px;
width: 640px;
background-color: lightgrey;
display: flex; /* added */
flex-direction: row; /* added */
flex-wrap: wrap-reverse; /* added */
align-content: flex-start; /* added */
}
div.wrapper div {
width: 200px;
height: 50px;
display: inline-block;
}
div.wrapper div p {
margin: 0px;
padding: 0px;
}
Here is a FIDDLE
Related
Doing a fairly basic HTML page I found myself perplexed by the following issue with flex in CSS.
First assume the following configuration:
A div wrapper with display: flex and applying justify-content: space-evenly, containing three inner boxes (could be more or less) each one also using flex (applying flex-wrap: wrap and align-items: end).
Each one of those inner boxes contains, in turn, two div elements: a top one and a bottom one (each with width: 100%); the bottom element has the same height while the top element has a different height per box; all of them are fixed heights in px.
This configuration looks more or less like this in HTML:
<div class="wrapper">
<div class="box">
<div class="top-element one"></div>
<div class="bottom-element one"></div>
</div>
<div class="box">
<div class="top-element two"></div>
<div class="bottom-element two"></div>
</div>
<div class="box">
<div class="top-element three"></div>
<div class="bottom-element three"></div>
</div>
</div>
And here's the CSS (written in SCSS to save space, I will include a snippet below where you can check the compiled CSS should you prefer); the commented line: "align-content: flex-end" indicates that I've already evaluated the effect of this property.
.wrapper {
display: flex;
justify-content: space-evenly;
.box {
display: flex;
align-items: flex-end;
// align-content: flex-end;
flex-wrap: wrap;
width: 30%;
.top-element {
width: 100%;
background-color: teal;
&.one {
height: 200px;
}
&.two {
height: 300px;
}
&.three {
height: 100px;
}
}
.bottom-element {
width: 100%;
background-color: lightblue;
&.one {
height: 100px;
}
&.two {
height: 100px;
}
&.three {
height: 100px;
}
}
}
}
Here's the snippet.
.wrapper {
display: flex;
justify-content: space-evenly;
}
.wrapper .box {
display: flex;
align-items: flex-end;
flex-wrap: wrap;
width: 30%;
}
.wrapper .box .top-element {
width: 100%;
background-color: teal;
}
.wrapper .box .top-element.one {
height: 200px;
}
.wrapper .box .top-element.two {
height: 300px;
}
.wrapper .box .top-element.three {
height: 100px;
}
.wrapper .box .bottom-element {
width: 100%;
background-color: lightblue;
}
.wrapper .box .bottom-element.one {
height: 100px;
}
.wrapper .box .bottom-element.two {
height: 100px;
}
.wrapper .box .bottom-element.three {
height: 100px;
}
<div class="wrapper">
<div class="box">
<div class="top-element one"></div>
<div class="bottom-element one"></div>
</div>
<div class="box">
<div class="top-element two"></div>
<div class="bottom-element two"></div>
</div>
<div class="box">
<div class="top-element three"></div>
<div class="bottom-element three"></div>
</div>
</div>
The issue is: It doesn't matter if you change the height of any of the top elements on any inner box, these remain vertically center-aligned according to the tallest element among all boxes, while the bottom ones remain at the bottom, and the space between top and bottom elements on each box is proportionally kept.
Now the question(s): is this correct css? and if so, I'm suspicious of align-items:"end" on each box to be the one to blame for this result, am I right? and if I'm wrong, why does this happen then?
Why didn't I use grid? well I'm in my flex phase... bear with me please.
You forget to define a vertical flex main direction for the elements with the CSS class .box.
Setting CSS property's flex-direction value to column for those elements fixes your problem.
SCSS
.box {
display: flex;
flex-direction: column;
...
I am trying to fill the remaining space of a containing flex box with the green div. I want the top flex row (blue) to only be the height of its contents and then the row below (green) to fill the rest. For some reason it just seems to split the flex rows evenly down the div. I have read a few questions on here already which all say to make sure the containing div has its height set to 100%. I have set the containing div height to 200px as this is my desired height, but I have also tried adding another container within this to 100% to no avail. I've also made sure to set the flex-grow property on the second row to 1. Every time I think I'm beginning to understand flex it throws another curve ball and it's driving me up the wall. Please help! Thank you.
P.S. for some reason the HTML code snippet below refuses to include the first line of my html but it is contained in the following div: <div class="rmCtrlList_item"
.rmCtrlList_item {
width: 80vw;
margin: 3vw 8.5vw;
height: 200px;
background-color: $primary-color;
border-radius: 10px;
padding: 5px;
display: flex;
flex-flow: row;
flex-wrap: wrap;
// ROWS
&_row {
width: 100%;
display: flex;
flex-direction: row;
flex-wrap: wrap;
}
#row-1 {
//max-height: 20px;
background-color: blue;
}
#row-2 {
flex-grow: 1;
align-items: center;
justify-content: center;
background-color: green;
}
// COLUMNS
&_col {
text-align: left;
flex-direction: column;
}
#col-1b {
flex-grow: 1;
}
}
<div class="rmCtrlList_item">
<div class="rmCtrlList_item_row" id="row-1">
<div class="rmCtrlList_item_col" id="col-1a">
<i class="icon__panel-2 fas fa-lightbulb"></i>
</div>
<div class="rmCtrlList_item_col" id="col-1b">
<a href="lights.html">
<h1 class="panel__title">Lights</h1>
</a>
</div>
<div class="rmCtrlList_item_col" id="col-1c">
<i class="icon__enlarge fas fa-plus-circle"></i>
</div>
</div>
<div class="rmCtrlList_item_row" id="row-2">
div to fill remaining space
</div>
</div>
how about to use flex-direction and below code what I used? green will fill ramaining space automatically, if you use its height's 100%
.container{
display: flex;
flex-direction: column;
width: 200px;
height: 300px;
border: 1px solid black;
}
.blue{
width: 100%;
height: 90px; /*change only blue's height size, green will be filled automatically*/
background: blue;
}
.green{
width: 100%;
height: 100%;
background: green;
}
<div class="container">
<div class="blue"></div>
<div class="green"></div>
</div>
I'm just trying the FlexLayout for different screen sizes.
The 3 boxes/divs below should be side to side on a large display, if it shrinks they should be above each other. But my top div is outside of my window and I don't want that.. How can I fix that?
<div class="container" fxLayout="row" fxLayout.lt-md="column" fxLayoutAlign="space-around center">
<div class="asd" [style.background-color]="'black'"></div>
<div class="asd" [style.background-color]="'green'"></div>
<div class="asd" [style.background-color]="'blue'"></div>
</div>
.asd {
min-height: 500px;
min-width: 400px;
}
.container {
height: 100%;
}
Flex elements won't stack unless you use flex-wrap: wrap along with a min-width or flex-basis declaration.
Basically, if the number of flex elements in the row would need to be smaller than their min-width they'll wrap to the next line.
.flexContainer {
display:flex;
max-width: 80%;
margin: 20px;
justify-content: space-between;
flex-wrap: wrap;
}
.flexItem {
background: #dddddd;
padding: 20px;
min-width: 200px;
margin: 0 10px 10px 0;
}
<div class="flexContainer">
<div class="flexItem">Flex</div>
<div class="flexItem">Flex</div>
<div class="flexItem">Flex</div>
<div class="flexItem">Flex</div>
</div>
Scenario :
I'm creating a pricing comparison table and am having difficulties aligning the last div, card-vat-fee, to the bottom of the container.
I need to do this because the tiers have longer running lists than
one another, causing the last div isn't aligned with the bottom of
the container.
How can I get the last div to align to the bottom of the flexbox?
Tried Case :
Of course, if I set a min-height: 320px; on the card-vat-fee class it will align the div to the bottom, however this isn't a responsive solution and I feel like there is a better approach that uses flex properties. Moreover, setting the card-vat-fee div to flex-grow, flex: 1 1 auto, produces an unideal solution.
Code :
<div class='pricing__tier'>
<div class='uni-card-header'>
</div>
<div class='uni-card-body'>
<div class='uni-row-on'>
</div>
<div class='uni-row-off'>
</div>
<div class='uni-row-on card-vat-fee'>
<div class='vat-fee-text'>
Credit card fees and VAT apply. See below for details.
</div>
</div>
</div>
</div>
<style>
.pricing__tier {
padding: 0;
text-align: center;
display: flex;
flex-direction: column;
width: 0%;
flex: 1;
}
.uni-card-body {
display: flex;
flex-direction: column;
}
</style>
Pricing Tier
Please Suggest.
Thanks in advance
Use margin-top:auto on the last div.
.pricing__tier {
padding: 0;
text-align: center;
display: flex;
flex-direction: column;
width: 25%;
flex: 1;
height: 200px; /* for demo purposes */
border: 1px solid grey;
}
.uni-card-body {
display: flex;
flex-direction: column;
flex: 1;
}
.card-vat-fee {
margin-top: auto; /* push to bottom */
background: green;
}
<div class='pricing__tier'>
<div class='uni-card-header'>
</div>
<div class='uni-card-body'>
<div class='uni-row-on'>
</div>
<div class='uni-row-off'>
</div>
<div class='uni-row-on card-vat-fee'>
<div class='vat-fee-text'>
Credit card fees and VAT apply. See below for details.
</div>
</div>
</div>
</div>
plaesa try this one :
.uni-card-body {
display: flex;
flex-direction: column;
width: 'for example' 700px;
}
.uni-row-on.card-vat-fee{
align-self: flex-end;
}
Ihope this will help you!
.uni-card-body {
display: flex;
flex-flow: row wrap;
justify-content: center;
background: yellow;
height: 90vh;
}
.uni-row-on.card-vat-fee {
align-self: flex-end;
background: green;
}
<div class='pricing__tier'>
<div class='uni-card-header'>
</div>
<div class='uni-card-body'>
<div class='uni-row-on'>
</div>
<div class='uni-row-off'>
</div>
<div class='uni-row-on card-vat-fee'>
<div class='vat-fee-text'>
Credit card fees and VAT apply. See below for details.
</div>
</div>
</div>
</div>
I've illustrated the thing in the snippet, it'll help.
Note: Content justification, background and height are for demonstration and not necessary.
1- set the parent div relative position without top & left & right &
bottom property
2- set the last div position absolute with bottom:0;right:0;left:0;height:36px;
<style>
.pricing__tier {
position:relative;
padding: 0;
text-align: center;
display: flex;
flex-direction: column;
width: 0%;
flex: 1;
}
.pricing__tier>.vat-fee-text {
position:absolute;
bottom:0;
right:0;
left:0;
height:36px;
}
</style>
I'm using flexbox to align my child elements. What I'd like to do is center one element and leave the other aligned to the very left. Normally I would just set the left element using margin-right: auto. The problem is that pushes the center element off center. Is this possible without using absolute positioning?
HTML & CSS
#parent {
align-items: center;
border: 1px solid black;
display: flex;
justify-content: center;
margin: 0 auto;
width: 500px;
}
#left {
margin-right: auto;
}
#center {
margin: auto;
}
<div id="parent">
<span id="left">Left</span>
<span id="center">Center</span>
</div>
Add third empty element:
<div class="parent">
<div class="left">Left</div>
<div class="center">Center</div>
<div class="right"></div>
</div>
And the following style:
.parent {
display: flex;
}
.left, .right {
flex: 1;
}
Only left and right are set to grow and thanks to the facts that...
there are only two growing elements (doesn't matter if empty) and
that both get same widths (they'll evenly distribute the available space)
...center element will always be perfectly centered.
This is much better than accepted answer in my opinion because you do not have to copy left content to right and hide it to get same width for both sides, it just magically happens (flexbox is magical).
In action:
.parent {
display: flex;
}
.left,
.right {
flex: 1;
}
/* Styles for demonstration */
.parent {
padding: 5px;
border: 2px solid #000;
}
.left,
.right {
padding: 3px;
border: 2px solid red;
}
.center {
margin: 0 3px;
padding: 3px;
border: 2px solid blue;
}
<div class="parent">
<div class="left">Left</div>
<div class="center">Center</div>
<div class="right"></div>
</div>
EDIT: See Solo's answer below, it is the better solution.
The idea behind flexbox is to provide a framework for easily aligning elements with variable dimensions within a container. As such, it makes little sense to provide a layout where the width of one element is totally ignored. In essence, that is exactly what absolute positioning is for, as it takes the element out of the normal flow.
As far as I know, there is no nice way of doing this without using position: absolute;, so I would suggest using it... but If you REALLY don't want to, or can't use absolute positioning then I suppose you could use one of the following workarounds.
If you know the exact width of the "Left" div, then you could change justify-content to flex-start (left) and then align the "Center" div like this:
#center {
position: relative;
margin: auto;
left: -{half width of left div}px;
}
If you do not know the width, then you could duplicate "Left" on the right side, use justify-content: space-between;, and hide the new right element:
Just to be clear, this is really, really ugly... better to use absolute positioning than to duplicate content. :-)
#parent {
align-items: center;
border: 1px solid black;
display: flex;
justify-content: space-between;
margin: 0 auto;
width: 500px;
}
#right {
opacity: 0;
}
<div id="parent">
<span id="left">Left</span>
<span id="center">Center</span>
<span id="right">Left</span>
</div>
.parent {
display: flex;
}
.left {
flex: 1;
}
.parent::after {
flex: 1;
content: '';
}
<div class="parent">
<div class="left">Left</div>
<div>Center</div>
</div>
I have another solution. In my opinion, Adding an empty block to the center element is fine but code-wise it bit ugly.
Since this is 4 years old I figured I'd update this with a much easier CSS Grid solution.
#parent {
display: grid;
grid-template-columns: repeat(3, 1fr);
border: 1px solid black;
margin: 0 auto;
width: 500px;
}
#center {
text-align: center;
}
<div id="parent">
<span id="left">Left</span>
<span id="center">Center</span>
</div>
If you don't want to rely on positioning, the only way I've found that makes it truly centered is to use a combination of auto margin and negative margin prevent the centered element to getting pushed over by the left aligned element. This requires that you know the exact width of the left aligned element though.
.container {
height: 100px;
border: solid 10px skyblue;
display: flex;
justify-content: center;
}
.block {
width: 120px;
background: tomato;
}
.justify-start {
margin-right: auto;
}
.justify-center {
margin-right: auto;
margin-left: -120px;
}
<div class="container">
<div class="block justify-start"></div>
<div class="block justify-center"></div>
</div>
As far as I know this is possible with the following code.
https://jsfiddle.net/u5gonp0a/
.box {
display: flex;
justify-content: center;
background-color: green;
text-align: left;
}
.left {
padding: 10px;
background-color: pink;
}
.center {
padding: 10px;
background-color: yellow;
margin: 0 auto;
}
<div class="box">
<div class="left">left</div>
<div class="center">center</div>
</div>
Try this no hacks :)
CSS
.container{
width: 500px;
margin: 0 auto;
}
.box{
display: flex;
align-items: center;/* just in case*/
justify-content: space-between;
}
.box p:nth-child(2){
text-align: center;
background-color: lime;
flex: 1 1 0px;
}
HTML
<div class="container">
<div class="box">
<p>One</p>
<p>Two</p>
</div>
</div>
http://codepen.io/whisher/pen/XpGaEZ
If you have a grid system you can use it to do what you want without "extra" css.
Below with bootstrap (V 4.X)
Note: It uses flex under the hood
<div class="row">
<div class="col text-left">left</col>
<div class="col text-center">center</col>
<div class="col text-right">right</col>
</div>
Doc bootstrap: https://getbootstrap.com/docs/4.6/layout/grid/
Et voilĂ ! :)
Solution 1: give 50% width to center element and use justify-content:space-between
#parent {
display: flex;
justify-content: space-between;
}
#center {
flex-basis: 50%;
}
<div id="parent">
<span id="left">Left</span>
<span id="center">Center</span>
</div>
Solution 2: Add one dummy element and hide it.
#parent {
display: flex;
justify-content: space-between;
}
#right {
visibility:hidden;
}
<div id="parent">
<span id="left">Left</span>
<span id="center">Center</span>
<span id="right">Right</span>
</div>