簡體   English   中英

如何在最后一行左對齊的情況下將包裝 flex 項目顯示為間隔?

[英]How to display wrapping flex items as space-between with last row aligned left?

我有一個固定寬度的容器,其中必須連續出現幾個寬度可變的元素,這些元素可以根據需要溢出到其他行中。

但是,每個元素的開頭必須與其頂部的元素對齊,因此在 ASCII 藝術中它看起來像這樣(例如,填充為 1):

    /----------------------------------\
    |                                  |
    | # One    # Two   # Three  # Four |
    | # Five   # Six                   |
    |                                  |
    \----------------------------------/

換句話說:

  • 每行的第一個元素必須左對齊
  • 每行的最后一個元素(最后一行除外)必須右對齊
  • 每個元素都必須與其上方的元素左對齊

我正在嘗試為此使用 flexbox,但沒有成功。

是我迄今為止最好的,使用flex-wrap: wrap容器和flex-grow: 1元素。

問題是最后一行填充到邊緣。

justify-content: flex-start; // this does nothing

如果我去掉flow-grow: 1那么元素分布不均。 我還嘗試在元素上擺弄last-of-type ,但這還不夠。

這甚至可能與flexbox一起flexbox ,還是我以錯誤的方式進行處理?

在嘗試了這里的建議(謝謝!)並在網上廣泛搜索后,我得出的結論是,這對於 flexbox 來說根本不可能。 我的意思是其他人已經得出了這個結論,而我仍然頑固地試圖讓它發揮作用,直到最終放棄並接受更聰明的人的智慧。

我發現有幾個鏈接可能會更好地解釋它,或者要求的不同方面,所以我將它們張貼在這里是為了......后代。

如何保持包裹的 flex-items 與前一行元素的寬度相同?

http://fourkitchens.com/blog/article/responsive-multi-column-lists-flexbox

我知道我有點晚了,但我在過去一個小時左右一直在尋找解決方案,我想我已經想通了。 將空的div放在容器的末尾,並將flex-grow: 1為它,僅此而已。 還要在容器上設置justify-content: space-between ,不要在其他項目上使用flex-grow 這將始終使最后一行向左對齊,因為此 div 將穿過所有剩余空間。

然而,這樣做的問題是它總是使最后一行左對齊 - 即使它是唯一的一行,這使得這個解決方案對我來說不可用,但它可能適用於可以期望多行項目的人。

使用 flexbox 沒有簡單的方法可以做到這一點。 但是如果你願意犧牲 IE 那么你可以用 css grid來做,把它添加到容器中:

display: grid;
grid-template-columns: repeat(auto-fill, minmax(240px, 1fr));

如果你想在元素之間有一些空間然后添加

grid-gap: 10px;

如果您的項目的寬度是固定的,您可以在項目列表的末尾添加幾個空的 div:

<div class="item">meaningful content</div>
<div class="item">meaningful content</div>
<div class="item">meaningful content</div>

<div class="empty-div"></div>
<div class="empty-div"></div>
<div class="empty-div"></div>

進而:

.item, .empty-div{ width: 150px; } // make them the same width

工作得很好。

我能夠通過正負邊距的組合實現預期的結果。

如果容器中的每個元素都定義了一個邊距以在它們之間創建一個空間:

.container .element {
   flex: 1;
   margin: 0px 5px;
}

使用相同數量的負邊距從容器中每行的邊緣恢復像素:

.container {
   display: flex;
   flex-direction: row;
   flex-wrap: wrap;
   margin: 0px -5px;
}

這應該導致行中的每個元素與容器邊緣的每行的第一個和最后一個之間有 10px 的間隔。

CSS Flex 4 列始終從左側開始。 看不出這是不可能的? 如果列應該等於,這對我們使用calc()和相對單位工作:

/* parent */

.ua-flex {
    display: flex;
    flex-wrap: wrap;
    justify-content: start;
}

/* children */

.ua-flex > * {
    flex: 0 0 calc(25% - 1em);
    margin: 1em 0 0 0;
}
.ua-flex > :not(:nth-child(4n+4)) {
    margin-right: 1.333333em;
}

我在這里遺漏了什么? 它完全是關於數學的,在這種情況下減去的 calc() 1em,在 4 列中的 3 列上給出了 3 個間隙 1.333em 的空間,並且在 3 列中減去了 0.5em 的 calc() 應該給出了 0.666em 間隙和邊距右4 列。

希望這有用...

我只是偶然發現了同樣的問題,並想出了另一種解決方案。 我無法決定它是骯臟的還是優雅的,但你自己決定。

向容器添加與每行最大項目數一樣多的空div為它們分配與行項目相同的類,但從中刪除任何邊距或填充(基本上是任何賦予它們高度的東西)。 這將導致該行按預期運行,因為在最后一行項目之后,總會有足夠的不可見“間隔”來填充該行。 被包裝到下一行的那些沒有高度,所以它們不應該影響頁面的其余部分。

