Çok satırlı bir esnek kutu düzeninde satır sonları nasıl belirtilir?


236

Çok satırlı flexbox'ta satır sonu yapmanın bir yolu var mı?

Örneğin, bu CodePen her 3 öğeden sonra kırmak için .

.container {
  background: tomato;
  display: flex;
  flex-flow: row wrap;
  align-content: space-between;
  justify-content: space-between;
}
.item {
  width: 100px;
  height: 100px;
  background: gold;
  border: 1px solid black;
  font-size: 30px;
  line-height: 100px;
  text-align: center;
  margin: 10px;
}
.item:nth-child(3n) {
  background: silver;
}
<div class="container">
  <div class="item">1</div>
  <div class="item">2</div>
  <div class="item">3</div>
  <div class="item">4</div>
  <div class="item">5</div>
  <div class="item">6</div>
  <div class="item">7</div>
  <div class="item">8</div>
  <div class="item">9</div>
  <div class="item">10</div>
</div>

Sevmek

.item:nth-child(3n){
  /* line-break: after; */    
}

1
Aynı ya da çok benzer bir sorunum vardı; Her 4 öğeyi kırmak istedim, bu yüzden her esnek öğenin genişliğini 25vw (veya% 25) olarak ayarladım. Yani sizin durumunuzda, her 3 madde için 33,3vw (veya% 33,3) kullanırsınız. İstediğim için mükemmel çalıştı. Daha basit bir yöntem arıyorsanız başka birine yardımcı olabilirler.
Ben Clarke

Ben Clarke! Çok teşekkür ederim! Cevabınız işe yarayan tek soru. Cevap olarak eklemeyi düşünebilirsiniz. :-)
itmuckel

Yanıtlar:


322

En basit ve en güvenilir çözüm, esnek eşyaları doğru yerlere yerleştirmektir. Yeterince genişlerse ( width: 100%), satır sonunu zorlarlar.

Ama bu çirkin ve anlamsal değil. Bunun yerine, esnek kabın içinde sözde elemanlar oluşturabilir ve orderbunları doğru yerlere taşımak için kullanabiliriz.

Ancak bir sınırlama vardır: esnek kabın sadece bir ::beforeve bir ::aftersözde elemanı olabilir. Bu, yalnızca 2 satır sonunu zorlayabileceğiniz anlamına gelir.

Bunu çözmek için esnek öğeler yerine esnek öğelerin içinde sözde öğeler oluşturabilirsiniz. Bu şekilde 2 ile sınırlı kalmayacaksınız. Ancak bu sözde unsurlar esnek öğeler olmayacak, bu nedenle satır sonlarını zorlayamayacaklar.

Ancak neyse ki, CSS Display L3 tanıtıldı display: contents(şu anda yalnızca Firefox 37 tarafından desteklenmektedir):

Öğenin kendisi herhangi bir kutu oluşturmaz, ancak alt öğeleri ve sözde öğeler hala normal şekilde kutular oluşturur. Kutu oluşturma ve düzenleme amacıyla, öğe, belge ağacındaki alt öğeleri ve sözde öğelerle değiştirilmiş gibi ele alınmalıdır.

Böylece display: contentsesnek kabın çocuklarına başvurabilir ve her birinin içeriğini ek bir ambalajın içine sarabilirsiniz. Daha sonra, esnek eşyalar bu ek sarmalayıcılar ve çocukların yalancı elemanları olacaktır.

Alternatif olarak, Fragmanlama Flex Düzeni ve CSS Fragmentasyonuna göre Flexbox,break-before , break-afterya da CSS 2.1 takma adları:

.item:nth-child(3n) {
  page-break-after: always; /* CSS 2.1 syntax */
  break-after: always; /* New syntax */
}

Flexbox'taki zorunlu satır sonları henüz geniş çapta desteklenmiyor, ancak Firefox'ta çalışıyor.


@Oriol İlk yaklaşım hakkında neden anlamsız değil çirkin olduğunu söylüyorsunuz? Sadece merak.
nacho4d

