Little Grid with Flexbox - css

I try to create this little gallery grid with flexbox, but I fail all time.
Is it possible with flexbox?
Here is my example and fiddle.
<div class="gallery">
<div class="box one">Box 1</div>
<div class="box two">Box 2</div>
<div class="box three">Box 3</div>
<div class="box four">Box 4</div>
<div class="box five">Box 5</div>
</div>
.gallery {
display:flex;
display: -webkit-flex;
-webkit-flex-wrap: wrap;
flex-wrap: wrap;}
.gallery .box {
background:#ccc;
height:250px;
width:33.33333%;}
.gallery .box.one,
.gallery .box.two {
-webkit-flex:1;
flex: 1;}
.gallery .box.three {
height:500px;}
.gallery .box.four,
.gallery .box.five {
-webkit-flex:1;
flex: 1;}

Ok, so have you tried using flex-direction: column? It requires a slight change in the way you think about flexbox. Try the following:
.gallery {
display: flex;
flex-direction: column;
flex-wrap: wrap;
max-height: 200px; // or however you want to do it, required for wrapping
}
.box {
height: 100px;
}
.three {
height: 200px;
}

You can try something like this:
create 3 parent divs .
create two child divs in each 1st and 3rd div with width 100% and height 50%
and flex-direction column.
#grid{
width:100%;
height:500px;
background:#eee;
display:flex;
}
#p1,#p2,#p3{
width:33%;
border:2px solid #fff;
display:flex;
flex-direction:column;
}
#pone,#ptwo,#p31,#p32{
flex-basis:100%;
height:50%;
border:3px solid white;
}
<div id="grid">
<div id="p1">
<div id="pone">
</div>
<div id="ptwo">
</div>
</div>
<div id="p2">
</div>
<div id="p3">
<div id="p31">
</div>
<div id="p32">
</div>
</div>
</div>

Related

Nested Flexbox - outer container doesn't flex

Update : I have edited the snippet to show better what I'm trying to achieve...
I have a number of tables of data, each of variable length, on a kiosk display. I want to fill the viewport as columns then overflow to pages below ie paging down would give me next screen of data. I thought Nested Flexbox would allow me to do this but the outer Container doesn't do what I hoped and data just flows to right - see below. Am I just inept or should I be doing it another way? Thx!
.container1 {
background: lightgrey;
display: flex;
width:300px;
flex-direction: column;
flex-wrap:wrap;
}
.container2 {
background: orangered;
display: flex;
flex-direction: column;
height:200px;
width: 300px;
flex-wrap: wrap;
}
.container2 > div{
font-size: 40px;
width: 100px;
}
.green {
background: yellowgreen;
}
.blue {
background: steelblue;
}
My effort doesn't work ...
<div class="container1">
<div class="container2">
<div class="green">1a<br>1b<br>1c</div>
<div class="blue">2a<br></div>
<div class="green">3a<br>3b</div>
<div class="blue">4a<br>4b<br>4c</div>
<div class="green">5a<br>5b</div>
<div class="blue">6a<br></div>
<div class="green">7a<br>7b</div>
<div class="blue">8a<br>8b<br>8c</div>
<div class="green">9a<br>9b<br>9c</div>
<div class="blue">10a<br></div>
<div class="green">11a<br>11b</div>
<div class="blue">12a<br>12b<br>12c</div>
</div>
</div>
I want output like this but ...
<div class="container2">
<div class="green">1a<br>1b<br>1c</div>
<div class="blue">2a<br></div>
<div class="green">3a<br>3b</div>
<div class="blue">4a<br>4b<br>4c</div>
</div>
<div class="container2">
<div class="green">5a<br>5b</div>
<div class="blue">6a<br></div>
<div class="green">7a<br>7b</div>
<div class="blue">8a<br>8b<br>8c</div>
</div>
<div class="container2">
<div class="green">9a<br>9b<br>9c</div>
<div class="blue">10a<br>10a<br></div>
<div class="green">11a<br>11b</div>
<div class="blue">12a<br>12b<br>12c</div>
</div>
You don't want to use flex-direction: column on the inner container2. You still want that to be row.
Setting flex-direction: column only establishes that the direction of children should flow from top to bottom (or reverse with column-reverse).
Setting flex-wrap: wrap on a parent with flex-direction: column wraps the elements on the cross axis (row in this case).
You don't even need the outer parent container, since there was only one flex child container2.
.container2 {
background: orangered;
display: flex;
flex-direction: row;
flex-wrap: wrap;
width: 300px;
height: 200px;
overflow: scroll;
}
.container2 > div {
font-size: 40px;
flex: 0 0 33.33333%;
min-height: 200px;
}
.green {
background: yellowgreen;
}
.blue {
background: steelblue;
}
<div class="container2">
<div class="green">1a<br>1b<br>1c</div>
<div class="blue">2a<br></div>
<div class="green">3a<br>3b</div>
<div class="blue">4a<br>4b<br>4c</div>
<div class="green">1a<br>1b<br>1c</div>
<div class="blue">2a<br></div>
<div class="green">3a<br>3b</div>
<div class="blue">4a<br>4b<br>4c</div>
<div class="green">1a<br>1b<br>1c</div>
<div class="blue">2a<br></div>
<div class="green">3a<br>3b</div>
<div class="blue">4a<br>4b<br>4c</div>
</div>

