Nested column flexbox inside row flexbox with wrapping - css

I have a page with nested flex boxes here: http://jsfiddle.net/fr0/6dqLh30d/
<div class="flex-group">
<ul class="flex-container red">
<li class="flex-item">1</li>
<li class="flex-item">2</li>
<li class="flex-item">3</li>
</ul>
<ul class="flex-container gold">
<li class="flex-item">1</li>
<li class="flex-item">2</li>
<li class="flex-item">3</li>
<li class="flex-item">4</li>
<li class="flex-item">5</li>
</ul>
<ul class="flex-container blue">
<li class="flex-item">1</li>
<li class="flex-item">2</li>
<li class="flex-item">3</li>
<li class="flex-item">4</li>
<li class="flex-item">5</li>
<li class="flex-item">6</li>
<li class="flex-item">7</li>
<li class="flex-item">8</li>
</ul>
<div>
And the (relevant) CSS:
.flex-group {
display: flex;
flex-direction: row;
height: 500px;
}
.flex-container {
padding: 0;
margin: 0;
list-style: none;
border: 1px solid silver;
display: flex;
flex-direction: column;
flex-wrap: wrap;
flex: 0 0 auto;
}
.flex-item {
padding: 5px;
width: 100px;
height: 100px;
margin: 10px;
line-height: 100px;
color: white;
font-weight: bold;
font-size: 2em;
text-align: center;
}
The outer flexbox (.flex-group) is meant to lay out from left-to-right. The inner flexboxes (.flex-container) are meant to layout from top-to-bottom, and should wrap if there isn't enough space (which there isn't in my jsfiddle). What I want to happen, is that the .flex-containers will grow in the X direction when the wrapping happens. But that's not occurring. Instead, the containers are overflowing.
What I want it to look like (in Chrome): https://dl.dropboxusercontent.com/u/57880242/flex-good.png
Is there a way to get the .flex-containers to size appropriately in the X direction? I don't want to hard-code their widths, since the items that appear in these lists will be dynamic.

I've been playing with this for a few minutes now, and I think I've got what you're looking for.
Here's the CSS
.flex-group {
margin: auto;
display: flex;
flex-direction: row;
justify-content: space-around;
}
.flex-container {
flex: 0 1 auto;
display: flex;
flex-flow: row wrap;
align-items: space-around;
align-content: flex-start;
padding: 0;
margin: 0;
list-style: none;
border: 1px solid silver;
}
.red li {
background: red;
}
.gold li {
background: gold;
}
.blue li {
background: deepskyblue;
}
.flex-item {
flex: 0 1 auto;
padding: 5px;
width: 100px;
height: 100px;
margin: 10px;
line-height: 100px;
color: white;
font-weight: bold;
font-size: 2em;
text-align: center;
}
And here's an updated fiddle to see it in action.

Interesting, I also fiddle around with it. I have given the flex-container a flex:1 100%; This evenly space the containers to 100%; The blocks will flow in their own container space and the containers keep equal height and weight no matter how you size the window.
.flex-container {
flex: 0 100%;
display: flex;
flex-flow: row wrap;
align-items: space-around;
align-content: flex-start;
padding: 0;
margin: 0;
list-style: none;
border: 1px solid silver;
}
See fiddle here

Related

Stacking items with flexbox