這里的例子: https : //jsfiddle.net/amknwjmj/

 .products { display: flex; flex-wrap: wrap; justify-content: space-between; } .product { /* set top and bottom margin only, as left and right will be handled by space-between */ margin: 0.25rem 0; /* account your desired margin two times and substract it from the base width of the row item */ flex-basis: calc(25% - (0.25rem * 2)); } .product.spacer { /* remove all properties increasing the element height from the spacers to avoid them being visible */ margin: 0; padding: 0; height: initial; } /* start demo styles (purely eye-candy not required for this to work) */ * { box-sizing: border-box; font-family: sans-serif; } .products { padding: .25rem .5rem; background: powderblue; } .product { height: 75px; line-height: 75px; padding: .25rem; text-align: center; background: steelblue; color: #fff; } .product.spacer { background: none; /* of course, spacers should NOT have a border but they are helpful to illstrate what's going on. */ border: 1px dashed gray; } /* end demo styles */
 <div class="products"> <article id="product-1" class="product">P1</article> <article id="product-2" class="product">P2</article> <article id="product-3" class="product">P3</article> <article id="product-4" class="product">P4</article> <article id="product-5" class="product">P5</article> <div class="product spacer"></div> <div class="product spacer"></div> <div class="product spacer"></div> <div class="product spacer"></div> </div>

在許多情況下可行的一種解決方案是簡單地對項目應用padding 然后你可以使用flex-start ,並在卡片之間獲得間距。

例如

 .container { display: flex; justify-content: center; } .parent { width: 420px; display: flex; flex-wrap: wrap; flex-direction: row; justify-content: flex-start; } .child { flex: 0 30%; min-width: 100px; padding-left: 10px; margin-bottom: 10px; } .child-content { background-color: yellow; border: 1px solid black; height: 100px; }
 <div class="container"> <div class="parent"> <div class="child"> <div class="child-content"> Box </div> </div> <div class="child"> <div class="child-content"> Box </div> </div> <div class="child"> <div class="child-content"> Box </div> </div> <div class="child"> <div class="child-content"> Box </div> </div> <div class="child"> <div class="child-content"> Box </div> </div> </div> </div>

所以,你有一個容器和里面的一些東西?

<div class="container">
  <span>msg1</span>
  <span>msg1</span>
  <span>msg1</span>
  <span>msg1</span>
  <span>msg1</span>
</div>

這就是它的工作原理,當您為容器聲明display: flex ,它的所有直接子項也將變為 flex ,並帶有一些默認配置( align-items:strech )。

我想你已經明白了,所以,也許你可以嘗試使用justify-content: space-between這將使你的項目在行中對齊,使它們等距加上flex-basis: 25% (以證明總是有 4 個項目在一行中,根據需要更改 de %),這應該適用於除最后一行之外的所有行。 對於最后一個,您可以使用 css 選擇器(如last-child )並將其屬性設置為flex-grow: 0 / flex-shrink:0 (解決您的問題之一,如果您使用flex: 1 1 25%而不是flex-basis ) 和align-self: flex-start或任何你喜歡的

你可以用一個fixed-with-pseudo-element來試試:

.container {
 display:flex;
 justify-content:space-between;
}
.container:after {
  content: '';
  flex-grow: 0;
  width: 25%;
}
.container .element {
  width: 25%;
}

您可以通過執行以下操作在除 flex-wrap 行中的最后一項之外的每個項目上指定margin-right

.item:not(:nth-child(4n)) {
  margin-right: 20px;
}

我面臨着同樣的問題,實際上這很簡單。 無需放置一些 SCSS 和或 jQuery。

您只需要指定“正方形”的最大數量,並進行取模以了解它是否與您的 maxNumber 匹配。 如果不是,您只需要定義一個快速函數來增加您的數字,直到該模返回 0。

當你有你的號碼時,你只需要循環你的html。 對我來說,我在 ReactNative 上編碼:

const RenderInvisibleSquare = (nb) => {
 let tab = [];
 let i = 1;
 for (; (nb + i) % 3 !== 0; i++) {}
 for (let n = 0; n < i; n++) {
  tab.push(<View style={{ width: 120, height: 120, backgroundColor: 'red' }}/>);
 }
 return tab;
};


<ScrollView>
  {
    data.map(item => (
      <View>
        <View style={{ marginVertical: 5 }}>
          <Text style={{ textAlign: 'center', color: '#7E8BF5' }}>{item.title}</Text>
        </View>
        <View style={{ flex: 1, flexWrap: 'wrap', alignItems: 'center', justifyContent: 'space-around', flexDirection: 'row' }}>
          {
            item.data.map(elem => (
              <View style={{ width: 120, height: 120, marginBottom: 10, backgroundColor: 'red' }} />
            ))
          }
          { item.data.length % 3 !== 0 && RenderInvisibleSquare(item.data.length)}
        </View>
      </View>
    ))
  }
</ScrollView>

如果你不想要內容 (backgroundColor: 'red') 在我的情況下你必須讓它“透明”。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2025 STACKOOM.COM