I've recently been playing with Flexbox for the first time and, in general, it's absolutely amazing. I've encountered an issue recently however, where I cannot seem to give flex items that are wrapping any vertical spacing.
I've tried using:
align-content: space-between;
but this doesn't seem to do anything. From the reading I've done, this would only seem to work if my flex container is taller than the elements contained within (is this right?) If so, then would I not have to set a height for my flex-container, which would seem to defeat the purpose of using flexbox?
The only way I can think of to make this work would be to give bottom margin to the elements within, but again this seems to defeat the purpose.
Hopefully I'm missing something fairly obvious - here's a link to a codepen: http://codepen.io/lordchancellor/pen/pgMEPz
Also, here's my code:
HTML:
<div class="container">
<div class="col-sm-12">
<h1>Flexbox Wrapping</h1>
<div class="flexContainer">
<div class="flexLabel">This is a flex label</div>
<a class="btn btn-primary">Button 1</a>
<a class="btn btn-warning">Button 2</a>
<a class="btn btn-success">Button 3</a>
</div>
</div>
</div>
CSS:
.flexContainer {
display: flex;
flex-wrap: wrap;
align-items: center;
align-content: space-between;
justify-content: center;
}
.flexContainer .flexLabel {
flex-basis: 150px;
flex-shrink: 0;
}
EDIT - Just going to add a little more detail here, as I'm not sure I'm putting it across well enough.
In my larger project, I have some block level elements that are arranged in a row using flexbox. However, there needs to be some responsiveness as the user may reduce the screen width. At this point, I want my elements to begin to stack (hence the wrap). However, as the elements begin to stack, they are all touching vertically, where I want there to be spacing.
It's beginning to look like top and bottom margins may be the only way to resolve this - however I was wondering if there was a flexbox-centric way to achieve this.
I had a similar issue and I used the following hack to solve the issue.
/* add a negative top-margin to the flex container */
.flexContainer {
/* ... your existing flex container styles here */
margin: -10px 0 0 0;
}
/* add a corresponding positive top margin to all flex items (all direct children of the flex container) */
.flexContainer > * {
margin-top: 10px;
}
For the top row of flex items the negative and positive margins cancel out, for the subsequent rows it adds the margin between the rows (in this case 10px between rows).
It's less than elegant but it gets the job done.
If you force wrapping by applying a width you can then use margins as you normally would without setting a height.
.flexContainer {
display: flex;
align-items: center;
flex-wrap: wrap;
justify-content: center;
background: pink;
width: 150px;
}
.flexContainer > * {
margin: 1em 0;
}
.flexContainer .flexLabel {
flex-basis: 150px;
flex-shrink: 0;
}
<link href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.5/css/bootstrap.min.css" rel="stylesheet" />
<div class="container">
<div class="col-sm-12">
<h1>Flexbox Wrapping</h1>
<div class="flexContainer">
<div class="flexLabel">This is a flex label</div>
<a class="btn btn-primary">Button 1</a>
<a class="btn btn-warning">Button 2</a>
<a class="btn btn-success">Button 3</a>
</div>
</div>
</div>
row-gap would solve your problem
.flexbox {
display: flex;
column-gap: 10px;
row-gap: 10px
}
It's because you don't have a height on your flex content for it to calculate the space-between so at the moment, the flex container is as small as possible. Add a height and it should work.
Another hacky solution is to give the item a bottom border:
border-bottom: 10px solid transparent;
Related
I have a big html project due at work and I just have to add one final touch. I am trying to create a horizontal icon list on my page but have been running into issues. Here is a picture of EXACTLY what I need to create. please point me in the right direction or send over some code to try. Thanks
Here is a (very) basic implementation of how to use flexbox to create this three-column effect. Each individual cell will grow/shrink to equally fill the available width. Of course this needs some fine-tuning, but I hope it at least gives you a good starting point :)
.flex-container {
display: flex;
height: 100px;
width: 100%;
background-color: #00ff00;
justify-content: space-between; /* could also try with space-around */
}
.flex-child {
display: flex;
justify-content: center;
align-items: center;
flex-grow: 1;
background-color: #ff0000;
height: calc(100% - 20px); /* for demonstration purposes, subtracts top and bottom margin from height */
margin: 10px; /* for demonstration purposes */
}
<div class="flex-container">
<div class="flex-child">
Content here
</div>
<div class="flex-child">
Content here
</div>
<div class="flex-child">
Content here
</div>
</div>
What issues have you been running into?
It just a big flex container that contains 3 small flex containers.
In each small container, you will need 3 divs, the first div also flex, contain an icon and a text.
Basically, I'm trying to move my hamburger menu div to the right side of the page with Flexbox, but it refuses to budge. I've tried the flex-start/flex-end stuff, I've tried margin-right/left auto, but it doesn't seem to work.
The only thing that makes it work is if I put in a fix left margin, but when the screen size shrinks, it basically pushes the logo off the screen.
What's wrong with my code?
/*Parent Element*/
#nav-bar {
display: flex;
justify-content: space-between;
padding-top: 1rem;
}
/*Children*/
#logo {
flex: 2;
justify-self: flex-start;
max-width: 6em;
margin-right: auto;
}
#mobile-nav {
flex: 1;
justify-self: flex-end;
margin-left: auto;
}
<div id="nav-bar">
<div id="logo"><img src="./img/logo.png" alt=""> </div>
<div id="mobile-nav">
<div></div>
<div></div>
<div></div>
</div>
<ul id="main-nav">
<li>Item1</li>
<li>Item2</li>
<li>Item3</li>
<li>Item4</li>
<li>CTA</li>
</ul>
</div>
This is how I would do it.
#nav-bar{
display: flex;
flex-flow: row;
width: 100%;
justify-content: space-between;
}
#logo{}
#mobile-nav{}
Flex auto margins work by consuming free space in the direction of the margin. For example, margin-right: auto consumes all free space to the right of the element. This has the effect of pinning the element and siblings on its left all the way to the left, while pinning siblings to its right all the way to the right.
The problem in your code is that you have flex-grow (via the flex shorthand property). Well, flex-grow, like auto margins, works by consuming free space. Since flex-grow distributes all free space on the line, there is nothing auto margins can do (there is no free space available for them to use).
The justify-content property also works through distribution of free space, and will be useless when flex-grow is in play.
Solution: remove flex-grow.
Here's a more detailed explanation with illustrations:
In CSS Flexbox, why are there no "justify-items" and "justify-self" properties?
i have written a CSS margin for spacing between checkboxes. It works fine on chrome but not on Firefox.
here is CSS
.vehicle-types {
float:left;
width:100%;
margin: 6px 0;
.check-vehicle {
float:left;
width:100%;
.checkbox-btn {
width: auto;
display: inline-block;
margin-right: 20px;
float:left;
input {
float:left;
width:0 !important;
}
label {
margin:0 !important;
float:left;
}
}
}
}
is there any Firefox browser specific CSS?
(screenshots below)
Thanks in advance.
Chrome
Firefox
Okay, So I was writing this answer before you pushed your edited post. I am still to go through the code but as an alternate you can try this and see if it works or not
update: You have only shared css which is still very difficult to comprehend
An ideal solution to have everything on the same line would be to do.
.parent-div {
display: flex;
flex-direction: row;
justify-content: space-between
}
.child-div {
align-items: center;
display: flex;
flex-direction: row;
}
.create-box {
height: 30px;
width: 30px;
border: 1px solid black;
}
p {
margin-left: 5px;
}
<div class="parent-div">
<div class="child-div">
<span class="create-box"> </span>
<p> checkBox 1 </p>
</div>
<div class="child-div">
<span class="create-box"> </span>
<p> checkBox 1 </p>
</div>
<div class="child-div">
<span class="create-box"> </span>
<p> checkBox 1 </p>
</div>
</div>
In the above code I have used flex
flex-direction says that wether you want your divs to be stacked in row or columns i.e consider this somewhat equivalent to bootstrap class row . (if you have used bootstrap previously)
justify-content: space-between: space-between gives equal space between each square, but not between it and the container.
Note: You could have also used space-around
Space-around puts an equal cushion of space on either side of the square — which means the space between the outermost squares and the container is half as much as the space between two squares (each square contributing a non-overlapping equal amount of margin, thus doubling the space).
align-items: center; just align everything inside a div to centre across x-y axis
I found this article very useful when learning about flexboxes (might help you as well)
Look, the Firefox version adds that margin to the first child as well..
To avoid that, use:
.checkbox-btn:not(:first-child) {
...
margin-right: 20px;
...
}
I had this kind of problem also but with IE, for the next time you can use this code
it will only show on firefox, you can edit what you want and it will only show on firefox
#-moz-document url-prefix() {
//just write the code here
}
I know its not a problem from your code but if that was the case you could go to:
https://caniuse.com/
and check if it is your code
I think this gif explains it very well:
https://gfycat.com/FormalReasonableHagfish
Context: I'm working on a digital catalog (I didn't start the project) for a company that sells TONS of products, sometimes they are small, sometimes big, sometimes wide, etc. They go on a specific area, lets say 400px x 400px.
I did horizontal alignment with flexbox and it works very well but on the vertical axis the products have static values (prod_1 top: 0px, prod_2: top 10px, prod_3 top: 20px...)
EDIT: My question/need is: I want to be able to align (responsively in the horizontal and vertical axis) 1 to 6 images inside 1 div but flexbox only let me choose one axis (flex-direction row or column), what can I do?
The code is something like this:
<div class='container'>
<img class='item_0'>
<img class='item_1'>
<img class='item_2'>
<img class='item_3'>
<img class='item_4'>
</div>
If posible the solution should be in CSS, if it can't be done, then it could be in Javascript or maybe changing a little bit the HTML.
This is because I only have access to CSS and JS. The index.html is generated automatically from a database by an application developed/controlled by another team and it's not that easy/quick to ask them for changes.
The best way I thought is with javascript but it may not be that easy, considering it's a big project and there's A LOT of code already written (not by me).
What do you guys think? I don't need the complete solution but some direction would be really appreciated, thank you!
Ok, so I am not 100% sure about what you need, but here's some code I made that does pretty much what your gif showed. You should be able to tweak it to your liking.
https://codepen.io/AlexWulkan/pen/wmmPvL
HTML:
<div class="container">
<div class="row">
<div class="box"></div>
</div>
<div class="row">
<div class="box"></div>
</div>
<div class="row">
<div class="box"></div>
</div>
</div>
CSS:
/* Outer container */
.container {
display: flex;
flex-direction: column;
background-color: #eee;
height: 400px;
width: 400px;
}
/* Each row of boxes */
.row {
display: flex;
align-items: center;
flex: 1;
padding: 0 1rem;
}
/* determines the position of the boxes in each row */
.row:first-child {
justify-content: flex-end;
}
.row:nth-child(2) {
justify-content: center;
}
.row:last-child {
justify-content: flex-start;
}
/* Each box */
.box {
background-color: #666;
height: 100px;
width: 100px;
}
Tell me if there's anything you have questions about and I'll try to answer. The code should be quite self-explanatory though. :)
I'm trying to do a responsive design for a menu, you can see the code here.
As you can see flex works pretty well for that design. My only concern is that it won't be compatible with older browsers. Is there an easy way of implementing this without flex, I have tried having only divs inside a container here
The problem is I don't know how to make the My log box appear beside the New log box.
I want to keep responsiveness (boxes stacking up vertically in smaller screens).
Here is the code:
HTML:
<div class="block-menu vertical">
<div class="menu-item">My organizations</div>
<div class="block-menu horizontal">
<div class="block-menu vertical">
<div class="menu-item">
ITPs
</div>
<div class="menu-item">
My log
</div>
</div>
<div class="menu-item">
New log
</div>
</div>
<div class="menu-item">
Profile
</div>
</div>
</div>
CSS:
div.block-menu.horizontal {
display: flex;
width: 100%;
flex-wrap: wrap;
}
div.block-menu.horizontal > div {
flex-grow: 1;
}
div.block-menu.vertical {
display: flex;
flex-direction: column;
}
div.block-menu.vertical > div.menu-item {
width: auto;
}
.menu-container div.menu-item {
padding: 20px;
margin: 10px;
background-color: red;
flex-grow: 1;
}
If you add one extra div (like it is in the flex example), it is kind of simple playing with the values for float and width, you can see an example here: http://jsfiddle.net/ggb2ecu7/3/
Although that one doesn't take into account the margin that you have in the flex example. To fix that, you could use calc, like this: http://jsfiddle.net/ggb2ecu7/4/ (sorry about the extra unnecessary CSS rules). E.g.:
.w2 {
width: calc(100% - 20px);
}
[20px because the margin I set was 10px (on both sides = 20px)]
The problem with calc is that it may not work with all the older versions. You can check the support for calc in here: http://caniuse.com/#feat=calc