In my header, I'm trying to put my name in the middle item below the first item "brush up". I've tried justify-content and align-items and just can't get it to move. I also want the navigation to stay on the right side. New to flexbox thank you for any help.
.container {
display: flex;
margin: 0 auto;
max-width: 960px;
flex-direction: column;
}
/* HEADER SECTION***************************************/
header {
width: 100%;
height: 8vh;
display: flex;
flex-direction: row;
outline: 1px solid red;
}
header * {
margin: 0;
padding: 0;
display: block;
}
header h1 {
outline: 1px solid red;
height: 50px;
flex: 3;
}
header p {
flex: 2;
outline: 1px solid red;
height: 25px;
align-items: baseline;
}
header ul {
flex: 1;
justify-content: flex-end;
outline: 1px solid red;
list-style-type: none;
}
header ul li {
margin: 0 0.5em;
}
<header>
<h1>Brushing up</h1>
<p>by Keller Johnson</p>
<ul>
<li>home</li>
<li>project 1</li>
<li>project 2</li>
</ul>
</header>
Are you looking for this?
header {
width: 100%;
display: flex;
}
header, header > * {
outline: 1px solid red;
}
header > div {
flex-grow: 1;
}
header > ul {
flex: 0 0 200px;
display: flex;
flex-direction: column;
justify-content: space-evenly;
list-style-type: none;
}
header * {
margin: 0;
padding: 0;
}
header h1 {
height: 50px;
}
header p {
outline: 1px solid red;
height: 25px;
}
header ul li {
margin: 0 0.5em;
}
<header>
<div>
<h1>Brushing up</h1>
<p>by Keller Johnson</p>
</div>
<ul>
<li>home</li>
<li>project 1</li>
<li>project 2</li>
</ul>
</header>
If this is not the result you want, consider explaining more clearly exactly what you're trying to achieve. Since we're talking about styling, a picture would help.

Flex relative to outer div (position will not help)

What I want to do is align .prod (products) all next to each other as if they were actually in the .subcontainer.
I can't use position since the 8th prod will not sit next to the 9th prod and so on. I could write some JS to do this however I'm trying to use pure css/sass. I have a feeling it's not possible, therefore stackoverflow amaze me with your work arounds.
Codepen: https://codepen.io/shaggywolfhound/pen/vYpMaPx
HTML:
<div class="container">
<div class="subcontainer">
<ol class="prod-cont">
<li class="prod"></li>
<li class="prod"></li>
<li class="prod"></li>
<li class="prod"></li>
<li class="prod"></li>
<li class="prod"></li>
<li class="prod"></li>
</ol>
<ol class="prod-cont">
<li class="prod"></li>
<li class="prod"></li>
.....
SASS:
.container {
width: 200px;
height: 2000px;
.subcontainer {
border: 1px solid red;
.prod-cont {
display: flex;
flex-wrap: wrap;
.prod {
margin: 2px;
display: inline-block;
border: 1px solid green;
box-sizing: border-box;
width: 45px;
height: 100px;
}
}
}
}
just add display: flex on .subcontainer and padding-left: 0 on .prod-cont.
Your code should look like this:
.container {
width: 200px;
height: 2000px;
.subcontainer {
display: flex;
border: 1px solid red;
.prod-cont {
display: flex;
flex-wrap: wrap;
padding-left: 0;
.prod {
margin: 2px;
display: inline-block;
border: 1px solid green;
box-sizing: border-box;
width: 45px;
height: 100px;
}
}
}
}

how to create even spacing in navbar

I was wondering how I could create even spacing in my navbar. I want to have even spacing between the "History, Etymology, and About." I also want that part to stay on the right, while the Shiba Inu stays on the left. I have attached a picture of what I have currently and also a picture of what I would like.
Thank you!
What I want
What I have
.navbar{
font-size: 13pt;
padding-bottom: 10px;
display: flex;
justify-content: space-between;
padding-bottom: 0;
height: 70px;
align-items: center;
position: fixed;
}
.main-nav{
list-style-type: none;
display: flex;
margin-right: 30px;
flex-direction: row;
justify-content: flex-end;
}
.home,
.nav-links{
text-decoration: none;
color:#212020;
}
.main-nav li{
display: flex;
flex-flow: row wrap;
margin: 0;
justify-content: space-between;
font-size: 13pt;
}
.home{
display: inline-block;
font-size: 22px;
margin-left: 10px;
}
<nav class="navbar">
SHIBA INU
<ul class="main-nav">
<li>
<a href="index.html" class="nav-links" >ABOUT</a>
</li>
<li>
<a href="#" class="nav-links" >ETYMOLOGY</a>
</li>
<li>
<a href="#" class="nav-links" >HISTORY</a>
</li>
</ul>
</nav>
In summary:
Make sure your flex parent or flex container have a width
defined of the parent in this case 100% means the full window as
there is no other parent here.
On the other hand the space between elements of the list can be done
with multiple approaches but I think a margin that excludes the last
one should work for your use case.
.navbar{
font-size: 13pt;
padding-bottom: 10px;
display: flex;
justify-content: space-between;
padding-bottom: 0;
height: 70px;
align-items: center;
position: fixed;
width: 100%;
}
.main-nav{
list-style-type: none;
display: flex;
margin-right: 30px;
flex-direction: row;
justify-content: flex-end;
flex-grow: 1;
align-items: justify-content;
}
.home,
.nav-links{
text-decoration: none;
color:#212020;
}
.main-nav li{
display: flex;
flex-flow: row wrap;
margin: 0;
justify-content: space-between;
font-size: 13pt;
}
.main-nav li:not(:last-child) {
margin-right: 10px;
}
.home{
display: inline-block;
font-size: 22px;
margin-left: 10px;
}
<nav class="navbar">
SHIBA INU
<ul class="main-nav">
<li>
<a href="index.html" class="nav-links" >ABOUT</a>
</li>
<li>
<a href="#" class="nav-links" >ETYMOLOGY</a>
</li>
<li>
<a href="#" class="nav-links" >HISTORY</a>
</li>
</ul>
</nav>