18
@ nacho4d Çünkü HTML stil oluşturma amacıyla değiştirilmemelidir. Fikrinizi değiştirirseniz ve 3 yerine 4 sütun istediğinize karar verirseniz, belki de çok sayıda HTML'yi değiştirmeniz gerekir. break-afterYalnızca stil sayfasındaki bir seçicinin değiştirilmesini gerektiren çözümle karşılaştırın .
Oriol

1
Ben çözüm iki numaralı IE çalışmak display: block;için .container ::beforeve ::aftersözde sınıfları eklemek gerekiyordu . YMMV!
twined

1
@twined Bu garip, çünkü esnek öğeler otomatik olarak bloke edilmeli.
Oriol

2
Sayfa sonu öğesi spesifikasyondan kaldırıldığı için, ikinci snippet'inizi sütun yönünde çalıştırmak ve kabının yüksekliğini genişletmemek mümkün mü? Hiç şansım yoktu ve flex-base'i% 100 / item olarak ayarlamak boyunu uzatıyor.
Lucent

42

Benim bakış açımdan, <hr> öğeleri esnek öğeler arasında satır kesmeleri olarak kullanmak daha anlamlıdır .

.container {
  display: flex;
  flex-flow: wrap;
}

.container hr {
  width: 100%;
}
<div class="container">
  <div>1</div>
  <div>2</div>
  <hr>
  <div>3</div>
  <div>2</div>
  ...
</div>

Chrome 66, Firefox 60 ve Safari 11'de test edilmiştir.


7
Ben de öyle yapıyorum, harika çalışıyor. Hr {flex-based:% 100; yükseklik: 0; kenar boşluğu: 0; sınır: 0; kesmeyi kesintisiz hale getirir.
Besworks

Bu yaklaşımı seviyorum. Not: gap: 10px;satırlar arasındaki mesafeyi kullanırken aslında 20px. Adresine için, yarım bu boyutta bir satır boşluğu belirtin: gap: 5px 10px;.
CuddleBunny

@ Çalışmalar: yerine borderayarlanmalıdırnone0
Mark

@mark, border:0;olduğu gibi geçerlidir border:none;. Bakınız: stackoverflow.com/questions/2922909/…
Besworks

23

@Oriol ne yazık ki, Ekim 2017 itibariyle, mükemmel bir cevabı vardır, ne display:contents, ne page-break-afterölçüde destekleniyor, o kadar iyi bu ancak diğer oyuncular destekler Firefox hakkında söyledi, ben ile gelip var şu daha iyi sert daha düşünün hangi "kesmek" her 3 öğeden sonra bir mola kodlama, çünkü bu sayfa mobil dostu yapmak çok zor hale getirecektir.

Dediğim gibi bu bir hack ve dezavantajı hiçbir şey için oldukça fazla ekstra öğeleri eklemek gerekir, ama hile yapar ve hatta tarihli IE11 çapraz tarayıcı çalışır.

"Hack", her div'den sonra ek bir öğe eklemektir; bu, display:nonecss'den nth-childhangisinin gerçekte böyle bir çizgi frenini zorlayarak görünür kılınacağına karar vermek için css kullanılır :

.container {
  background: tomato;
  display: flex;
  flex-flow: row wrap;
  justify-content: space-between;
}
.item {
  width: 100px;
  background: gold;
  height: 100px;
  border: 1px solid black;
  font-size: 30px;
  line-height: 100px;
  text-align: center;
  margin: 10px
}
.item:nth-child(3n-1) {
  background: silver;
}
.breaker {display:none;}
.breaker:nth-child(3n) {
  display:block;
  width:100%;
  height:0;
 }
<div class="container">
  <div class="item">1</div><p class=breaker></p>
  <div class="item">2</div><p class=breaker></p>
  <div class="item">3</div><p class=breaker></p>
  <div class="item">4</div><p class=breaker></p>
  <div class="item">5</div><p class=breaker></p>
  <div class="item">6</div><p class=breaker></p>
  <div class="item">7</div><p class=breaker></p>
  <div class="item">8</div><p class=breaker></p>
  <div class="item">9</div><p class=breaker></p>
  <div class="item">10</div><p class=breaker></p>
</div>


2
Ayrıca "display: content" ve "page-break-after" yöntemlerinin çalışmadığını ve bu "hack" e başvurulduğunu gördüm. Bu bir Chrome hatası olarak bildirildi ve "WontFix" olarak işaretlendi (bkz. Bugs.chromium.org/p/chromium/issues/detail?id=473481 ): "CSS Çalışma Grubu'na göre, hayır CSS ile esnek bir kutuda satır sonunu zorlamanın geçerli yolu. "
Martin_W

Seçiciyi kullanarak bir karmaşa dokunuşu kaydedebilirsiniz .container>p. Sonra tüm bu <p></p>etiketlerin classözelliğe ihtiyacı olmaz . Elbette önemli değil . Sadece tembel beynim akıllı çözümün için küçük, yerden tasarruf sağlayan bir ayar buluyor. Tabii ki, kullanıcının başka<p> doğrudan alt öğesi olarak etikete.container . Teknik olarak tüm diğer aynı yapabileceğini <div>çocuklar, ama sen başka olması daha muhtemel bir çok <div>olduğundan da .containersizden daha <p>s, bu yüzden muhtemelen bir akıllı hareket var.
Steve

13

Anlamsal bir çizgi patlaması mı istiyorsunuz?

Sonra kullanmayı düşünün <br>. W3Schools size BRsadece şiirler yazmak için olduğunu önerebilir (yakında benim olacak), ancak içeriğinizi bir sonraki satıra itecek% 100 genişlikli bir blok öğesi olarak davranacak şekilde değiştirebilirsiniz. 'Br' bir mola önerirse, benim için kullanmaktan daha uygun görünüyor hrveya% 100div ve html'yi daha okunabilir hale getiriyor.

<br>Çizgilere ihtiyaç duyduğunuz yere ekleyin ve bu şekilde şekillendirin.

 // Use `>` to avoid styling `<br>` inside your boxes 
 .container > br 
 {
    width: 100%;
    content: '';
 }

Sen edebilirsiniz devre dışı <br>medya sorgu ile ayarlayarak, display:hiç blockveyanone uygun olarak (bu bir örnek yer verdik ama dışarı yorumladı sol).

Kullanabilirsiniz order:Gerekirse siparişi ayarlamak için .

Ve farklı sınıflar veya isimlerle istediğiniz kadar koyabilirsiniz :-)

