Flex WRAP discussion

:slight_smile:

1 Like

Now got it. Thanks.

1 Like
<div class="fcontent whitebg ftable">
	<h2 class="bmargin italic">Features table</h2>
	<div class="featuretable">
		<div class="left">Feature</div>
		<div class="middle">Pro</div>
		<div class="right">Self service</div>
	</div>	
	<div class="featuretable">
		<div class="left">Feature</div>
		<div class="middle">Pro</div>
		<div class="right">Self service</div>
	</div>
	<div class="featuretable">
		<div class="left">Feature</div>
		<div class="middle">Pro</div>
		<div class="right">Self service</div>
	</div>
	<div class="featuretable">
		<div class="left">Feature</div>
		<div class="middle">Pro</div>
		<div class="right">Self service</div>
	</div>
</div>

CSS:

.ftable {
  display: flex;
  flex-direction: column;
  border: 2px solid red;
}
.featuretable {
  display: flex;
  justify-content: space-between;
  border: 2px solid red;
  max-width: 900px;
  /*width: 900px;*/
}
.featuretable .left, 
.featuretable .middle, 
.featuretable .right {
  border: 2px solid red;
}

I am trying to make a table through flex-box, but I want to restrict the maximum width of the table. Works fine, but it was not aligned in the horizontal center. when I use margin: auto;

This creates the issue:

width_margin

margin + width

works, but

margin + max-width

contracts the design.

Using fix width seems an injustice to flex as compared to max-width.

Objective: Trying to achive this kind of table through flexbox:

No that’s tabular data and should be a table :slight_smile:

Remember flexbox is not a grid. It does not match columns to columns (unless you fix widths in some ways). Flexbox is more about horizontal alignment but when you explicitly need columns and rows to match then you need CSS grid. However in this case the data is tabular so an html table is the semantic element for the job and you get automatic row and column alignment built in for free :slight_smile:

In your example you can achieve what you want but will only appear to work because you have the same content in each. If you add the margin:auto to the featuretable but remove the flex from ftable then that will achieve what you were expecting.

.ftable {
  /*display: flex;
  flex-direction: column;*/
  border: 2px solid red;
}
.featuretable {
  display: flex;
  justify-content: space-between;
  border: 2px solid red;
  max-width: 900px;
  margin:auto;
  /*width: 900px;*/
}
.featuretable .left, 
.featuretable .middle, 
.featuretable .right {
  border: 2px solid red;
}

However should you add content then this will happen.

Save yourself all that hassle and use a table which is the correct tool for that job. If you want to use flexbox then you would need to give a width to the left and right columns to keep them equal.

2 Likes

Sure, I will atempt with table and post the outcome. Thanks.

Ok, shout if you run into trouble :slight_smile:

Here is a grid example just for fun.

2 Likes

Thank you so much sir. All these encouragements are priceless. You made my journey far easy then it would have been without you. Such mentorship would be rare in virtual world.

Every one is so supportive in this community, including moderators who were always patient in listening and resolving any post reopening request or anything else.

4 Likes

Hi there, I was able to create a table, but have some decison ambiguity. If I keep:
table-layout: fixed; It has left most content issue getting in tow line. when I move from fixed to auto, the problem gets solved, but lot of empty space is left in the left side, which looks ugly and poor design. Then I used:

table-layout: fixed; + colspan=“2” → this loks good, but colspan=“2” is part of html and in small viewport cant be eliminated and hence responsive suffers.

table

<table>
  <thead>
    <tr>
      <th scope="col">Feature	</th>
      <th scope="col">Pro </th>
      <th scope="col">Self service</th>
    </tr>
  </thead>
  <tbody>
    <tr>
      <td>Chat or email us for help	</td>
      <td>Yes</td>
      <td>Credit card only</td>
    </tr>

    <tr>
      <td>Payment options		</td>
      <td>Yes</td>
      <td>Credit card only</td>
    </tr>

      <td>Cross browser compatbility	</td>
      <td>Yes</td>
      <td>Credit card only</td>
    </tr>

    <tr>
      <td>First priority in our support queue	</td>
      <td>Yes</td>
      <td>Credit card only</td>
    </tr>
  </tbody>
</table>

CSS:

table {
  border: 1px solid #F3F3F3;
  border-collapse: collapse;
  margin: 0;
  padding: 0;
  table-layout: fixed;
  width: 100%;
  max-width: 900px;
  margin: auto;
  font-size: 1.1rem;
}

