仅对每个 flexbox 行中的第一项设置样式

dwh*_*ieb 4 css flexbox

我有一个水平的、环绕的 flexbox,如下所示:

.container {
  display:        flex;
  flex-direction: row;
  flex-wrap:      wrap;
}
Run Code Online (Sandbox Code Playgroud)

每行的项目数会因屏幕宽度而异,每个项目的宽度也会有所不同。

我只想为每个 flexbox 行的第一项添加样式。下面是我正在寻找的内容的说明。

Example 1
|--------|--------|--------|
|style me|        |        |
|--------|--------|--------|
|style me|        |        |
|--------|--------|--------|
|style me|        |
|--------|--------|

Example 2
|--------|---|-----|------------|
|style me|   |     |            |
|--------|---|-----|------------|
|  style me     |      |        |
|---------------|------|--------|
| style me |      |
|----------|------|
Run Code Online (Sandbox Code Playgroud)

我如何使用 Flexbox 做到这一点?

我仍然需要在调整屏幕大小时将行换行,所以我认为我不能使用 Grid。但是,如果可以使用 Grid 来解决这个问题,那对我来说也是一个很好的解决方案。

Pio*_*ski 5

正如@AndyHoffman 已经在评论中提到的那样,(截至 2019 年 3 月)使用纯 css 是不可能做到的。如果您容忍一点 javascript,那么您可以遍历所有 flex 子项,看看它们的位置是否表明它们在第一列中并相应地应用样式。下面的代码段显示了一个基本示例:

function highlightFirst(){
  let flexChildren = document.querySelectorAll('.content');
  let leftPosition = flexChildren[0].offsetLeft;
  for(let flexChild of flexChildren){
    if(flexChild.offsetLeft <= leftPosition){
      flexChild.classList.add('firstColumn');
    }else{
      flexChild.classList.remove('firstColumn');
    }
  }
}
window.addEventListener('resize', highlightFirst);
highlightFirst();
Run Code Online (Sandbox Code Playgroud)
* {
  list-style:none;
  margin: 0;
  padding: 0;
}

.wrapper {
  display: flex;
  flex-wrap: wrap;
  border: solid 1px black;
}

.content {
  height: 20px;
  background: grey;
  margin: 5px;
}

.firstColumn {
  border: 2px dashed red;
}
Run Code Online (Sandbox Code Playgroud)
<ul class="wrapper">
    <li class="content" style="width:  14px;">1</li>
    <li class="content" style="width:  77px;">2</li>
    <li class="content" style="width:  41px;">3</li>
    <li class="content" style="width:  94px;">4</li>
    <li class="content" style="width:  76px;">5</li>
    <li class="content" style="width:  61px;">6</li>
    <li class="content" style="width:  81px;">7</li>
    <li class="content" style="width:  70px;">8</li>
    <li class="content" style="width:  22px;">9</li>
    <li class="content" style="width:  29px;">10</li>
    <li class="content" style="width:  27px;">11</li>
    <li class="content" style="width:  22px;">12</li>
    <li class="content" style="width:  56px;">13</li>
    <li class="content" style="width:  32px;">14</li>
    <li class="content" style="width:  55px;">15</li>
    <li class="content" style="width:  34px;">16</li>
    <li class="content" style="width:  75px;">17</li>
    <li class="content" style="width:  97px;">18</li>
    <li class="content" style="width:  25px;">19</li>
    <li class="content" style="width:  48px;">20</li>
</ul>
Run Code Online (Sandbox Code Playgroud)

该示例非常基础,只是为了展示一个工作原理,但为了在实际场景中可用,应该对其进行扩展以规避以下缺点:

  1. javascript 仅在启动和调整窗口大小时运行 - 最好在父上使用resizeObserver.wrapper,但支持确实很差
  2. 它不会检测每个 flex child 的内容的大小变化
  3. 只假设从左到右的方向
  4. 假定所有项目的左边距都是精确的(以便第一列始终对齐左边缘)
  5. 它使用硬编码的类名
  6. 由于使用了 ES6 语言特性,它可能需要转译或重写以支持旧浏览器(这是必需的)