I am trying to create a flex-box container following display:
I was able to do:
.garden {
width: 500px;
height: 500px;
background: #CCC;
}
.flower {
border: 1px solid #000;
width: 100px;
height: 100px;
}
.row {
display: flex;
}
.row:first-child {
justify-content: space-between;
}
.row:nth-child(2){
justify-content: center;
}
.row:last-child {
justify-content: space-around;
}
<div class="garden">
<div class="row">
<div class="flower red">Red</div>
<div class="flower green">Green</div>
<div class="flower yellow">Yellow</div>
</div>
<div class="row">
<div class="flower red">Red</div>
<div class="flower green">Green</div>
<div class="flower yellow">Yellow</div>
</div>
<div class="row">
<div class="flower red">Red</div>
<div class="flower green">Green</div>
<div class="flower yellow">Yellow</div>
</div>
</div>
How should I align first row to the top, 2nd row to middle center and last row to bottom?
You could set also the .garden element as a flexbox container, with column direction and proper spacing:
.garden {
width: 500px;
height: 500px;
background: #CCC;
display: flex;
flex-direction: column;
justify-content: space-between
}
.flower {
border: 1px solid #000;
width: 100px;
height: 100px;
}
.row {
display: flex;
}
.row:first-child {
justify-content: space-between;
}
.row:nth-child(2){
justify-content: center;
}
.row:last-child {
justify-content: space-around;
}
<div class="garden">
<div class="row">
<div class="flower red">Red</div>
<div class="flower green">Green</div>
<div class="flower yellow">Yellow</div>
</div>
<div class="row">
<div class="flower red">Red</div>
<div class="flower green">Green</div>
<div class="flower yellow">Yellow</div>
</div>
<div class="row">
<div class="flower red">Red</div>
<div class="flower green">Green</div>
<div class="flower yellow">Yellow</div>
</div>
</div>
Related
I want a layout with a header, body, and footer. I do not want to use display: fixed, so I'm only scrolling the body. I use flex-grow: 1 to force the body section to fill the height.
The body has 4 columns. The columns are taller than the height of the body, so the body scrolls. However, the columns do not scroll, only their content.
In this codepen, scroll the middle section with the 4 columns. Note the gold background of the columns does not scroll. Instead, you see the orange background of the body.
How do I get the body content area to fill the screen if there's less content but also have the content background expand with the content when it scrolls? I've tried adding clearing div's and setting the column height to 100%.
Video illustration of the problem: http://recordit.co/eGpT87EmPp
* {
box-sizing: border-box;
padding: 0;
margin: 0;
}
html,
body {
height: 100vh;
}
.App {
background: red;
display: flex;
flex-direction: column;
height: 100vh;
}
.App .Header {
background: violet;
display: flex;
min-height: 2rem;
}
.App .Header .Player {
background: pink;
flex: 1 1;
text-align: center;
}
.App .Body {
background: orange;
display: flex;
flex-grow: 1;
overflow-y: scroll;
}
.App .Body .Column {
background: gold;
box-shadow: inset -1px 0 0 0 black;
display: flex;
flex-direction: column;
flex: 1 1;
padding-top: 1rem;
}
.App .Tile {
background: #111;
color: white;
margin: 0 auto 1rem;
padding: 5rem 0;
text-align: center;
width: 4rem;
}
.App .Footer {
background: deepskyblue;
min-height: 2rem;
}
<div class="App">
<div class="Header">
<div class="Player">Player</div>
<div class="Player">Player</div>
<div class="Player">Player</div>
<div class="Player">Player</div>
</div>
<div class="Body">
<div class="Column">
<div class="Tile">0</div>
<div class="Tile">1</div>
<div class="Tile">2</div>
<div class="Tile">3</div>
<div class="Tile">4</div>
<div class="Tile">5</div>
<div class="Tile">6</div>
<div class="Tile">7</div>
<div class="Tile">8</div>
<div class="Tile">9</div>
<div class="Tile">10</div>
<div class="Tile">11</div>
<div class="Tile">12</div>
<div class="Tile">13</div>
<div class="Tile">14</div>
<div class="Tile">15</div>
<div class="Tile">16</div>
<div class="Tile">17</div>
<div class="Tile">18</div>
<div class="Tile">19</div>
</div>
<div class="Column">
<div class="Tile">0</div>
<div class="Tile">1</div>
<div class="Tile">2</div>
<div class="Tile">3</div>
<div class="Tile">4</div>
<div class="Tile">5</div>
<div class="Tile">6</div>
<div class="Tile">7</div>
<div class="Tile">8</div>
<div class="Tile">9</div>
<div class="Tile">10</div>
<div class="Tile">11</div>
<div class="Tile">12</div>
<div class="Tile">13</div>
<div class="Tile">14</div>
<div class="Tile">15</div>
<div class="Tile">16</div>
<div class="Tile">17</div>
<div class="Tile">18</div>
<div class="Tile">19</div>
</div>
<div class="Column">
<div class="Tile">0</div>
<div class="Tile">1</div>
<div class="Tile">2</div>
<div class="Tile">3</div>
<div class="Tile">4</div>
<div class="Tile">5</div>
<div class="Tile">6</div>
<div class="Tile">7</div>
<div class="Tile">8</div>
<div class="Tile">9</div>
<div class="Tile">10</div>
<div class="Tile">11</div>
<div class="Tile">12</div>
<div class="Tile">13</div>
<div class="Tile">14</div>
<div class="Tile">15</div>
<div class="Tile">16</div>
<div class="Tile">17</div>
<div class="Tile">18</div>
<div class="Tile">19</div>
</div>
<div class="Column">
<div class="Tile">0</div>
<div class="Tile">1</div>
<div class="Tile">2</div>
<div class="Tile">3</div>
<div class="Tile">4</div>
<div class="Tile">5</div>
<div class="Tile">6</div>
<div class="Tile">7</div>
<div class="Tile">8</div>
<div class="Tile">9</div>
<div class="Tile">10</div>
<div class="Tile">11</div>
<div class="Tile">12</div>
<div class="Tile">13</div>
<div class="Tile">14</div>
<div class="Tile">15</div>
<div class="Tile">16</div>
<div class="Tile">17</div>
<div class="Tile">18</div>
<div class="Tile">19</div>
</div>
</div>
<div class="Footer">Footer</div>
</div>
So it doesn't look like you want the individual columns to scroll. If I've misinterpreted that requirement, then the solution is simple.
Make these adjustments to your code:
.Body {
background: orange;
display: flex;
flex-grow: 1;
/* overflow-y: scroll; */
min-height: 0; /* new */
}
.Column {
overflow: auto; /* new */
background: gold;
box-shadow: inset -1px 0 0 0 black;
display: flex;
flex-direction: column;
flex: 1 1;
padding-top: 1rem;
}
codepen
Here's an explanation for the modifications above: Why don't flex items shrink past content size?
If you just want the .Body element to scroll, add a wrapper:
<div class="Body">
<section><!---- NEW ----->
<div class="Column">
<div class="Tile">0</div>
<div class="Tile">1</div>
<div class="Tile">2</div>
<div class="Tile">3</div>
. . .
.Body {
background: orange;
flex-grow: 1;
overflow: auto;
}
section {
display: flex;
}
codepen
Here's an explanation for the modifications above: Make background color extend into overflow area
So I have a structure pretty similar to the snippet below.
The issue I have is that I am trying to make it so that the divs such as child always take the same height relative to the container even if they are empty. So if there are two children they have to be 50% of the parent if there are three children 33.3% of the parent and ec.
Did a lot of digging, tried usingflex-grow and setting it on the children, adding an after content on the childContent class if it was empty but the empty children still collapse.
Is it even possible to achieve equal heights on the children without using js and fixed heights and if yes how?
.container {
display: flex;
flex-direction: column;
height: 100%;
width: 100%;
overflow: auto;
}
.child {
height: 100%;
display: flex;
flex-direction: column;
}
.childHeader {
display: flex;
flex-direction: row;
}
.headerItem {
background-color: red;
}
.childContent {
background-color: white;
}
.childContent:empty:after {
content: '.';
visibility: hidden;
min-height: 300px;
}
.contentItem {
background-color: skyblue;
border: 3px solid black;
}
<div class="container">
<div class="child">
<div class="childHeader">
<div class="headerItem">1</div>
<div class="headerItem">2</div>
<div class="headerItem">3</div>
<div class="headerItem">4</div>
<div class="headerItem">5</div>
<div class="headerItem">6</div>
<div class="headerItem">7</div>
</div>
<div class="childContent">
<div class="contentItem">1</div>
<div class="contentItem">2</div>
<div class="contentItem">3</div>
<div class="contentItem">4</div>
<div class="contentItem">5</div>
<div class="contentItem">6</div>
<div class="contentItem">7</div>
</div>
</div>
<div class="child">
<div class="childHeader">
<div class="headerItem">1</div>
<div class="headerItem">2</div>
<div class="headerItem">3</div>
<div class="headerItem">4</div>
<div class="headerItem">5</div>
<div class="headerItem">6</div>
<div class="headerItem">7</div>
</div>
<div class="childContent">
</div>
</div>
<div class="child">
<div class="childHeader">
<div class="headerItem">1</div>
<div class="headerItem">2</div>
<div class="headerItem">3</div>
<div class="headerItem">4</div>
<div class="headerItem">5</div>
<div class="headerItem">6</div>
<div class="headerItem">7</div>
</div>
<div class="childContent">
</div>
</div>
</div>
Check this out, I'm not really sure if this is what you want to do.
I just added min-height: calc(100vh - 60px); in your .childContent
.container {
display: flex;
flex-direction: column;
height: 100%;
width: 100%;
overflow: auto;
}
.child {
display: flex;
flex-direction: column;
}
.childHeader {
display: flex;
flex-direction: row;
}
.headerItem {
display:flex;
flex-basis:100%;
background-color: red;
}
.childContent {
background-color: grey;
position: relative;
display: block;
min-height: calc(80vh - 60px);
}
.childContent:empty::after {
content: '.';
visibility: hidden;
}
.contentItem {
background-color: skyblue;
border: 3px solid black;
}
<div class="container">
<div class="child">
<div class="childHeader">
<div class="headerItem">1</div>
<div class="headerItem">2</div>
<div class="headerItem">3</div>
<div class="headerItem">4</div>
<div class="headerItem">5</div>
<div class="headerItem">6</div>
<div class="headerItem">7</div>
</div>
<div class="childContent">
<div class="contentItem">1</div>
<div class="contentItem">2</div>
<div class="contentItem">3</div>
<div class="contentItem">4</div>
<div class="contentItem">5</div>
<div class="contentItem">6</div>
<div class="contentItem">7</div>
</div>
</div>
<div class="child">
<div class="childHeader">
<div class="headerItem">1</div>
<div class="headerItem">2</div>
<div class="headerItem">3</div>
<div class="headerItem">4</div>
<div class="headerItem">5</div>
<div class="headerItem">6</div>
<div class="headerItem">7</div>
</div>
<div class="childContent">
</div>
</div>
<div class="child">
<div class="childHeader">
<div class="headerItem">1</div>
<div class="headerItem">2</div>
<div class="headerItem">3</div>
<div class="headerItem">4</div>
<div class="headerItem">5</div>
<div class="headerItem">6</div>
<div class="headerItem">7</div>
</div>
<div class="childContent">
</div>
</div>
</div>
Check this one out https://developer.mozilla.org/en-US/docs/Web/CSS/calc
Question: How can I get a border to stretch to the height of the parent and surround child cell. Given I am using flexbox and aligning to baseline.
Can this be done with all css?
More Details:
I am using flex box to align my items in each row to a certain baseline. It is centered on each cell under "center here" in the following picture:
When I hover currently on each item it hovers with a solid line with a 10px margin around each cell:
I want the on hover border to stretch to the top and bottom of the row on hover like this:
That way when I hover on each item, their hover border boxes would line up like this:
^ this is what I would like it to look like if I turn hover on, on each cell.
codepen
/* on hover i want this to be a box around the item, and to have the top and the bottom of the border be touching the top/bottom of the row it is on */
.flex-item:hover {
border: 1px solid darkred;
}
/* so item doesn't move when not hovering */
.flex-item {
border: 1px solid lightblue;
}
.flex-container {
overflow: hidden; position: relative;
display: -webkit-flex;
display: flex;
-webkit-align-items: baseline;
align-items: baseline;
width: 400px;
height: 350px;
background-color: lightblue;
flex-wrap: wrap;
padding: 10px;
}
.inner-wrapper {
display: inline-block;
text-align: center;
width: 100px;
margin: 10px;
background-color: cornflowerblue;
}
.flex-body {
border-bottom: 1px solid #fff;
}
.flex-body-more {
float: left;
clear: left;
width: 100%;
}
.flex-img {
justify-content: center;
align-items: center;
}
<div class="flex-container">
<div class="flex-item">
<div class="inner-wrapper">
<div class="flex-title">flex title1</div>
<div class="flex-img">
<img src='http://dummyimage.com/90x40/000/ffffff&text=hi'>
</div>
<div class="flex-body">center here</div>
<div class="flex-body-more">more text</div>
</div>
</div>
<div class="flex-item">
<div class="inner-wrapper">
<div class="flex-title">flex title1 longer title</div>
<div class="flex-img">
<img src='http://dummyimage.com/40x40/000/ffffff&text=hi'>
</div>
<div class="flex-body">center here</div>
<div class="flex-body-more">more text</div>
</div>
</div>
<div class="flex-item">
<div class="inner-wrapper">
<div class="flex-title">flex title1</div>
<div class="flex-img">
<img src='http://dummyimage.com/40x90/000/ffffff&text=hi'>
</div>
<div class="flex-body">center here</div>
<div class="flex-body-more">more text more text more text</div>
</div>
</div>
<div class="flex-item">
<div class="inner-wrapper">
<div class="flex-title">flex title1</div>
<div class="flex-img">
<img src='http://dummyimage.com/90x40/000/ffffff&text=hi'>
</div>
<div class="flex-body">center here</div>
<div class="flex-body-more">more text</div>
</div>
</div>
<div class="flex-item">
<div class="inner-wrapper">
<div class="flex-title">flex title1</div>
<div class="flex-img">
<img src='http://dummyimage.com/40x50/000/ffffff&text=hi'>
</div>
<div class="flex-body">center here</div>
<div class="flex-body-more">more text</div>
</div>
</div>
</div>
Just a few rules that you'll need to adjust to your flex items:
.flex-item {
border: 1px solid lightblue;
transition: .7s;
display: flex;
align-items: flex-end;
}
.flex-container {
overflow: hidden;
position: relative;
display: -webkit-flex;
display: flex;
width: 400px;
height: 350px;
background-color: lightblue;
flex-wrap: wrap;
padding: 10px;
justify-content: flex-start;
}
See code snippet below:
/* on hover i want this to be a box around the item, and to have the top and the bottom of the border be touching the top/bottom of the row it is on */
.flex-item:hover {
border: 1px solid darkred;
}
/* so item doesn't move when not hovering */
.flex-item {
border: 1px solid lightblue;
transition: .7s;
display: flex;
align-items: flex-end;
}
.flex-container {
overflow: hidden;
position: relative;
display: -webkit-flex;
display: flex;
width: 400px;
height: 350px;
background-color: lightblue;
flex-wrap: wrap;
padding: 10px;
justify-content: flex-start;
}
.inner-wrapper {
display: inline-block;
text-align: center;
width: 100px;
margin: 10px;
background-color: cornflowerblue;
}
.flex-body {
border-bottom: 1px solid #fff;
}
.flex-body-more {
float: left;
clear: left;
width: 100%;
}
.flex-img {
justify-content: center;
align-items: center;
}
<div class="flex-container">
<div class="flex-item">
<div class="inner-wrapper">
<div class="flex-title">flex title1</div>
<div class="flex-img">
<img src='http://dummyimage.com/90x40/000/ffffff&text=hi'>
</div>
<div class="flex-body">center here</div>
<div class="flex-body-more">more text</div>
</div>
</div>
<div class="flex-item">
<div class="inner-wrapper">
<div class="flex-title">flex title1 longer title</div>
<div class="flex-img">
<img src='http://dummyimage.com/40x40/000/ffffff&text=hi'>
</div>
<div class="flex-body">center here</div>
<div class="flex-body-more">more text</div>
</div>
</div>
<div class="flex-item">
<div class="inner-wrapper">
<div class="flex-title">flex title1</div>
<div class="flex-img">
<img src='http://dummyimage.com/40x90/000/ffffff&text=hi'>
</div>
<div class="flex-body">center here</div>
<div class="flex-body-more">more text more text more text</div>
</div>
</div>
<div class="flex-item">
<div class="inner-wrapper">
<div class="flex-title">flex title1</div>
<div class="flex-img">
<img src='http://dummyimage.com/90x40/000/ffffff&text=hi'>
</div>
<div class="flex-body">center here</div>
<div class="flex-body-more">more text</div>
</div>
</div>
<div class="flex-item">
<div class="inner-wrapper">
<div class="flex-title">flex title1</div>
<div class="flex-img">
<img src='http://dummyimage.com/40x50/000/ffffff&text=hi'>
</div>
<div class="flex-body">center here</div>
<div class="flex-body-more">more text</div>
</div>
</div>
</div>
How can I force flexbox items to have same height.
In examples I found online, people are using align-items: stretch css property, but my example is more complex.
Here is a codepen example:
.container {
background-color: red;
display: flex;
align-items: stretch;
}
.boxes {
background-color: yellow;
margin: 5px;
display: flex;
}
.boxes-column {
flex-direction: column;
}
.box {
background-color: green;
width: 100px;
margin: 5px;
}
.heading {
background-color: pink;
}
<body>
<div class="container">
<div class="boxes boxes-column">
<div class="heading">This is heading</div>
<div class="boxes">
<div class="box">Content content content content content content content</div>
<div class="box">Content content</div>
<div class="box">Content</div>
<div class="box">Contento contento</div>
<div class="box">Cc</div>
<div class="box">Contetno contento contento</div>
</div>
</div>
<div class="boxes boxes-column">
<div class="heading">This is heading 2</div>
<div class="boxes">
<div class="box">Content</div>
<div class="box">Contentno Contetn</div>
<div class="box">C</div>
</div>
</div>
</div>
</body>
Height of items items below 'Heading' and height of items below 'Heading 2' should be equal.
Used this css and now the boxes have the same height:
.container > .boxes > .boxes {
flex: 1;
}
Take a look at the below snippet:
.container {
background-color: red;
display: flex;
align-items: stretch;
}
.boxes {
background-color: yellow;
margin: 5px;
display: flex;
}
.boxes-column {
flex-direction: column;
}
.box {
background-color: green;
width: 100px;
margin: 5px;
}
.heading {
background-color: pink;
}
.container > .boxes > .boxes {
flex: 1;
}
<body>
<div class="container">
<div class="boxes boxes-column">
<div class="heading">This is heading</div>
<div class="boxes">
<div class="box">Content content content content content content content</div>
<div class="box">Content content</div>
<div class="box">Content</div>
<div class="box">Contento contento</div>
<div class="box">Cc</div>
<div class="box">Contetno contento contento</div>
</div>
</div>
<div class="boxes boxes-column">
<div class="heading">This is heading 2</div>
<div class="boxes">
<div class="box">Content</div>
<div class="box">Contentno Contetn</div>
<div class="box">C</div>
</div>
</div>
</div>
</body>
I am trying to adjust date and time to be on the same level as city name. Please, see the picture below. Blue path line doesn't start from the beginning of city name because .flight-date element moved to next line. How can I make date-time element to grow to top instead of bottom or propose any other solutions how can I achieve the similar result?
CodePen example
HTML:
<div class="container-fluid">
<div class="roundtrip">
<div class="trip col-xs-5">Outbound
<div class="flight">
<div class="date-time col-xs-offset-4 col-xs-1">
<div class="flight-time pull-right">12:40</div>
<div class="flight-date pull-right">Friday 11 Sep</div>
</div>
<div class="col-xs-offset-0 col-xs-2">
Los Angeles
</div>
</div>
<div class="flight-path"></div>
<div class="flight">Chicago</div>
<div class="connection">5hr wait</div>
<div class="flight">Chicago</div>
<div class="flight-path"></div>
<div class="flight">New York</div>
<div class="connection">2hr wait</div>
<div class="flight">New York</div>
<div class="flight-path"></div>
<div class="flight">Amsterdam</div>
</div>
<!-- just padding: --><div class="col-xs-2"></div>
<div class="trip col-xs-5">Inbound
<div class="flight">Amsterdam</div>
<div class="flight-path"></div>
<div class="flight">Los Angeles</div>
</div>
</div>
</div>
LESS:
body {padding: 2em 0 0 2em}
.roundtrip {
width: 100%;
display: inline-flex;
flex-direction: row;
align-items: stretch;
}
.trip {
//width: 100px;
text-align: center;
border: 1px solid black;
//margin: 0px 3px;
display: flex;
flex-direction: column;
}
.flight {
white-space: nowrap;
}
.date-time{
vertical-align:top
}
.flight-path {
width: 6px;
min-height: 85px;
flex-grow: 1;
align-self: center;
background-color: #6090FF;
}
.connection {
height: 40px;
align-self: center;
width: 70px;
color: red;
border: 1px solid red;
display: flex;
flex-direction: column;
justify-content: center;
}
You can use flexbox like this:
body {
padding: 2em 0 0 2em
}
.align-bottom { /*added*/
display: flex;
align-items: flex-end;
}
.roundtrip {
width: 100%;
display: inline-flex;
flex-direction: row;
align-items: stretch;
}
.trip {
//width: 100px;
text-align: center;
border: 1px solid black;
//margin: 0px 3px;
display: flex;
flex-direction: column;
}
.flight {
white-space: nowrap;
}
.date-time {
text-align: center;
}
.flight-path {
width: 6px;
min-height: 85px;
flex-grow: 1;
align-self: center;
background-color: #6090FF;
}
.connection {
height: 40px;
align-self: center;
width: 70px;
color: red;
border: 1px solid red;
display: flex;
flex-direction: column;
justify-content: center;
}
<link href="http://maxcdn.bootstrapcdn.com/bootstrap/3.3.4/css/bootstrap.min.css" rel="stylesheet"/>
<div class="container-fluid">
<div class="roundtrip">
<div class="trip col-xs-12">Outbound
<div class="flight align-bottom"> <!--added the class 'align-bottom'-->
<div class="date-time col-xs-offset-2 col-xs-3">
<div class="flight-time">12:40</div>
<div class="flight-date">Friday 11 Sep</div>
</div>
<div class="col-xs-offset-0 col-xs-2">Los Angeles</div>
</div>
<div class="flight-path"></div>
<div class="flight">Chicago</div>
<div class="connection">5hr wait</div>
<div class="flight">Chicago</div>
<div class="flight-path"></div>
<div class="flight">New York</div>
<div class="connection">2hr wait</div>
<div class="flight">New York</div>
<div class="flight-path"></div>
<div class="flight">Amsterdam</div>
</div>
</div>
</div>
Check this out for more info about flexbox