Flexbox: Satır başına 4 ürün


261

Sayfamla dinamik olarak yeniden boyutlandırılacak 8 öğeyi görüntülemek için bir esnek kutu kullanıyorum. Öğeleri iki satıra bölmeye nasıl zorlarım? (Sıra başına 4)?

Alakalı bir ekran alıntısı:

(Veya jsfiddle'ı tercih ederseniz - http://jsfiddle.net/vivmaha/oq6prk1p/2/ )

.parent-wrapper {
  height: 100%;
  width: 100%;
  border: 1px solid black;
}
.parent {
  display: flex;
  font-size: 0;
  flex-wrap: wrap;
  margin: -10px 0 0 -10px;
}
.child {
  display: inline-block;
  background: blue;
  margin: 10px 0 0 10px;
  flex-grow: 1;
  height: 100px;
}
<body>
  <div class="parent-wrapper">
    <div class="parent">
      <div class="child"></div>
      <div class="child"></div>
      <div class="child"></div>
      <div class="child"></div>
      <div class="child"></div>
      <div class="child"></div>
      <div class="child"></div>
      <div class="child"></div>
    </div>
  </div>
</body>


16
[Güncelleme] Bu soru yanıt vermeyen zayıf bir tasarıma dayanıyordu. Aşağıdaki cevaplardan birini kullanarak kendinizi bulursanız dikkatli olun. İyi bir tasarımda, daha geniş ekranlarda daha fazla, daha küçük ekranlarda daha az öğe olur. Tüm ekran boyutları için 4 öğeyi zorlamak, yalnızca dar ekran genişliklerinde çekici görünecektir.
Vivek Maharajh

Yanıtlar:


384

Sen var flex-wrap: wrapkonteyner üzerinde. Bu iyidir, çünkü nowrap( kaynak ) olan varsayılan değeri geçersiz kılar . Öğelerin bazı durumlarda bir ızgara oluşturmak için sarılmamasının nedeni budur .

Bu durumda, ana sorun flex-grow: 1esnek ürünlerdir.

flex-growMülkiyet aslında boyutu esnek öğeleri yok. Görevi, kapta ( kaynak ) boş alan dağıtmaktır . Ekran boyutu ne kadar küçük olursa olsun, her öğe satırdaki boş alanın oransal bir kısmını alacaktır.

Daha spesifik olarak, kabınızda sekiz esnek öğe vardır. İle flex-grow: 1, her biri hatta boş alanın 1 / 8'ini alır. Öğelerinizde içerik olmadığından, sıfır genişliğe daralabilir ve hiçbir zaman sarılmaz.

Çözüm, öğeler üzerinde bir genişlik tanımlamaktır. Bunu dene:

.parent {
  display: flex;
  flex-wrap: wrap;
}

.child {
  flex: 1 0 21%; /* explanation below */
  margin: 5px;
  height: 100px;
  background-color: blue;
}
<div class="parent">
  <div class="child"></div>
  <div class="child"></div>
  <div class="child"></div>
  <div class="child"></div>
  <div class="child"></div>
  <div class="child"></div>
  <div class="child"></div>
  <div class="child"></div>
</div>

Kısayolda flex-grow: 1tanımlandığında, % 25 olmasına flexgerek yoktur flex-basis, bu da marjlar nedeniyle satır başına üç öğeye neden olur.

Yana flex-growsatırda boş alan tüketir, flex-basissadece bir şal zorlamak için yeterince büyük olması gerekir. Bu durumda, flex-basis: 21%kenar boşlukları için bolca alan var, ancak beşinci bir öğe için asla yeterli alan yok.


1
Bunu sevdim çünkü benim için çalıştı, ama “bol alan” beni biraz tedirgin ediyor. Bu “tahminin” başarısız olabileceği küçük bir pencere veya durum var mı?
Jackson

1
Ne tür bir durum? Çoğu düzende sorun yaratabilecek aşırı durumlar vardır. Bu tür vakalar normalde maliyet-fayda analizleriyle seyreder çünkü asla veya neredeyse hiç gerçekleşmezler. Örneğin, yukarıdaki çözümde, çok büyük kenar boşlukları koyarsanız, düzen bozulabilir. Bu bir sorunsa, soruya gönderilmelidir. @Jackson
Michael Benjamin

2
“Çok büyük kenar boşlukları koyarsanız, düzen bozulabilir” Bu, kaçınmak istediğim bir senaryo örneği. Pratikliği umursamıyorum; mükemmellik için hayranlığımı eğlendirmek. Daha kesin olmanın bir yolu var mı?
Jackson

27
Ayrıca kullanabilirsinizflex: 1 0 calc(25% - 10px);
MarkG

2
Mükemmel cevap! Kullandığım küçük bir iyileştirme margin: 2%;, kutuların küçük cihazlarda / çözünürlüklerde yeni bir satıra atlamasını önlemek için sabit piksel sayısı yerine. genel formül (100 - (4 * box-width-percent)) / 8farklı kutu genişlikleri için% 'dir
thomaspsk

104

Öğelere bir genişlik ekleyin .child. Şahsen margin-lefther satırda 4 olmasını istiyorsanız yüzdeleri kullanırdım .

DEMO

.child {
    display: inline-block;
    background: blue;
    margin: 10px 0 0 2%;
    flex-grow: 1;
    height: 100px;
    width: calc(100% * (1/4) - 10px - 1px);
}

İyi bir fikir. Bu fikri küçük düzenlemelerle kullandım. jsfiddle.net/vivmaha/oq6prk1p/6
Vivek Maharajh

1
Ah. Bu aslında sorunumu çözmüyor. Bir örnek için buraya bakın: jsfiddle.net/vivmaha/oq6prk1p/7 . Marjım için yüzdeleri kullanma özgürlüğüm yok. Sabit bir genişlikte olmalıdırlar. Bu, seçtiğimiz sihir% 23'ün sabit marjı dikkate almadığı için işe yaramayacağı anlamına gelir.
Vivek Maharajh

3
Evet, kireç çözer! "kalk (% 100 * (1/4) - 10 piksel - 1 piksel)". Bkz. Jsfiddle.net/vivmaha/oq6prk1p/9
Vivek Maharajh

24
Öyleyse bu konuda esnekliğin ne faydası var?
twicejr

Duyarlı tasarıma ne dersiniz? Çocuğa sabit bir genişlik koymak istemiyoruz
Candlejack

40

İşte başka bir takdir.

Bunu şu şekilde de yapabilirsiniz:

.parent{
  display: flex;
  flex-wrap: wrap;
}

.child{
  width: 25%;
  box-sizing: border-box;
}

Örnek: https://codepen.io/capynet/pen/WOPBBm

Ve daha eksiksiz bir örnek: https://codepen.io/capynet/pen/JyYaba


1
4 yaşından küçük çocuğum varsa ne olur? Boş boş alandan hoşlanmıyorum, çocuk cevap vermiyor ...
Candlejack

Muddasir Abbas'ın diğer cevabı sadece esnek ayarları kullanıyor, bu yüzden daha temiz bir çözüm olduğunu düşünüyorum.
Andrew Koster

17

Ben olukları için negatif kenar boşlukları ve kalk kullanarak bu şekilde yapardı:

.parent {
  display: flex;
  flex-wrap: wrap;
  margin-top: -10px;
  margin-left: -10px;
}

.child {
  width: calc(25% - 10px);
  margin-left: 10px;
  margin-top: 10px;
}

Demo: https://jsfiddle.net/9j2rvom4/


Alternatif CSS Izgara Yöntemi:

.parent {
  display: grid;
  grid-template-columns: repeat(4, 1fr);
  grid-column-gap: 10px;
  grid-row-gap: 10px;
}

Demo: https://jsfiddle.net/jc2utfs3/


14
<style type="text/css">
.parent{
    display: flex;
    flex-wrap: wrap;
}
.parent .child{
    flex: 1 1 25%;
}
</style>    
<div class="parent">
      <div class="child"></div>
      <div class="child"></div>
      <div class="child"></div>
      <div class="child"></div>
      <div class="child"></div>
      <div class="child"></div>
      <div class="child"></div>
      <div class="child"></div>
    </div>

Umarım yardımcı olur. daha fazla ayrıntı için bu bağlantıyı takip edebilirsiniz


4

Bence bu örnek daha fazla barebone ve anlaşılması daha kolay @dowomenfart.

.child {
    display: inline-block;
    margin: 0 1em;
    flex-grow: 1;
    width: calc(25% - 2em);
}

Bu, doğrudan ete kesim yaparken aynı genişlik hesaplamalarını gerçekleştirir. Matematik kolay bir yoludur ve embir yeni standart nedeniyle ölçeklenebilirlik ve mobil uyumluluğu için.


3
em gerçekten yeni bir standart değil. Eşekte bir acı olabilir ve tasarımcılar EM'leri düşünerek tasarlamazlar.
Danny van Holten

2

.parent-wrapper {
	height: 100%;
	width: 100%;
	border: 1px solid black;
}
	.parent {
	display: flex;
	font-size: 0;
	flex-wrap: wrap;
	margin-right: -10px;
	margin-bottom: -10px;
}
	.child {
	background: blue;
	height: 100px;
	flex-grow: 1;
	flex-shrink: 0;
	flex-basis: calc(25% - 10px);
}
	.child:nth-child(even) {
	margin: 0 10px 10px 10px;
	background-color: lime;
}
	.child:nth-child(odd) {
	background-color: orange; 
}
<!DOCTYPE html>
<html lang="en">
<head>
	<meta charset="UTF-8">
	<title>Document</title>
	<style type="text/css">

	</style>
</head>
<body>
  <div class="parent-wrapper">
    <div class="parent">
      <div class="child"></div>
      <div class="child"></div>
      <div class="child"></div>
      <div class="child"></div>
      <div class="child"></div>
      <div class="child"></div>
      <div class="child"></div>
      <div class="child"></div>
    </div>
  </div>
</body>
</html>

;)


