使用CSS获取Flexbox中的行数/行数

时间:2019-04-25 11:15:05

标签: html css flexbox

我有一个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 个答案:

答案 0 :(得分:1)

如果您知道每个元素的高度(即每一行的高度),请使用多个背景

.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)。如果height的值为负,则不会显示该图层,但如果为正,则将显示该图层,并且由于background-repeat默认为repeat,因此它将覆盖所有元素。

顺序也很重要。例如,如果我们有3行,则蓝色和黄色将变为负高度,而另一排将为正高度,因此我们将在顶部显示一个为灰色的高度。我们添加另一行,使黄色为正(它将显示)。我们删除另一行,将灰色设为负号,然后显示粉红色。

当然,仅当您要将背景样式应用于元素时,此技巧才有效。如果您想应用其他样式,我们应该找到其他技巧。

答案 1 :(得分:-1)

我能找到的唯一解决方案来自Lea Verou在2011年发表的一篇文章here

正如我在评论中所述,您将必须使用复杂的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>