table tr {
  padding: .45rem;
}

table th,
table td {
  padding: .625em;
  text-align: center;
}

table th:first-child,
table td:first-child {
  text-align: end;
  font-weight: bold;
  font-size: 1.46rem;
  font-family: Source Sans Pro,sans-serif;
}
table th {
  font-weight: bold;
  font-size: 1.46rem;
  font-family: Source Sans Pro,sans-serif; 
  background-color: #FFFFFF;
}

tbody tr:nth-child(even) {
  background-color: #FFFFFF;
}

tbody tr:nth-child(odd) {
  background-color: #F3F3F3;
}

When colspan="2"

You can’t really do a colspan (although the browser doesn’t seem to mind) as there are no columns to span. In essence you can only span columns that are defined in the first row. Essentially you would need the first row to have 4 columns and then you could do the colspan=“2” for the next items.

e.g.


  <thead>
    <tr>
      <th></th>
      <th scope="col">Feature </th>
      <th scope="col">Pro </th>
      <th scope="col">Self service</th>
    </tr>
  </thead>
  <tbody>
    <tr>
      <td colspan="2">Chat or email us for help </td>
etc..

However you don’t need to do any of that as the fixed width algorithm basically divides the table columns equally. Therefore if you want the first column to be twice as wide then you just set its width to 50% and the other 2 columns automatically become 25%.

e.g.

table th:first-child,
table td:first-child {
  width:50%;
}

Of course that means that content will wrap within those widths unlike the table-layout:auto algorithm which makes room for the most content as needed. In your case it looks like the fixed algorithm would be best but for a lot of data with variable amounts of data in each column you would usually use choose the auto algorithm.

You can apply widths to the auto layout algorithm and they will take effect but only as long as the data fits within those dimensions. The auto algorithm basically takes widths as a suggestion but will bend them if it wants :slight_smile:

1 Like

True, That makes full sense. Thank you so much.

1 Like

Hi there,

This is the situation →

This is the CSS:

.smore .snippets {
    display: flex;
    justify-content: space-between;
    flex-wrap: wrap;
    border: 2px solid red;
    gap:2%;
}
.smore .recurse {
    flex: 0 0 32% ;
    border: 2px solid red;
}

I am using the gap property, the column gap is achieved, but the row gap is missing. Can we achieve this w/o using margin?

It’s the old problem of percentages and you can’t base the vertical gap percentage (in flexbox only as grid is ok) unless the parent has a fixed height. If for example the snippets div had a height of 500px then the percentage starts working for vertical gaps.

I don’t like percentage margins much anyway but you can instead use vw for a similar effect.

gap: .5vw;

vw and vh units are not bound by parents dimensions unlike percentages,

1 Like

Hi there,

I calculated it like this:

32+32+32 = 96%
The remaining 4% divided by two = 2% as GAP, but I was ignorant to one thing that if we do not use %age as gap, then gap is sufficient to give both row and column gap.

The horizontal calculation is mostly irrelevant as you are using justify-content:space-between. The elements are 32% wide so you will always get the remaining space distributed evenly.

If you use vw then you will get the height but you will need to have something like 1.5vw as vw units are based on the viewport width.

In this case I think you are better to use margins in percentage as vertical margins in percentage are based on the width of the element. That means the bottom margin should match the gaps at the sides.

e.g.

.wrap {
    display: flex;
    justify-content: space-between;
    flex-wrap: wrap;
    border: 2px solid red;
}
.wrap > div {
    flex: 0 0 32% ;
    border: 2px solid red;
    box-sizing:border-box;
    margin: 0 0 2%;
}

I believe that gives you what you were after :slight_smile:

1 Like

Right, I tried something similar:

.smore .snippets {
    display: flex;
    justify-content: space-between;
    flex-wrap: wrap;
    /*border: 2px solid red;*/
    /*gap:1vw;*/
}
.smore .recurse {
    /*max-width: calc(33% - 20px)*/;
    flex: 0 1 31.33% ;
    /*border: 2px solid red;*/
    margin-bottom: 15px;
    margin-top: 15px;
}

Here 2% is of what?

Percentage for vertical margins percentage are based on the width of the parent element.

I’m not that keen on percentage margins and would prefer a fixed width gap with the element itself scaling. I don’t really want bigger gaps on bigger screens although you may want to adjust at both extremes (large and small) with media queries or a mixture using clamp().

1 Like

This topic was automatically closed 90 days after the last reply. New replies are no longer allowed.