CSS Display: Flex on Desktop and Mobile

I'm newer to using FLEXBOX and have a question on a layout using Desktop and Mobile.
I'm displaying info using a label and data (not on a form).
On the desktop, I'd like it to display like this:
label-------label-------label------label
Data--------Data--------Data-------Data
On a desktop, label and data will be a % based on number of elements.
But, on a mobile, I'd like it to display like this:
label------
Data-------
Label------
Data-------
label------
data-------
Label------
Data-------
label------
data-------
On mobile, I'd like label and data to be 25% & 75% wide.
Not sure on the HTML if it should be laid out like this
<div class="container">
<div class="label">Label</div>
<div class="data">Data</a>
<div class="label">Label</div>
<div class="data">Data</a>
<div class="label">Label</div>
<div class="data">Data</a>
</div>
OR
<div class="container">
<div class="label">label</div>
<div class="label">label</div>
<div class="label">label</div>
</div>
<div class="container">
<div class="data">data</div>
<div class="data">data</div>
<div class="data">data</div>
</div>
Any guidance would be great!
Thanks!
It sounds like you're flexible on the HTML structure.
I recommend grouping data pairs with parent elements, making columns and rows.
With two nested flexboxes, you can change flex-direction as desired.
/* FOR DEMO PURPOSES */
var $body = $('body');
$('button').on('click', function() {
$body.toggleClass('small');
});
.container {
display: flex;
flex-wrap: wrap;
background-color: lightgreen;
}
.group {
display: flex;
flex-direction: column;
}
.item {
padding: .25em .5em;
}
#media (min-width: 700px) {
.container {
background-color: lightblue;
flex-direction: column;
}
.group {
flex-direction: row;
}
}
/* FOR DEMO PURPOSES */
.small .container {
background-color: lightblue;
flex-direction: column;
}
.small .group {
flex-direction: row;
}
button {
position: absolute;
top: 100px;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div class="container">
<div class="group">
<div class="item label">Label 1</div>
<div class="item data">Data 1</div>
</div>
<div class="group">
<div class="item label">Label 2</div>
<div class="item data">Data 2</div>
</div>
<div class="group">
<div class="item label">Label 3</div>
<div class="item data">Data 3</div>
</div>
</div>
<button>Simulate Size Change</button>
Here's a demo with more than one row of data:
/* FOR DEMO PURPOSES */
var $body = $('body');
$('button').on('click', function() {
$body.toggleClass('small');
});
.container {
display: flex;
flex-wrap: wrap;
background-color: lightgreen;
}
.group {
display: flex;
flex-direction: column;
}
.item {
padding: .25em .5em;
}
.label {
font-weight:bold;
}
.flag {
color:red;
}
#media (min-width: 700px) {
.container {
background-color: lightblue;
flex-direction: column;
}
.group {
flex-direction: row;
}
}
/* FOR DEMO PURPOSES */
.small .container {
background-color: lightblue;
flex-direction: column;
}
.small .group {
flex-direction: row;
}
button {
position: absolute;
top: 130px;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div class="container">
<div class="group">
<div class="item label">Label 1</div>
<div class="item data">Data 1a</div>
<div class="item data flag">Data 1b</div>
<div class="item data">Data 1c</div>
</div>
<div class="group">
<div class="item label">Label 2</div>
<div class="item data">Data 2a</div>
</div>
<div class="group">
<div class="item label">Label 3</div>
<div class="item data">Data 3a</div>
<div class="item data">Data 3b</div>
</div>
</div>
<button>Simulate Size Change</button>
For more ideas, I highly recommend reading Accessible, Simple, Responsive Tables # CSS-Tricks and checking out the other resources listed there.
I would order them like the first option. Then, at desktop view I'd make a flex flow of column wrap, set a height for the container and set each flex-item to be 50% height.
On mobile, id switch to flex-flow: row wrap, and define the container's width, then each child at 25%/75% depends on which child.
HTML:
<div class="container">
<div class="label">Label</div>
<div class="data">Data</a>
<div class="label">Label</div>
<div class="data">Data</a>
<div class="label">Label</div>
<div class="data">Data</a>
</div>
CSS:
.container {
display: flex;
flex-flow: row wrap;
justify-content: space-evenly;
align-items: center;
height: 500px; // what ever you want here
}
.label, .data {
height: 45% // Less than 50% for margins, etc.
}
#media only screen and (max-width: 900px) { //Set desired width to call 'mobile'
.container {
flex-flow: row wrap;
width: unset;
height: 500px; //Whatever you want again
}
.data {
width: 70%;
}
.label {
width: 22%;
}
}

