【问题标题】:Center a flex item in a row when there are a different number of items on each side当每一侧有不同数量的项目时,将一个弹性项目居中
【发布时间】:2018-03-07 21:10:05
【问题描述】:

如何实现在图片上绘制的这种布局?例如。左侧 3 个项目,1 个居中,2 个在右侧。

ul 是橙色,黑框是项目

ul {
  display: flex;
  width: 100%;
}
<ul>
  <li>Item 1</li>
  <li>Item 2</li>
  <li>Item 3</li>
  <li>Item 4</li>
  <li>Item 5</li>
  <li>Item 6</li>
</ul>

【问题讨论】:

    标签: html css flexbox css-grid


    【解决方案1】:

    弹性盒

    使用 7 个项目。

    一个在中间。

    每边有 3 个。

    visibility: hidden隐藏右边的一个。

    如果您不想在 DOM 中添加虚假项目,请使用伪元素,也可以使用 visibility: hidden

    更多细节在这里:


    网格

    如果您对其他 CSS3 技术持开放态度,则可以避免上述 flexbox hack。这是使用 Grid 的干净有效的解决方案:

    ul {
      display: grid;
      grid-template-columns: repeat(7, 1fr);
      grid-template-rows: 50px;
      grid-gap: 10px;
      grid-template-areas: " item1 item2 item3 item4 ... item5 item6 ";
    }
    
    li:nth-child(1) { grid-area: item1; }
    li:nth-child(2) { grid-area: item2; }
    li:nth-child(3) { grid-area: item3; }
    li:nth-child(4) { grid-area: item4; }
    li:nth-child(5) { grid-area: item5; }
    li:nth-child(6) { grid-area: item6; }
    
    /* non-essential demo styles */
    p {
      text-align: center;
    }
    span {
      background-color: yellow;
      padding: 5px;
    }
    li {
      display: flex;
      align-items: center;
      justify-content: center;
      color: white;
      background-color: black;
    }
    ul {
      background-color: red;
      list-style: none;
      margin: 0;
      padding: 10px;
    }
    <ul>
      <li>Item 1</li>
      <li>Item 2</li>
      <li>Item 3</li>
      <li>Item 4</li>
      <li>Item 5</li>
      <li>Item 6</li>
    </ul>
    <p><span>TRUE CENTER</span></p>

    【讨论】:

    • 这实际上是一个很好的解决方法,但是如果项目的宽度不同(例如导航栏中的链接),它就不再起作用了,不是吗?所以我必须为每个项目提供相同的固定宽度,或者没有?编辑:刚刚看到你的链接,那很好!也许绝对定位就是答案
    • 实际上,即使没有 abspos,它仍然可以完成,这可能会导致您的项目在较窄的屏幕上重叠。有关详细信息,请参阅我的链接帖子。
    • @lastnoob,为了避免 flexbox hack,考虑 CSS Grid。答案已更新。
    • 网格 1+ :)
    【解决方案2】:

    如果您需要在其父对象的正中间居中,那么最简单的方法是使用 3 个包含项目的包装器,并给它们flex-basis: 33.333%

    这样您就可以轻松控制项目在较小屏幕上的换行方式。

    ul {
      display: flex;
      width: 100%;
      list-style: none;
      padding: 0;
    }
    
    ul li {
      flex-basis: 33.333%;
      display: flex;
    }
    
    ul li:nth-child(2) span {
      margin: auto;                          /*  align center  */
    }
    
    ul li:nth-child(3) span:first-child {
      margin-left: auto;                     /*  align right  */
    }
    <ul>
      <li>
        <span>Item 1</span><span>Item 2</span><span>Item 3</span>
      </li>
      <li>
        <span>Item 4</span>
      </li>
      <li>
        <span>Item 5</span><span>Item 6</span>
      </li>
    </ul>

    另一种选择是在左/右包装上使用flex: 1 1 0

    ul {
      display: flex;
      width: 100%;
      list-style: none;
      padding: 0;
    }
    
    ul li {
      display: flex;
    }
    
    ul li:nth-child(1),
    ul li:nth-child(3) {
      flex: 1 1 0;
    }
    
    ul li:nth-child(3) span:first-child {
      margin-left: auto;
    }
    <ul>
      <li>
        <span>Item 1</span><span>Item 2</span><span>Item 3</span>
      </li>
      <li>
        <span>Item 4</span>
      </li>
      <li>
        <span>Item 5</span><span>Item 6</span>
      </li>
    </ul>

    另一个保留现有标记的方法是使用自动边距,但在本例中,居中的边距将介于 3 和 5 之间。

    ul {
      display: flex;
      width: 100%;
      list-style: none;
      padding: 0;
    }
    
    ul li:nth-child(4) {
      margin: auto;
    }
    <ul>
      <li>Item 1</li>
      <li>Item 2</li>
      <li>Item 3</li>
      <li>Item 4</li>
      <li>Item 5</li>
      <li>Item 6</li>
    </ul>

    【讨论】:

    • 不,第 4 项在第 3 项和第 5 项之间居中,因此如果一侧有更多项目,则不再绝对居中。
    【解决方案3】:

    如果不想更改标记,可以使用 Grid 布局代替 Flexbox:

    ul {
      display: grid;
      width: 100%;
      grid-template-columns: auto auto 1fr auto 1fr auto auto;
      grid-column-gap: 20px;
      list-style: none;
      padding: 0;
    }
    
    li {
      width: 50px;
      height: 50px;
      background: #000;
      color: #fff;
    }
    
    li:nth-child(5) {
      grid-column: 6;
    }
    <ul>
      <li>Item 1</li>
      <li>Item 2</li>
      <li>Item 3</li>
      <li>Item 4</li>
      <li>Item 5</li>
      <li>Item 6</li>
    </ul>

    【讨论】:

    • 使用 Grid 有很多方法可以做到这一点。我的目标是用最简单的代码重新创建 OP 的布局。
    • 没有检查您的代码示例,假设它是相似的......它不是......简短而实用,所以 +1 :)
    【解决方案4】:

    这里是:

    * {
      padding: 0;
      margin: 0;
    }
    
    ul,
    li {
      list-style:none;
    }
    
    ul {
      display:flex;
      width:100%;
      background-color: yellow;
      justify-content: space-between;
    }
    
    span {
      width: 50px;
      height: 50px;
      background-color: violet;
    }
    
    span + span {
      margin-left: 25px;
    }
    
    li {
      display: flex;
      flex-direction: row;
    }
    
    .centered {
      margin-left: -75px;
    }
    <ul>
      <li>
        <span>Item 1</span>
        <span>Item 2</span>
        <span>Item 3</span>
      </li>
      <li class="centered">
        <span>Item 4</span>
      </li>
      <li>
        <span>Item 5</span>
        <span>Item 6</span>
      </li>
    </ul>

    如果有任何不清楚的地方,请随时提出问题。

    【讨论】:

      【解决方案5】:

      我认为 flexbox 对您的情况来说是一个很好的解决方案。我创建了一个codepen,您可以在其中看到我的解决方案的结果。它使用&lt;div&gt;s,但您可以将它们改回&lt;ul&gt;

      HTML:

      <div class="container">
          <div class="inter first">
              <div class="content"></div>
              <div class="content"></div>
              <div class="content"></div>
          </div>
          <div class="inter second">
              <div class="content"></div>
          </div>
          <div class="inter first">
              <div class="content dont-mind-me"></div>
              <div class="content"></div>
              <div class="content"></div>
          </div>
      </div>
      

      CSS:

      .container {
          width: 600px;
          height: 20px;
          display: flex;
          background-color: orange;
      }
      
      .inter {
          flex: 1 0 auto;
          display: flex;
      }
      .first {
          justify-content: space-between;
      }
      
      .second {
          justify-content: center;
      }
      
      .content {
          flex: 0 1 60px;
          height: 20px;
          background-color: black;
      }
      
      .dont-mind-me {
          visibility: hidden;
      }
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2017-11-07
        • 2018-01-25
        • 1970-01-01
        • 2016-05-16
        • 2018-04-08
        • 2016-12-26
        • 2018-03-23
        • 2016-01-22
        相关资源
        最近更新 更多