.container {
  background: tomato;
  display: flex;
  flex-flow: row wrap;
  justify-content: space-between;
}
.item {
  width: 100px;
  background: gold;
  height: 100px;
  border: 1px solid black;
  font-size: 30px;
  line-height: 100px;
  text-align: center;
  margin: 10px
}

.container > br
{
  width: 100%;
  content: '';
}

// .linebreak1 
// { 
//    display: none;
// }

// @media (min-width: 768px) 
// {
//    .linebreak1
//    {
//       display: block;
//    }
// }
<div class="container">
  <div class="item">1</div>
  <div class="item">2</div>
  <br class="linebreak1"/>
  <div class="item">3</div>
  <div class="item">4</div>
  <div class="item">5</div>
  <div class="item">6</div>
  <div class="item">7</div>
  <div class="item">8</div>
  <div class="item">9</div>
  <div class="item">10</div>
</div>


Kendinizi W3Schools'un söyledikleriyle sınırlandırmanıza gerek yok:

resim açıklamasını buraya girin


Tekniğin bir uzantısı her üç <br class="2col">maddeden <br class="3col">sonra , üçte birinden sonra konulmasıdır . Ardından cols-2, kapsayıcıya bir sınıf uygulayın ve yalnızca bu sayıda sütun için uygun satır aralıklarını etkinleştirmek üzere css oluşturun. Örneğin. br { display: none; } .cols-2 br.2col { display: block; }
Simon_Weaver

Hayır, a brsatır kesen öğeler için değildir , metin içindir : developer.mozilla.org/en-US/docs/Web/HTML/Element/br ... stackoverflow.com/questions/3937515/…
Ason