A centered column without fixed width

I would like to create a page with a centred column, in which the individual items do not have a fixed width (see image).
I've tried using flexbox, but that seems to want to fill out the blocks over the entire box. I've also tried to use the normal margin: 0 auto approach, but that doesn't work if you don't have a fixed width.
Is there a way to do this? I prefer pure CSS of course.
Here's an example using a flexbox. No width settings anywhere.
.container {
display: flex;
flex-direction: column;
align-items: center;
}
.element {
background-color: lightblue;
border: thin solid blue;
}
span:not(first-child) {
margin-left: 1rem;
border: thin solid red;
}
<div class="container">
<div class="element">This is text</div>
<div class="element">This is also some text</div>
<div class="element">
<span>And even in different</span>
<span>boxes on the same row</span>
</div>
</div>
Here is an example, hope it will help ^^ :
.parent {
display:flex;
flex-direction:column;
justify-content:center;
align-items:center;
}
.child {
margin-bottom:20px;
min-width:200px;
min-height:80px;
background-color:#555;
}
.child-fluid {
min-width:100%;
display:flex;
padding:5px;
}
.content {
min-height:80px;
background-color:#AAA;
flex:1;
margin:5px;
}
<!DOCTYPE html>
<html>
<head>
<title>Page Title</title>
</head>
<body>
<div class="parent">
<div class="child"></div>
<div class="child"></div>
<div class="child" style="min-width: 350px;"></div>
<div class="child child-fluid">
<div class="content"></div>
<div class="content"></div>
</div>
<div class="child"></div>
</div>
</body>
</html>
with flex box you have to have a width set on the parent. It doesn't have to be a fixed width though you could do something like
.parent{
display: flex;
flex-direction: column;
justify-content: center;
align-items: center;
width: 100%;
}
that might work.

How to make one element fill to the bottom of its container in Bootstrap 3?