Center div using Flexbox

I am trying to center the outer 'div' container using Flexbox. I have an unordered list with 3 li's. The li's width is: width: calc(100%/3). The ul's width is 70%. The problem is that when I try centering the ul (justify-content: center), it doesn't get centered.
I finally figured out the source of the problem. When I remove the line: width: calc(100%/3), it centers properly. My question is: How can I get it to center properly?
I tried margin: auto, but that didn't work.
Here's the JSFiddle, and here's the code snippet:
#flex-container {
width: 70%;
list-style-type: none;
padding: 0;
margin: 0;
display: -webkit-inline-flex;
display: inline-flex;
-webkit-justify-content: center;
justify-content: center;
}
li {
box-sizing: border-box;
background-color: tomato;
width: calc(100%/3);
}
<ul id="flex-container">
<li class="flex-item">First</li>
<li class="flex-item">Second</li>
<li class="flex-item">Third</li>
</ul>
When I remove the line: width: calc(100%/3), it centers properly
You should not calculate the width when you are using flex layout, because that is what flex is itself supposed to do.
If you are looking to align the text inside of the lis then text-align is what you need. You should also remove the width from the lis and use the flex property instead.
Snippet:
* { box-sizing: border-box; padding: 0; margin: 0; }
#flex-container {
list-style-type: none;
width: 70%; display: flex;
}
li {
flex: 1 1 auto;
background-color: tomato; border: 1px solid #fff;
text-align: center;
}
<ul id="flex-container">
<li class="flex-item">First</li>
<li class="flex-item">Second</li>
<li class="flex-item">Third</li>
</ul>
If you are looking to have variable width lis then justify-content is what you need. You should control the width via the width property and use flex property as required to expand or shrink.
Snippet:
* { box-sizing: border-box; padding: 0; margin: 0; }
#flex-container {
list-style-type: none; width: 70%;
display: flex; justify-content: center;
background-color: #eee;
}
li {
flex: 0 0 auto; width: 15%;
background-color: tomato; border: 1px solid #fff;
}
li:first-child { width: 20%; }
li:last-child { width: 30%; }
<ul id="flex-container">
<li class="flex-item">First</li>
<li class="flex-item">Second</li>
<li class="flex-item">Third</li>
</ul>
I modified your code:
http://jsfiddle.net/hrr65ajr/2/
#flex-container {
width: 70%;
list-style-type: none;
padding: 0;
margin: 0;
display: -webkit-inline-flex;
display: inline-flex;
-webkit-justify-content: center;
justify-content: center;
}
li {
box-sizing: border-box;
background-color: tomato;
margin: auto;
width: calc(100%/3);
text-align: center;
}
<ul id="flex-container">
<li class="flex-item">First</li>
<li class="flex-item">Second</li>
<li class="flex-item">Third</li>
</ul>
Try this:
HTML
<div class="center">
<ul id="flex-container">
<li class="flex-item">First</li>
<li class="flex-item">Second</li>
<li class="flex-item">Third</li>
</ul>
</div>
CSS
.center {
display:flex;
-webkit-justify-content: center;
justify-content: center;
}
#flex-container {
width: 70%;
list-style-type: none;
padding: 0;
margin: auto 0;
display: -webkit-inline-flex;
display: inline-flex;
-webkit-justify-content: center;
justify-content: center;
}
li {
box-sizing: border-box;
background-color: tomato;
width: calc(100%/3);
}