2
Bunu mükemmel bir çözüm olarak sunmamak için ifadelerimi değiştireceğim, ancak bazı durumlarda bunu diğer div veya sözde öğe çözümlerinden daha kötü olarak görmüyorum. Belki şimdi bunun hakkında bir şiir yazacağım.
Simon_Weaver

Evet ... bir şiir iyi olurdu, buraya bir bağlantı göndermeyi unutmayın :) ... Mükemmel bir çözümle ilgili olarak, ( break-*kabul edilen cevapta gösterilen) var, ancak ne yazık ki henüz çapraz tarayıcılara ulaşmadı bu nedenle ikinci en iyisi, ebeveyninin genişliğini yerel olarak dolduran ve sonraki kardeşleri tekrar kabul edilen cevapta verilen bir sıraya iten bir eleman kullanmaktır. Yani bir bloktan başka herhangi bir eleman kullanmak, semantik olarak, daha kötü olurdu br.
Ason

5
Unutmayın, W3C yerine W3Schools'un bir baskısını gönderiyorsunuz, bunlar bağlı değil.
Edu Ruiz

7

Geleneksel yolun esnek ve anlaşılması oldukça kolay olduğunu düşünüyorum:

Biçimlendirme

<div class="flex-grid">
    <div class="col-4">.col-4</div>
    <div class="col-4">.col-4</div>
    <div class="col-4">.col-4</div>

    <div class="col-4">.col-4</div>
    <div class="col-4">.col-4</div>
    <div class="col-4">.col-4</div>

    <div class="col-3">.col-3</div>
    <div class="col-9">.col-9</div>

    <div class="col-6">.col-6</div>
    <div class="col-6">.col-6</div>
</div>

Grid.css dosyası oluşturun :

.flex-grid {
  display: flex;
  flex-flow: wrap;
}

.col-1 {flex: 0 0 8.3333%}
.col-2 {flex: 0 0 16.6666%}
.col-3 {flex: 0 0 25%}
.col-4 {flex: 0 0 33.3333%}
.col-5 {flex: 0 0 41.6666%}
.col-6 {flex: 0 0 50%}
.col-7 {flex: 0 0 58.3333%}
.col-8 {flex: 0 0 66.6666%}
.col-9 {flex: 0 0 75%}
.col-10 {flex: 0 0 83.3333%}
.col-11 {flex: 0 0 91.6666%}
.col-12 {flex: 0 0 100%}

[class*="col-"] {
  margin: 0 0 10px 0;

  -webkit-box-sizing: border-box;
  -moz-box-sizing: border-box;
  box-sizing: border-box;
}

@media (max-width: 400px) {
  .flex-grid {
    display: block;
  }
}

Bir ... oluşturdum örnek (jsfiddle)

Pencereyi 400 pikselin altında yeniden boyutlandırmaya çalışın, duyarlı!


Bu çözümde elementler bir arada, fikir aralarında uzun bir boşluk bırakmak.
Juanma Menendez

2

Fazladan işaretleme eklemeyi gerektirmeyen bir diğer olası çözüm, öğeleri ayırmak için dinamik bir kenar boşluğu eklemektir.

Örnek olması durumunda, bu calc()sadece 3n + 2 elemanının (2, 5, 8) eklenmesi margin-leftve eklenmesiyle yapılabilir.margin-right

.item:nth-child(3n+2) {
  background: silver;
  margin: 10px calc(50% - 175px);
}

Snippet Örneği

.container {
  background: tomato;
  display: flex;
  flex-flow: row wrap;
  align-content: space-between;
  justify-content: space-between;
}
.item {
  width: 100px;
  height: 100px;
  background: gold;
  border: 1px solid black;
  font-size: 30px;
  line-height: 100px;
  text-align: center;
  margin: 10px;
}
.item:nth-child(3n+2) {
  background: silver;
  margin: 10px calc(50% - 175px);
}
<div class="container">
  <div class="item">1</div>
  <div class="item">2</div>
  <div class="item">3</div>
  <div class="item">4</div>
  <div class="item">5</div>
  <div class="item">6</div>
  <div class="item">7</div>
  <div class="item">8</div>
  <div class="item">9</div>
  <div class="item">10</div>