I have a container element which has two elements:
A which is col-md-8
B which is col-md-4
C which is col-md-4
Now A is longer so it extends the container element.
I would like C to fill in the rest of the space such that height of A = height of B + height of C (including the margins).
How would I do this in bootstrap?
Try using CSS Flexbox. It will be to tidy to achieve this using bootstrap classes.
Have a look at the snippet below:
.section {
display: flex;
font-size: 30px;
color: #fff;
}
.sec-item {
flex: 1;
}
.left-section {
background: blue;
height: 100vh;
flex: 8;
}
.right-section {
display: flex;
flex-direction: column;
flex: 4;
}
.right-section .top {
background: red;
flex: 1;
}
.right-section .bottom {
background: green;
flex: 1;
}
<div class="section">
<div class="sec-item left-section">A</div>
<div class="sec-item right-section">
<div class="top">B</div>
<div class="bottom">C</div>
</div>
</div>
Hope this helps!
Try something like this. It uses Flex-property
*{
box-sizing:border-box;
}
.row{
display:flex;
flex-direction:row;
}
#leftDiv{
height:400px;
border:2px solid black;
}
#rightDiv{
border:2px solid black;
display:flex;
flex-direction:column;
}
.redOne{
background-color:red;
height:100px;
flex-shrink:0;
}
.greenOne{
background-color:green;
flex-shrink:0;
flex-grow:1;
}
<link href="https://cdnjs.cloudflare.com/ajax/libs/twitter-bootstrap/3.3.7/css/bootstrap.min.css" rel="stylesheet"/>
<div class="container">
<div class="row">
<div class="col-md-6 col-sm-6 col-xs-6" id="leftDiv">
</div>
<div class="col-md-6 col-sm-6 col-xs-6" id="rightDiv">
<div class="redOne"></div>
<div class="greenOne"></div>
</div>
</div>

Switch one sandwich column and two columns in responsive

I tried switching one sandwich column and two columns by using flex. However, I could not do it without using two div tags and display: none;
Could you please give me any advice?
One column image
Two columns image
HTML
<div class="container">
<div class="category1">
<div class="timezone1">timezone1</div>
<div class="menu1">menu1</div>
<div class="timezone2">timezone2</div>
<div class="menu2">menu2</div>
<div class="timezone3">timezone3</div>
<div class="menu3">menu3</div>
</div>
</div>
<div class="pc-container">
<div class="pc-category1">
<div class="pc-timezone1">timezone1</div>
<div class="pc-timezone2">timezone2</div>
<div class="pc-timezone3">timezone3</div>
</div>
<div class="pc-category2">
<div class="pc-menu1">menu1</div>
<div class="pc-menu2">menu2</div>
<div class="pc-menu3">menu3</div>
</div>
</div>
CSS
.container {
display: flex;
flex-flow: column wrap;
}
.pc-container {
display: none;
}
#media screen and (min-width: 768px){
.container {
display: none;
}
.pc-container {
display: flex;
flex-flow: row wrap;
}
}
These images are added July 28.
Initial screen
Narrow to show smartphone screen
Re-large to show PC screen, but each column is not side by side.
Just switch from columns to wrapping rows....
.category1 {
display: inline-flex;
border: 1px solid grey;
padding: .5em;
flex-direction: column;
}
#media screen and (min-width: 500px) {
.category1 {
flex-direction: row;
flex-wrap: wrap;
}
.category1 > div {
white-space: nowrap;
flex: 0 1 50%;
}
.category1 > [class^="menu"] {
text-align: right;
}
}
<div class="container">
<div class="category1">
<div class="timezone1">timezone1</div>
<div class="menu1">menu1</div>
<div class="timezone2">timezone2</div>
<div class="menu2">menu2</div>
<div class="timezone3">timezone3</div>
<div class="menu3">menu3</div>
</div>
</div>
Codepen Demo
Here's another option: http://codepen.io/panchroma/pen/LkALXG/
HTML
<div class="container">
<div class="timezone">timezone1</div>
<div class="menu">menu1</div>
<div class="timezone">timezone2</div>
<div class="menu">menu2</div>
<div class="timezone">timezone3</div>
<div class="menu">menu3</div>
</div>
CSS
.timezone,
.menu{
width:50vw;
display:inline-block;
}
.menu{
float:right;
}
#media screen and (max-width: 767px){
.menu,
.timezone{
float:none;
display:block;
width:auto;
}
}
Good luck!

Resources