CSS столбцы макс столбцы без медиа-запросов - PullRequest
9 голосов
/ 21 марта 2019

Можно ли определить сетку с максимальным количеством столбцов, но разрешить элементам переноситься на новые строки при изменении ширины экрана?

У меня есть реализованные классы, которые позволяют переносить строки на новые строки, но максимальное количество столбцов отсутствует.

Вот кодовое перо одного метода, использующего flex box

CSS:

.flex-container {
  display: flex;
  flex-wrap: wrap;
}

Другой метод заключается в использовании сетки

.grid {
  display: grid;
  counter-reset: grid-items;
  position: relative;
}


.grid--auto-fit {
  grid-template-columns: repeat(auto-fit, minmax(200px, 1fr));
}

Я хочу довольно общее решение для этого, возможно ли то, чего я хочу достичь без Javascript или медиа-запросов?

Ответы [ 2 ]

3 голосов
/ 22 марта 2019

С помощью 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.

3 голосов
/ 21 марта 2019

Вы не можете явно сделать это либо для flexbox , либо для CSS-сетки - но вы можете использовать hack используя CSS Variables (обычно это все, что вам нужно).


CSS Grid Layout

Например, вы можете установить глобальный номер столбца в :root, в то время как определенный номер столбца в оболочке сетки - см. CSS сетка ниже с четырьмя столбцами, установленными глобально:

:root {
  --columns: 3;
}

.grid {
  display: grid;
  grid-gap: 10px;
  /* adjusting for the 10px grid-gap as well */
  grid-template-columns: repeat(auto-fit, minmax(calc(100% / var(--columns) - 20px), 1fr)); 
}

.grid > * {
  background-color: green;
  height: 200px;
}
<div class="grid">
  <div>1</div>
  <div>2</div>
  <div>3</div>
  <div>4</div>
  <div>5</div>
  <div>6</div>
</div>

Теперь вы можете установить правило для количества столбцов для контейнера grid с помощью redeclaring --columns (или вы можете добавить JS class, который содержит декларацию --columns) - см. Демонстрацию ниже:

:root {
  --columns: 3;
}

.grid {
  display: grid;
  grid-gap: 10px;
  --columns: 4; /* re-define the number of columns */
  grid-template-columns: repeat(auto-fit, minmax(calc(100% / var(--columns) - 20px), 1fr));
}

.grid > * {
  background-color: green;
  height: 200px;
}
<div class="grid">
  <div>1</div>
  <div>2</div>
  <div>3</div>
  <div>4</div>
  <div>5</div>
  <div>6</div>
</div>

Flexbox

Аналогичные аргументы действительны для flexboxes - см. Упрощенную демонстрацию ниже:

:root {
  --columns: 3;
}

.flexbox {
  display: flex;
  flex-wrap: wrap;
  --columns: 4; /* re-define the number of columns */
}

.flexbox > * {
  background-color: green;
  height: 200px;
  margin: 10px;
  flex-basis: calc(100% / var(--columns) - 20px);
}
<div class="flexbox">
  <div>1</div>
  <div>2</div>
  <div>3</div>
  <div>4</div>
  <div>5</div>
  <div>6</div>
</div>
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...