Home > Software design >  How can I set a default width for elements in a row, but have that width reduce when more elements a
How can I set a default width for elements in a row, but have that width reduce when more elements a

Time:08-04

Lets say I have the following HTML:

<div >
  <div >1</div>
  <div >2</div>
  <div >3</div>
  <div >4</div>
  <div >5</div>
  <div >6</div>
  <div >7</div>
  <div >8</div>
</div>

When there are 4 or more items I would like there to be 4 items per row and each item having a width of 250px.

But when there are 3 or less items I would like those items to fit on a single row and each item should have a width of 345px.

I have the following css classes applied:

.parent {
  display: flex;
  flex-direction: row;
  flex-wrap: wrap;
}

.item {
  flex-grow: 1;
  min-width: calc(100%/4);
  max-width: 345px;
}

This results in each item having a width of 345px no matter what. When there are 4 or more items I get three items per row each having 345px width. When there are 3 items or less I get a single row and each item having 345px.

How can I achieve the desired behavior?

3 items or less: Single row. Each item having 345px width.
4 items or more: Multiple rows with 4 items per row. Each item having 250px width.

NOTE: Not sure if this changes anything, but the page is divided into 12 columns. And the items mentioned here appear on columns 2 through 8.

Thank you

CodePudding user response:

You need some more flex properties, see snippet:

.parent {
  display: flex;
  flex-direction: row;
  flex-wrap: wrap;
}

.item {
  flex-grow: 1;
  flex-shrink: 1;
  flex-basis: 25%;
  outline: 1px solid lime;
}
<div >
  <div >1</div>
  <div >2</div>
  <div >3</div>
</div>
<br/>
<div >
  <div >1</div>
  <div >2</div>
  <div >3</div>
  <div >4</div>
  <div >5</div>
  <div >6</div>
  <div >7</div>
  <div >8</div>
  <div >9</div>
</div>

flex-basis provides the base size for each item, while flex-grow and flex-shrink allow them to adjust to the available width. It could also be written with a shortcut

flex: 1 1 25%;

CodePudding user response:

You can consider specific selectors to achieve this:

.parent {
  display: flex;
  flex-direction: row;
  flex-wrap: wrap;
  border:1px solid;
  margin:10px;
  gap:5px;
}

.item {
  width: 345px;
  background: red;
}

.item:nth-last-child(n   4):first-child,
.item:nth-last-child(n   4):first-child ~ *{
  width: 250px;
  background: blue;
}
<div >
  <div >1</div>
  <div >2</div>
  <div >3</div>
  <div >4</div>
  <div >5</div>
  <div >6</div>
  <div >7</div>
  <div >8</div>
</div>

<div >
  <div >1</div>
  <div >2</div>
  <div >3</div>
</div>

  • Related