Understanding Flex 3 Column Better

You can make a gap without a margin by specifying justify-content:space-between on the container.

e.g.

.content{justify-content:space-between;}
.main-sidebar{margin-left:0;}
.flex-main {order:1;}
.main-sidebar{order:2;}

If you change the order it will still keep the gap between columns.

1 Like

that means →

100 - (69 + 28) = 3% will be the space between. {Reminaing of the %age width of the two elements}

1 Like

Yes, that’s correct.:slight_smile:

1 Like

I think even if we have dedicated 33% to a nested flex item, for example, but if the other item is not available then the item in discussion takes 100%, but see here → click here even if you delete this part →

<aside class="main-sidebar col">
the main content doesn’t takes full width. whats wrong?

That’s because you have a width on flex-main.

If you remove the width from .flex-main and instead use flex:1 0 68.8% then the element will spread to fill the space (with or without side column) but then you lose your gap between the columns.

I’m not sure that you have a gap between columns and then swap or remove columns. I can’t see a way around it at the minute but it might be because its getting late here:)

1 Like

Hello sir, Have you come back.

Yes, I had another look and I think we are stuck on this point. The only way I could see of doing this was if the sidebar came immediately before flex-main in the html and then you could style the width of flex-main based on the side-bar being present.

e.g.
.main-sidebar + .flex-main{width:68.8%}
.flex-main{width:100%}

That would also assume that you are removing the html for the sidebar rather than just setting it to display:none. Of course that makes the rules html dependent which unless you are sure will not change could cause problems if you later insert other items between those two containers.

It looks to me as though you will have to add a new class to flex-main when you hide the sidebar so that you can reset its width to 100%.

The problem is the fact that you want to swap columns left and right etc which means margins cannot automatically used. The only method I can see it the space-between rule but that needs the items to have widths.

Maybe someone with fresh eyes can have a look as I may be missing the obvious?

1 Like

In all honesty, if I required two alternative layouts for a site, I would just use two alternative html templates and be done with it.
But if you were adamant on using a single template, if you are swapping the bar’s side via the order property, you are somehow altering css, so why not alter the margin property at the same time?
I’m not sure what means you are using to make this change, but one way could be to use the old trick of applying a class to the body, server-side, then set some css for the elements in question beneath that.
Eg.

<body class="bar-left">
<!-- OR -->
<body class="bar-right">

with

.bar-left .main-sidebar {
   order: 1;
   margin: 0 10px 0 0;
}
.bar-right .main-sidebar {
   order: 2;
   margin: 0 0 0 10px;
}
2 Likes

I can fix this with php logic. Like If the full width is chosen then print width: 100% else 68.8%. But may be there is some fix as you have said let’s wait for someone else to come in.

1 Like

Actually, I am not adamant, and I am a novice and started learning like 80n days back. In PHP I only know this much → https://laracasts.com/series/php-for-beginners

Let us assume that we want to break it in 3 HTML templates.

  1. sidebar in left hand-side
  2. sidebar in right-handside
  3. No Sidebar

In the first two, the difference will just of an order (If we are using flex as is the case now) and the entire code will be repeated. In the 3rd one the difference of just of one extra class or some minor CSS, and the entire HTML is repeated.

In WordPress creating so much unnecessary HTML is considered as a novice and poor practice, and author of such themes are looked up as incompetent and novice.

I am a beginner I can easily get away by creating 3 templates, but I am taking up the challenge so that after 9 months or 1 Year I could be a great, competitive and a reliable Wordpress developer.

I have replicated the issue in a codepen, and looks like this is the solution →

.flex-main:only-child { flex: 1; }

Try removing this →

    <aside class="main-sidebar col">
      
    </aside>
2 Likes

Yes, good idea that should work as long as you only have the sidebar and main section within the content wrap.:slight_smile:

1 Like

I tested in your Codepen to create the gap with equal margins on the sidebar and main and then expanding the flex container with the same value in order to soak up the side gaps:

body {
    margin: 1em auto 0;
    border: solid;
    width: 90%;
}
.content {
    display: flex;
    margin: 0 -10px;
    height: 90vh;
}
.flex-main {
    margin: 0 10px;
    flex: 1;
    order: 2;
    background: cyan;
}
.main-sidebar {    /*
    display: none; /* */
    margin: 0 10px;
    width: 29%;
    order: 1;
    background: yellow;
}

I think this approach could work in a live site too so I tossed together an example with different columns to play with:
Flex-Gaps.html (1.6 KB)

1 Like

This looks like something very great, but I could not understand the logic what is actually going on. Can you please elaborate the logic you have tested. Thanks.


I have created a new pen with the nesting as suggested by @SamA74, but I am facing some challenges.

Code Pen is Here.

I think the margin is external, and it takes extra space, but the padding is internal and it doesn’t take extra space, Right? or Perhaps I may be wrong.

In order to align the text to look great, I used this →

.top, .article, .secondary {
paddding: 10 px;
}

Try to put the above in the codepen.

But then it breaks the design because it seem to take the extra space apart from the %ages that we have set for .article or .secondary

Yes that would work also but the only problem I see is that the margins extend the container and you would have to be careful that there is always 10px space at the side of the layout to soak up these margins without creating a scrollbar. Care would need to be taken especially for smaller devices otherwise the layout will be wider than the screen and create a scroll.

I don’t think there’s a fully automatic way that can work without consequence but Erik’s is pretty close.:slight_smile:

The only-child method is also good if in fact the sidebar is simply not output and would not need changes to the css.

1 Like

I think this incorporates 3 properties →

flex: 0 0 74%;

Shrink, grow and width, Right?

Should we bifurcate it because I want to write width like this →

width: calc (70.4% - 20px;)

I tried it like this →

    padding: 10px;
    flex: 0 0 74%;
    width: calc(74%-20px);

and this seems to be working.

But do you think that writing this is a good practice →

    flex: 0 0 74%;
    width: calc(74%-20px);

because the later is actually overriding the 3rd property set in the flex i.e. 74%.

I think the last property in this flex: 0 0 74%;
is flex-basis property.

Width and flex-basis are interchangeable in some circumstances and indeed in IE edge/ie11 there are some bugs where nested children don’t obey the parents dimensions where width is omitted so you always need to test flex designs in IE first to avoid these bugs.

However in your above rule you will need flex-grow set to 1 not zero otherwise when you remove the side column the container will stick at at 68.8% and not stretch to full-width. flex-basis is not the same as width (alone) and sets an initial width depending on what else is going on but will stretch if nothing else is there (even if the property width is present).

Some people use width as fallback anyway. (In some layouts you can set the flex-item to display:inline-block and combined with a width can create a fallback right down to ie8 isn simple cases).

It gets complicated at times so you just need to test the rules and see what happens.:slight_smile:

2 Likes

Close. It’s: flex-grow, flex-shrink and flex-basis (in that order).

2 Likes

If i set flex grow equal to 1 then this → [flex: 0 0 74%;]
https://www.screencast.com/t/bgBhsjlOR

will change to [flex: 0 0 74%;]https://www.screencast.com/t/QStUJORmH that means spacing between them will disappear as the justify-content is set to space-between. Or there is another way to do this?

I choose flex to avoid the complicacy of the floats, but this doesn’t seems to be that simple.

It all depends on your full code as I was feeding it into your site code and without the flex grow the column wou;dn’t expand.

I’ve just had a play around and based this on my old flexbox gutters codepen and this seems to do what you want.

2 Likes