使用 flex 实现四列到列列表的反馈 - 第 2 轮

Posted

技术标签:

【中文标题】使用 flex 实现四列到列列表的反馈 - 第 2 轮【英文标题】:Feedback to achieve four column to column list using flex - Round 2 【发布时间】:2021-09-26 17:39:51 【问题描述】:

我无法实现响应式弹性布局来容纳无序列表。每个列表项都需要在链接顶部包含一个图像。我希望它在台式机、笔记本电脑和平板电脑尺寸上有四列,然后在移动设备上分成两列。另一个堆栈溢出用户帮助我清理了我的代码,但是当我用链接(我需要使用)替换段落元素时,它破坏了均匀间隔的四到两列布局。

出于可访问性目的,我需要使用无序列表,因为它最终会包含一个图像列表,以及它各自的链接。

这是我现在所处的位置:

https://codepen.io/shannon-hart82/pen/QWvgpdz

<style>
body 
    display: flex;
    justify-content: center;


.container 
  display: block;
  


.headline 
  display: flex;
  flex-direction: column;
  justify-content: center;
  align-items: center;


ul.flex-list 
  list-style: none;
  display: flex;
  width: calc((200px + 2 * 10px)*2);
  flex-wrap: wrap;


ul.flex-list img 
    width: 200px;
    height: 200px;


li.flex-list-item 
  text-align: center;
  padding: 10px;


a 
  display: inline-block;
 width: 100%;
  



@media screen and (min-width: 991px) 
    ul.flex-list 
        width: calc((200px + 2 * 10px)*4);
    

</style>
<body>
    <div class="container">
      <div class="headline">
          <h2 >Best fruit</h2>
          <p>Consectetur adipiscing elit, sed do eiusmod tempor incididunt.</p>
      </div>

      <ul class="flex-list">
        <li class="flex-list-item">
          <img src="https://via.placeholder.com/200"  />
          <a href="/">Apples</a>
        </li>

        <li class="flex-list-item">
          <img src="https://via.placeholder.com/200"  />

          <a href="/">Oranges</a>
        </li>

        <li class="flex-list-item">
          <img src="https://via.placeholder.com/200"  />

          <a href="/">Strawberries</a>
        </li>

        <li class="flex-list-item">
          <img src="https://via.placeholder.com/200"  />

          <a href="/">Blueberries</a>
        </li>

        <li class="flex-list-item">
          <img src="https://via.placeholder.com/200"  />

          <a href="/">Nectarines</a>
        </li>

        <li class="flex-list-item">
          <img src="https://via.placeholder.com/200"  />

          <a href="/">Bananas</a>
        </li>

        <li class="flex-list-item">
          <img src="https://via.placeholder.com/200"  />

          <a href="/">Rasberries</a>
        </li>

        <li class="flex-list-item">
          <img src="https://via.placeholder.com/200"  />

          <a href="/">Blackberries</a>
        </li>
      </ul>
    </div>
  </body>

谢谢!

【问题讨论】:

当你以这种方式使用 flexbox 时,每行显示的项目数将取决于子项目的宽度和父容器的宽度。如果将图像的宽度从 200 像素减小到 160 像素,它将堆叠 4 宽。如果您需要图像保持 200 像素宽,可以尝试调整列表项元素的宽度或内边距。 【参考方案1】:

设置一个固定的min-widthflex-basis来控制每个flex line(row)中flex item的数量

总的来说,这将是使用CSS grid layout 最容易实现的。但是这个问题专门要求一个 flexbox 解决方案,所以我会回答这个问题。

当前的解决方案不起作用,因为图像的大小 (160 像素) 会影响弹性项目的最小大小。发生这种情况是因为您的弹性项目具有默认的min-width: auto,而对于弹性项目,这意味着它们将尝试至少适合其内容,包括图像。然后,该最小尺寸会影响进入每个 flex 行的 flex 项目的数量。

因此,要获得每个 flex 行中确切数量的项目,您需要以下两件事:

在您的弹性项目上设置min-width: 0,以便它们停止查看其内容(图像)以确定它们的最小尺寸 将flex-basis 设置为与您想要的列数相对应的弹性容器的百分比。如果你想要 2 列,每个项目应该有flex-basis: 50%。对于 4 列,这将是 flex-basis: 25% 设置box-sizing: border-box 以确保您在弹性项目上设置的任何borderpadding 都包含在flex-basis 百分比中。否则,您的弹性项目将增长到超过您想要的百分比,这将再次弄乱您获得的列数。

以下是您的问题的有效解决方案。我使用了CSS custom property 来简化flex-basis 的计算,但您也可以将百分比输入其中。

body 
  display: flex;
  justify-content: center;


.container 
  border: 2px dotted black;
  display: block;


.headline 
  border: 2px dotted green;
  text-align: center;


ul.flex-list 
  list-style: none;
  display: flex;
  width: calc((160px + 2 * 10px) * 2);
  flex-wrap: wrap;
  padding: 0;


ul.flex-list img 
  width: 160px;
  height: 160px;


li.flex-list-item 
  --number-of-columns: 2;
  border: 2px dotted blue;
  text-align: center;
  padding: 10px;
  min-width: 0;
  flex: 1 1 calc(100% / var(--number-of-columns));
  box-sizing: border-box;


a 
  border: 2px dotted red;
  display: inline-block;
  width: 100%;


@media screen and (min-width: 991px) 
  ul.flex-list 
    width: calc((200px + 2 * 10px) * 4);
  

  li.flex-list-item 
    --number-of-columns: 4;
  
<div class="container">
  <div class="headline">
    <h2>Best fruit</h2>
    <p>Consectetur adipiscing elit, sed do eiusmod tempor incididunt.</p>
  </div>

  <ul class="flex-list">
    <li class="flex-list-item">
      <img src="https://via.placeholder.com/200"  />
      <a href="/">Apples</a>
    </li>

    <li class="flex-list-item">
      <img src="https://via.placeholder.com/200"  />

      <a href="/">Oranges</a>
    </li>

    <li class="flex-list-item">
      <img src="https://via.placeholder.com/200"  />

      <a href="/">Strawberries</a>
    </li>

    <li class="flex-list-item">
      <img src="https://via.placeholder.com/200"  />

      <a href="/">Blueberries</a>
    </li>

    <li class="flex-list-item">
      <img src="https://via.placeholder.com/200"  />

      <a href="/">Nectarines</a>
    </li>

    <li class="flex-list-item">
      <img src="https://via.placeholder.com/200"  />

      <a href="/">Bananas</a>
    </li>

    <li class="flex-list-item">
      <img src="https://via.placeholder.com/200"  />

      <a href="/">Rasberries</a>
    </li>

    <li class="flex-list-item">
      <img src="https://via.placeholder.com/200"  />

      <a href="/">Blackberries</a>
    </li>
  </ul>
</div>

【讨论】:

以上是关于使用 flex 实现四列到列列表的反馈 - 第 2 轮的主要内容,如果未能解决你的问题,请参考以下文章

Excel从列到列的映射

如果连续空间不足,则将 flex-direction 切换到列

用CSS+DIV实现四列式分栏

JQuery Sortable + Bootstrap - 第一列到最后一列 - 项目消失

等宽布局和flex

散列·再散列