flex-basis 对响应式 flex table 的影响

Implications of flex-basis on a responsive flex table

我学习了如何使用 flex 制作 table 的教程。它有效,但我不明白为什么,这让我很沮丧。

这个问题分为两部分。

第 1 部分

这是代码:

<style>
  ee-row {
    display: flex;
    flex-direction: row;
    flex-wrap: wrap;
    width: 100%;
  }

  ee-cell {
    flex-grow: 1;
    flex-shrink: 1;
    flex-basis: 0;
  }
</style>

<ee-table>
  <ee-row>
    <ee-cell>Header - One .. ... .</ee-cell>
    <ee-cell>Header - Two. .. </ee-cell>
    <ee-cell>Header - Three</ee-cell>
  </ee-row>

  <ee-row>
    <ee-cell>Row 1 - One. ..... .. ..</ee-cell>
    <ee-cell>Row 1 - Two. ... .. .. ... ...... </ee-cell>
    <ee-cell>Row 1 - Three..... .. .. . ... .. .. ... ...... </ee-cell>

  </ee-row>
  <ee-row>
    <ee-cell>Row 2 - One</ee-cell>
    <ee-cell>Row 2 - Two</ee-cell>
    <ee-cell>Row 2 - Three</ee-cell>
  </ee-row>
  <ee-row>
    <ee-cell>Row 3 - One</ee-cell>
    <ee-cell>Row 3 - Two</ee-cell>
    <ee-cell>Row 3 - Three</ee-cell>
  </ee-row>
<ee-table>

问题:

(1a) 为什么 flex-basis: 0 可以使列对齐得很好? (试着把它拿出来,你会得到一个错位的 table,这实际上是我对 flex 的期望)

(1b) 如何强制指定列的大小?例如,如果我希望第一列尽可能窄怎么办?如果我希望第三列具有特定宽度怎么办?

第 2 部分

这实际上是用来制作响应式 table。它实际上工作得非常漂亮。对于宽屏幕,它将显示所有列。对于中等屏幕,它将显示除 "unnecessary" 单元格之外的所有内容。对于小屏幕,它会堆叠信息而不显示 headers。

这里是最短的展示方式:

<style>
  ee-row {
    display: flex;
    flex-direction: row;
    flex-wrap: wrap;
    width: 100%;
  }

  ee-cell {
    flex-grow: 1;
    flex-shrink: 1;
    flex-basis: 0;

  }

  @media screen and (max-width: 800px) {
    ee-cell {
      flex-basis: 100%;
    }
    ee-cell[header] {
      display: none
    }
  }

  @media screen and (max-width: 1200px) {
    ee-cell[unnecessary] {
      display: none
    }
  }


</style>

<ee-table>
  <ee-row>
    <ee-cell header>Header - One .. ... .</ee-cell>
    <ee-cell header>Header - Two. .. </ee-cell>
    <ee-cell header unnecessary>Header - Three</ee-cell>
  </ee-row>

  <ee-row>
    <ee-cell>Row 1 - One. ..... .. ..</ee-cell>
    <ee-cell>Row 1 - Two. ... .. .. ... ...... </ee-cell>
    <ee-cell unnecessary>Row 1 - Three..... .. .. . ... .. .. ... ...... </ee-cell>

  </ee-row>
  <ee-row>
    <ee-cell>Row 2 - One</ee-cell>
    <ee-cell>Row 2 - Two</ee-cell>
    <ee-cell unnecessary>Row 2 - Three</ee-cell>
  </ee-row>
  <ee-row>
    <ee-cell>Row 3 - One</ee-cell>
    <ee-cell>Row 3 - Two</ee-cell>
    <ee-cell unnecessary>Row 3 - Three</ee-cell>
  </ee-row>
<ee-table>

(2a) 这是一条好路吗?

(2b) 是否有可能将其转换为 CSS tables 并拥有此 "holy grail of table responsiveness" 而无需进入 flex 兔子洞?

(2c) 事实上,这是一个兔子洞吗?

我会尽力回答您的弹性问题,但我建议在开始之前使用 grids 来实现您的目标可能是一种更合乎逻辑和直观的方法。你有没有理由避免这些?它们的布局就像表格一样,您可以更轻松地控制它们。

1a.

Flex-basis 指示弹性项目的初始大小(在您开始增长或收缩以适应 space 之前)。如果您删除了 flex-basis,它将转到默认值 auto。这意味着所有弹性项目的初始大小将明确定义(例如 150 像素)或根据其内容的大小自动调整大小。通过将其设置为零,您为所有元素提供了相同的起点。因此,如果 flex-basis 为 0,而 flex-grow 为 1,则所有元素将平均增长以填充 space。注意:flex-grow 只是一个比例,表示当有剩余 space.

时要填充多少 space

1b.

要使第一列尽可能小:(我不确定您是否有特定的宽度,如果有请参阅下一个解决方案)

/* Leave the rest of the code as is */
ee-cell:nth-child(1) { 
   flex-basis: auto;
   flex-grow: 0;
}

要使第三列具有特定宽度:

/* Leave the rest of the code as is */
ee-cell:nth-child(3) { 
    width: 100px; 
    flex-basis:auto;
    flex-grow: 0; 
}

这两种解决方案都将基础设置为自动,表示初始大小将特定于此元素(内容 - 在第一个示例中 - 或特定宽度 - 在第二个示例中),然后说不允许此项目增长以帮助填充 space (flex-grow: 0)

2.

我看这个 CSS 我主要关心的是可读性和易用性(未来维护)。我认为你可以用 flex 实现你的目标,正如你所做的那样。但如果是我,我会改用网格。下面的代码做同样的事情,但也给了你更多的控制权(我将在下面列出你将拥有的更多选项)并且,在我看来,当你阅读它时更有意义:

<style>
  ee-table {
    display: grid;
    grid-template-columns: repeat(3, 1fr);
    /* use the line below to accomplish 1b - smallest possible first column, set width last column */
    /* grid-template-columns: auto 1fr 100px; */
    width: 100%;
  }

 @media screen and (max-width: 1200px) {
  ee-table { 
    grid-template-columns: 1fr 1fr;
  }
   ee-cell[unnecessary] {
     display: none
   }
 }

 @media screen and (max-width: 800px) {
    ee-table { 
      grid-template-columns: 1fr;
    }
    ee-cell[header] {
      display: none
    }
 }
</style>

<ee-table>
    <ee-cell header>Header - One .. ... .</ee-cell>
    <ee-cell header>Header - Two. .. </ee-cell>
    <ee-cell header unnecessary>Header - Three</ee-cell>

    <ee-cell>Row 1 - One. ..... .. ..</ee-cell>
    <ee-cell>Row 1 - Two. ... .. .. ... ...... </ee-cell>
    <ee-cell unnecessary>Row 1 - Three..... .. .. . ... .. .. ... ...... </ee-cell>

    <ee-cell>Row 2 - One</ee-cell>
    <ee-cell>Row 2 - Two</ee-cell>
    <ee-cell unnecessary>Row 2 - Three</ee-cell>

    <ee-cell>Row 3 - One</ee-cell>
    <ee-cell>Row 3 - Two</ee-cell>
    <ee-cell unnecessary>Row 3 - Three</ee-cell>
<ee-table>

带有网格的其他选项

  • 网格间隙:您可以设置列和行之间的间距(如果您愿意,可以不同)。
  • 从行中解放出来:当您可以在 html 的一个长列表中包含所有内容时,您将拥有更大的灵活性。这也可以用 flex 来完成,但不太优雅。
  • 移动单元格:您可以在 flexbox 中执行此操作,但您无法像在网格中那样在行之间执行此操作。