Получить количество строк / строк во flexbox с помощью CSS - PullRequest
3 голосов
/ 25 апреля 2019

У меня есть элемент flexbox, который может иметь любое количество дочерних элементов.Эти дочерние элементы могут иметь различную ширину (но не более 100%) и иметь одинаковую высоту, поэтому они образуют аккуратные ряды.Иллюстрация:

[.....] [....]  
[.............]  
[..] [....] [.]  
[......]

Я хочу по-разному стилизовать элементы, когда их больше трех, чем когда всего три, два или один ряд.Есть ли способ сделать это с помощью CSS?

Я не знаю, сколько дочерних элементов будет в одной строке.Это может быть один ребенок в ряду, или два, или три.Как на иллюстрации выше.Элементы генерируются на основе данных, которые могут изменяться, поэтому я не могу зафиксировать их по x элементам в строке.

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

.parent .child {
  max-width: 100%;
  background: red;
}

// can I do this?
.parent:has-more-than-three-lines .child {
  background: blue;
}

Я знаю, что могу использовать JavaScript для чтения высоты элемента и высоты дочерних элементов после него.отрисовывает и вычисляет, сколько строк.Но я бы хотел этого избежать.Если мне нужно дать дочерним элементам фиксированную высоту, это нормально для меня.

Чтобы было ясно, я хочу стилизовать все дочерние элементы на основе роста родителей, а не только ихв дополнительных строках.

Ответы [ 2 ]

1 голос
/ 25 апреля 2019

Вот идея использования нескольких фоновых изображений, если вы знаете высоту каждого элемента (т.е. высоту каждой строки)

.parent {
  display: flex;
  flex-wrap: wrap;
  margin:10px;
  
  background:
    linear-gradient(blue,blue)     0 0/100% calc(100% - 4 * 50px),
    linear-gradient(yellow,yellow) 0 0/100% calc(100% - 3 * 50px),
    linear-gradient(grey,grey)     0 0/100% calc(100% - 2 * 50px), 
    linear-gradient(pink,pink)     0 0/100% calc(100% - 1 * 50px), 
    linear-gradient(black,black)   0 0/100% calc(100% - 0 * 50px);
}

.parent > div {
  max-width: 100%;
  height:50px;
  flex-grow:1;
  min-width:100px;
  border:1px solid red;
  box-sizing:border-box;
}

div.two {
  flex-basis:22%;
  border:1px solid blue;
}
div.three {
  flex-basis:44%;
  border:1px solid green;
}
<div class="parent">
<div class="two"></div>
<div ></div>
<div ></div>
<div class="two"></div>
<div ></div>
<div class="three"></div>
<div ></div>
<div class="two"></div>
<div class="three"></div>
<div class="three"></div>
</div>

<div class="parent">
<div class="two"></div>
<div ></div>
<div ></div>
<div class="two"></div>
<div ></div>
<div class="three"></div>
<div ></div>
<div class="two"></div>
<div class="three"></div>
<div class="three"></div>
<div ></div>
<div class="three"></div>
</div>


<div class="parent">
<div class="two"></div>
<div ></div>
<div ></div>
<div ></div>
<div class="two"></div>
<div class="three"></div>
<div class="three"></div>
</div>

<div class="parent">
<div class="two"></div>
<div ></div>
<div ></div>
<div ></div>
<div class="two"></div>
</div>

Трюк прост, у нас разные фоновые слои, и каждый слой занимает полную ширину и высоту, равную calc(100% - n * 50px).Если значение высоты отрицательно, слой не будет отображаться, но если он будет положительным, он будет отображаться, и, поскольку background-repeat по умолчанию repeat, он будет охватывать все элементы.

Порядок также важен,Если, например, у нас есть 3 строки, синий и желтый получат отрицательную высоту, а другую положительную, поэтому мы покажем ту, на вершине которой серый.Добавляем еще один ряд, делаем желтый позитив (он покажет).Мы удаляем еще одну строку, в которой мы делаем серый негатив, а розовый будет отображаться.

Конечно, этот прием работает только в том случае, если вы хотите применить стиль фона к элементу.Мы должны найти другой трюк, если вы хотите применить другие стили.

0 голосов
/ 25 апреля 2019

Единственное решение, которое я смог найти, - это статья Леа Веру, опубликованная в 2011 году. здесь .

Как уже говорилось в моих комментариях, вам придется использовать сложную nth-childселекторы.

* {
  box-sizing: border-box;
  font-family: Arial, sans-serif;;
}

body {
  margin: 0;
}

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

.wrapper {
  align-items: flex-start;
}

.container {
  width: calc(1/3 * 100% - 2em);
  flex-direction: column;
  border: 1px solid #000;
  margin: 1em;

  /* Optional : if you want border-radius on the container */
  border-radius: 5px;
  overflow: hidden;
}

.item {
  padding: 1em;
}

/* Style for standalone element */

.item:nth-child(1):nth-last-child(1) {
  background: lemonchiffon;
}

/* Style for element that has 2 childs */

.item:nth-child(1):nth-last-child(2),
.item:nth-child(2):nth-last-child(1) {
  background: lightskyblue;
}

/* Style for element that has 3 childs */

.item:nth-child(1):nth-last-child(3),
.item:nth-child(2):nth-last-child(2),
.item:nth-child(3):nth-last-child(1) {
  background: thistle;
}

/* Style for element that has 4 childs */

.item:nth-child(1):nth-last-child(4),
.item:nth-child(2):nth-last-child(3),
.item:nth-child(3):nth-last-child(2),
.item:nth-child(4):nth-last-child(1) {
	background: gainsboro;
}

/* For further information, see http://lea.verou.me/2011/01/styling-children-based-on-their-number-with-css3/ */
<div class="wrapper">
  <div class="container">
    <div class="item">
      Item
    </div>
  </div>
  <div class="container">
    <div class="item">Item</div>
    <div class="item">Item</div>
  </div>
  <div class="container">
    <div class="item">Item</div>
    <div class="item">Item</div>
    <div class="item">Item</div>
    <div class="item">Item</div>
  </div>
</div>
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...