1
Lütfen bunun neden sadece kod göndermek yerine OP sorusuna cevap verdiğine dair bir bağlam ekleyebilirsiniz.
d219

Eğer justify-content: space-evenly;prime eklerseniz, o zaman güzel hizalarlar calcve çocuğa yapmak zorunda değilsiniz . Yine de örnek için teşekkürler!
Mattijs

0

Esnek sarma + negatif kenar boşluğu

Neden esnektir display: inline-block?

Neden negatif kâr marjı?

Kenar senaryoları için SCSS veya CSS-in-JS kullanırsınız (yani sütundaki ilk öğe) veya varsayılan bir kenar boşluğu ayarlayıp daha sonra dış kenar boşluğundan kurtulursunuz.

uygulama

https://codepen.io/zurfyx/pen/BaBWpja

<div class="outerContainer">
    <div class="container">
        <div class="elementContainer">
            <div class="element">
            </div>
        </div>
        ...
    </div>
</div>
:root {
  --columns: 2;
  --betweenColumns: 20px; /* This value is doubled when no margin collapsing */
}

.outerContainer {
    overflow: hidden; /* Hide the negative margin */
}

.container {
    background-color: grey;
    display: flex;
    flex-wrap: wrap;
    margin: calc(-1 * var(--betweenColumns));
}

.elementContainer {
    display: flex; /* To prevent margin collapsing */
    width: calc(1/var(--columns) * 100% - 2 * var(--betweenColumns));
    margin: var(--betweenColumns);
}

.element {
    display: flex;
    border: 1px solid red;
    background-color: yellow;
    width: 100%;
    height: 42px;
}

-12

İşte kullanmadan başka bir yol calc().

// 4 PER ROW
// 100 divided by 4 is 25. Let's use 21% for width, and the remainder 4% for left & right margins...
.child {
  margin: 0 2% 0 2%;
  width: 21%;
}

// 3 PER ROW
// 100 divided by 3 is 33.3333... Let's use 30% for width, and remaining 3.3333% for sides (hint: 3.3333 / 2 = 1.66666)
.child {
  margin: 0 1.66666% 0 1.66666%;
  width: 30%;
}

// and so on!

Hepsi bu kadar. Daha estetik boyutlar elde etmek için boyutlarla süslenebilirsiniz, ancak bu fikir.


6
Bunu test etmedim, ancak CSS sözdizimi yanlış (CSS değerleri alıntılanmadı ve bildirimler noktalı virgülle bitmeli), bu yüzden kesinlikle geçerli biçiminde çalışmayacak.
Nick F
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.