С помощью flexbox вы можете просто установить max-width
для контейнера, так как ваши элементы имеют фиксированную ширину:
.flex-container {
display: flex;
flex-wrap: wrap;
max-width:calc(5*(200px + 20px));
}
.flex-item {
background: tomato;
padding: 5px;
width: 200px;
height: 100px;
margin: 10px;
line-height: 100px;
color: white;
font-weight: bold;
font-size: 2em;
text-align: center;
box-sizing:border-box;
}
<div class="flex-container wrap">
<div class="flex-item">1</div>
<div class="flex-item">2</div>
<div class="flex-item">3</div>
<div class="flex-item">4</div>
<div class="flex-item">5</div>
<div class="flex-item">6</div>
<div class="flex-item">7</div>
<div class="flex-item">8</div>
</div>
Единственным недостатком является то, что вам нужно знать ширину ваших элементов и их поля, чтобы правильно установить max-width
.
Если вы хотите, чтобы ваши элементы расширялись и покрывали всю ширину, вы можете использовать трюк с min-width
, как показано ниже:
.flex-container {
display: flex;
flex-wrap: wrap;
}
.flex-item {
background: tomato;
padding: 5px;
min-width: 200px;
width:calc(100%/5 - 20px); /*5 columns*/
height: 100px;
margin: 10px;
line-height: 100px;
color: white;
font-weight: bold;
font-size: 2em;
text-align: center;
box-sizing:border-box;
}
<div class="flex-container wrap">
<div class="flex-item">1</div>
<div class="flex-item">2</div>
<div class="flex-item">3</div>
<div class="flex-item">4</div>
<div class="flex-item">5</div>
<div class="flex-item">6</div>
<div class="flex-item">7</div>
<div class="flex-item">8</div>
</div>
Здесь также необходимо учитывать запас. Вы можете легко сделать это более гибким, используя переменную CSS:
.flex-container {
display: flex;
flex-wrap: wrap;
}
.flex-item {
--m:10px;
background: tomato;
padding: 5px;
min-width: 200px;
width:calc(100%/5 - 2*var(--m)); /*5 columns*/
height: 100px;
margin: var(--m);
line-height: 100px;
color: white;
font-weight: bold;
font-size: 2em;
text-align: center;
box-sizing:border-box;
}
<div class="flex-container wrap">
<div class="flex-item">1</div>
<div class="flex-item">2</div>
<div class="flex-item">3</div>
<div class="flex-item">4</div>
<div class="flex-item">5</div>
<div class="flex-item">6</div>
<div class="flex-item">7</div>
<div class="flex-item">8</div>
</div>
Вы также можете рассмотреть flex-grow
, если хотите, чтобы ваш элемент всегда расширялся (даже если есть перенос), но вы можете столкнуться с проблемой последней строки, которую вам нужно исправить с некоторыми хаки:
.flex-container {
display: flex;
flex-wrap: wrap;
--m:10px;
}
.flex-item {
background: tomato;
padding: 5px;
min-width: 200px;
flex-grow:1;
width:calc(100%/5 - 2*var(--m)); /*5 columns*/
height: 100px;
margin: var(--m);
line-height: 100px;
color: white;
font-weight: bold;
font-size: 2em;
text-align: center;
box-sizing:border-box;
}
.flex-container span {
min-width: 200px;
flex-grow:1;
width:calc(100%/5 - 2*var(--m)); /*5 columns*/
margin:0 var(--m);
}
<div class="flex-container wrap">
<div class="flex-item">1</div>
<div class="flex-item">2</div>
<div class="flex-item">3</div>
<div class="flex-item">4</div>
<div class="flex-item">5</div>
<div class="flex-item">6</div>
<div class="flex-item">7</div>
<div class="flex-item">8</div>
<!-- 4 empty elements to fix the issue (we can also use pseudo element) -->
<span></span>
<span></span>
<span></span>
<span></span>
</div>
В приведенном ниже примере мы сделали количество столбцов равным 5, поэтому нам понадобится как минимум 4 пустых элемента для решения проблемы на случай, если в последней строке будет от 1 до 4 элементов. Конечно, это недостаток, но, поскольку вы знаете количество столбцов, вы можете легко установить эти пустые элементы, и вам не понадобится JS.
Чтобы сделать его более гибким, вот идея с переменными CSS:
.flex-container {
display: flex;
flex-wrap: wrap;
border:1px solid;
--m:10px;
--n:5;
--width:150px;
}
.flex-item {
background: tomato;
min-width: var(--width);
flex-grow:1;
width:calc(100%/var(--n) - 2*var(--m));
height: 50px;
margin: var(--m);
box-sizing:border-box;
}
.flex-container span {
display:contents; /* each span will give us 2 elements*/
}
.flex-container span:before,
.flex-container span:after,
.flex-container:before,
.flex-container:after{
content:"";
min-width: var(--width);
flex-grow:1;
width:calc(100%/var(--n) - 2*var(--m));
margin:0 var(--m);
order:1; /*we make sure they are at the end*/
}
<div class="flex-container wrap">
<div class="flex-item">1</div>
<div class="flex-item">2</div>
<div class="flex-item">3</div>
<div class="flex-item">4</div>
<div class="flex-item">5</div>
<div class="flex-item">6</div>
<div class="flex-item">7</div>
<div class="flex-item">8</div>
<!-- a lot of elements !! -->
<span></span>
<span></span>
<span></span>
<span></span>
<span></span>
<span></span>
<span></span>
</div>
<div class="flex-container wrap" style="--n:10">
<div class="flex-item">1</div>
<div class="flex-item">2</div>
<div class="flex-item">3</div>
<div class="flex-item">4</div>
<div class="flex-item">5</div>
<div class="flex-item">6</div>
<div class="flex-item">7</div>
<div class="flex-item">8</div>
<!-- a lot of elements !! -->
<span></span>
<span></span>
<span></span>
<span></span>
<span></span>
<span></span>
<span></span>
</div>
<div class="flex-container wrap" style="--n:3">
<div class="flex-item">1</div>
<div class="flex-item">2</div>
<div class="flex-item">3</div>
<div class="flex-item">4</div>
<div class="flex-item">5</div>
<div class="flex-item">6</div>
<div class="flex-item">7</div>
<div class="flex-item">8</div>
<!-- a lot of elements !! -->
<span></span>
<span></span>
<span></span>
<span></span>
<span></span>
<span></span>
<span></span>
</div>
Я использовал display:contents
, чтобы иметь возможность установить N пустых элементов, которые позже будут рассматриваться как 2 * N, что может уменьшить код.
Если у вас будет 7 столбцов, нам потребуется только 6 дополнительных элементов. Мы можем использовать два псевдоэлемента, тогда только 2 пустых элемента, чтобы покрыть оставшиеся 4.