Flexbox children does not respect height of parent with flex-direction column

The general idea is to have 2 rows of equal heights and the first row contain 2 columns of equal width for a full page layout. The problem I'm running into is that when one of the cells fill up with children elements, the parent row's height expands overtaking the sibling row when the heights should be equal.
body {
min-height: 100vh;
height: auto;
display: flex;
flex-direction: column;
}
.content {
flex: 1;
display: flex;
flex-direction: column;
}
.row {
border: dashed 1px;
flex: 1;
}
.row1 {
display: flex;
}
.cell {
flex: 1;
padding: 8px;
border: dashed 1px black;
margin: 4px;
display: flex;
flex-direction: column;
}
.title {
border: solid 1px;
padding: 8px;
font-size: 24px;
}
.things {
flex: 1;
margin: 8px 0 0;
padding: 0;
overflow-y: scroll;
}
.things li {
list-style-type: none;
padding: 4px;
border: solid 1px;
margin: 8px 8px 8px;
}
<div class="content">
<div class="row row1">
<div class="cell">
<div class="title">Cell 1</div>
<ul class="things">
<li>thing 1</li>
<li>thing 2</li>
<li>thing 3</li>
<li>thing 4</li>
<li>thign 5</li>
<li>thing 1</li>
<li>thing 2</li>
<li>thing 3</li>
<li>thing 4</li>
<li>thign 5</li>
</ul>
</div>
<div class="cell">
<div class="title">Cell 2</div>
</div>
</div>
<div class="row row2">Row 2</div>
</div>
Since flex is a shorthand property, flex: 1 means
flex-grow: 1;
flex-shrink: 1;
flex-basis: 0%;
But for some reason, the 0% seems to confuse Chrome. So add flex-basis: 0 manually:
.row { flex-basis: 0; }
And since Firefox implements the new auto as the initial value of min-height, it needs
.row { min-height: 0; }
So the final code is
.row {
flex: 1;
flex-basis: 0;
min-height: 0;
}
/* Styles go here */
body {
min-height: 100vh;
height: auto;
display: flex;
flex-direction: column;
}
header {
background: #000;
color: #fff;
display: flex;
justify-content: space-between;
}
a {
color: #fff;
padding: 4px;
text-decoration: none;
}
a:hover {
background: #fff;
color: #000;
}
.content {
flex: 1;
display: flex;
flex-direction: column;
}
.row {
border: dashed 1px;
flex: 1;
flex-basis: 0;
min-height: 0;
}
.row1 {
display: flex;
}
.cell {
flex: 1;
padding: 8px;
border: dashed 1px black;
margin: 4px;
display: flex;
flex-direction: column;
}
.title {
border: solid 1px;
padding: 8px;
font-size: 24px;
}
.things {
flex: 1;
margin: 8px 0 0;
padding: 0;
overflow-y: scroll;
}
.things li {
list-style-type: none;
padding: 4px;
border: solid 1px;
margin: 8px 8px 8px;
}
<header>
Home
Acct
</header>
<div class="content">
<div class="row row1">
<div class="cell">
<div class="title">Cell 1</div>
<ul class="things">
<li>thing 1</li>
<li>thing 2</li>
<li>thing 3</li>
<li>thing 4</li>
<li>thign 5</li>
</ul>
</div>
<div class="cell">
<div class="title">Cell 2</div>
</div>
</div>
<div class="row row2">Row 2</div>
</div>

Resources