</div>


1
Bu bir oylamayı hak ediyor. Esneklik ve kenar boşluğu kombinasyonunu kullanmak satır sonlarını desteklemenin gerçekten basit bir yoludur. Ayrıca calcbu cevapta belirtildiği gibi gerçekten iyi çalışıyor .
stwilz

Bunu daha iyi seviyorum, sadece margin-right: 1pxöğe ve sonraki öğenin yeni bir satırda başlamasını sağlayacak.
arvil

0

Gelecek sorularınız için, bunu kullanarak da yapmak mümkündür. float bunu her 3 öğede de özelliği ve temizleyerek .

İşte yaptığım bir örnek.

.grid {
  display: inline-block;
}

.cell {
  display: inline-block;
  position: relative;
  float: left;
  margin: 8px;
  width: 48px;
  height: 48px;
  background-color: #bdbdbd;
  font-family: 'Helvetica', 'Arial', sans-serif;
  font-size: 14px;
  font-weight: 400;
  line-height: 20px;
  text-indent: 4px;
  color: #fff;
}

.cell:nth-child(3n) + .cell {
  clear: both;
}
<div class="grid">
  <div class="cell">1</div>
  <div class="cell">2</div>
  <div class="cell">3</div>
  <div class="cell">4</div>
  <div class="cell">5</div>
  <div class="cell">6</div>
  <div class="cell">7</div>
  <div class="cell">8</div>
  <div class="cell">9</div>
  <div class="cell">10</div>
</div>


3
Buradaki OP, çözümün flexbox kullanması gerektiğini belirtiyor ya da display: flex;değildisplay: inline-block;
bafromca

1
.cell:nth-child(3n + 1)bunun yerine yazabilirsiniz
Si7ius

-1

Burada birkaç cevap denedim ve hiçbiri işe yaramadı. İronik bir şekilde, işe yarayan <br/>bir kişinin en basit alternatifi hakkındaydı :

<div style="flex-basis: 100%;"></div>

ya da şunları da yapabilirsiniz:

<div style="width: 100%;"></div>

Bunu yeni bir satır istediğiniz yere yerleştirin. Bitişik olanlarla bile çalışıyor gibi görünüyor <span>, ama bitişik olanlarla kullanıyorum <div>.


2
% 100 genişlikli div'ler, kabul edilen cevapta verilen ilk çözümdür.
TylerH

1
Doğru, bir çeşit. Kötü bir nedenden dolayı aşağı bakıyorlar (çirkin, gerçekten mi?). Ayrıca cevabım da var flex-basis.
Andrew

-4

.container {
  background: tomato;
  display: flex;
  flex-flow: row wrap;
  align-content: space-between;
  justify-content: space-between;
}

.item {
  width: 100px;
  height: 100px;
  background: gold;
  border: 1px solid black;
  font-size: 30px;
  line-height: 100px;
  text-align: center;
  margin: 10px;
}
<div class="container">
  <div>
    <div class="item">1</div>
    <div class="item">2</div>
    <div class="item">3</div>
  </div>
  <div>
    <div class="item">4</div>
    <div class="item">5</div>
    <div class="item">6</div>
  </div>
  <div>
    <div class="item">7</div>
    <div class="item">8</div>
    <div class="item">9</div>
  </div>
  <div class="item">10</div>
</div>

öğeleri burada olduğu gibi bir dom öğesinde sarmayı deneyebilirsiniz. bu ile sadece iyi bir yapıya sahip sorunu çözecek css bir sürü bilmek zorunda değilsiniz.


1
Konteyneri normal display: blockhale getirebilir ve bu yeni katman 2 divs flexbox'larını yapabilirsiniz. Bu satırlar için geçerlidir. Sütun modunu kullanırken div değerlerini açıklıklarla değiştirin.
jiggunjer
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.