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?
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.
I need an image in nested flex containers to have width 100%, but this doesn´t work in IE11 when the container has flex-direction: column. I tried:
img {
width: 100%;
max-width: calc( 100% - 0.1px );
}
but this also doesn't work. Any ideas?
section, .articles-wrapper, .article-wrapper {
display: flex;
}
.article-wrapper {
flex-direction: column;
}
img {
width: 100%;
}
html:
<section>
<div class="articles-wrapper">
<div class="article-wrapper">
<img src="http://via.placeholder.com/600x150">
</div>
</div>
</section>
Have you inspected the page to see how the elements are laid out?
The image actually is taking up 100% of it's parent's width, because by default flex-items are not allowed to grow to fill the flex container but expand only enough to display their content.
Both the .articles-wrapper and .article-wrapper elements need to be explicitly allowed to grow, either by specifying flex-grow: 1; or using the shorthand property flex with one of several values:
.articles-wrapper, .article-wrapper {
flex: auto; /* shorthand for flex: 1 1 auto; */
}
OR
.articles-wrapper, .article-wrapper {
flex: 1; /* shorthand for flex: 1 1 0%; */
}
As you get deeper into using flexbox, I recommend keeping Philip Walton's Flexbugs repo at hand which lists common bugs for all browsers as well as workarounds for each.
EDIT Michiel: flex: 1 works in IE11, except that the aspect ratio is not maintained when the window is scaled to a smaller size than the image size. This 'feature' is documented in Flexbugs #5, and can be solved by adding a non-flex wrapper:
<section>
<div class="articles-wrapper">
<div class="article-wrapper">
<div> <!-- ADDED NON-FLEX WRAPPER -->
<img src="http://via.placeholder.com/600x150">
</div>
</div>
</div>
</section>
Consider this HTML:
<div class="flexbox-container">
<div class="flexbox-item">
Some text.
</div>
<div class="flexbox-item">
Some quite longer, longer, longer text.
</div>
<div class="flexbox-item">
Some other text.
</div>
</div>
and this CSS:
.flexbox-container {
display: flex;
flex-flow: row wrap;
justify-content: space-between;
align-items: center;
}
How can I tell the flexbox container to give all of its children a 100% width unless all of them fit in the same line, effectively occupying 33.33% each?
Tried this:
.flexbox-item {
min-width: 33%;
flex-grow: 1;
}
But it's not exactly what I'm looking for, since as soon as 2 items fit in a line, the third one will be wrapped.
Edit- Some more info: The expected behaviour of these divs is for them to occupy 100% width on mobile, and then as soon as they all fit in the same line, to have justify-content: space-between work its magic. Space-between is required. I can do this in a more specific way with breakpoints but would like to go flexbox all the way.
Pen here
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;
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