Betere manier om de afstand tussen flexbox-items in te stellen

Om de minimale afstand tussen flexbox-items in te stellen, gebruik ik margin: 0 5px op .item en margin: 0 -5px op container. Voor mij lijkt het een hack, maar ik kan geen betere manier vinden om dit te doen.

Voorbeeld

#box {
  display: flex;
  width: 100px;
  margin: 0 -5px;
}
.item {
  background: gray;
  width: 50px;
  height: 50px;
  margin: 0 5px;
}
<div id='box'>
    <div class='item'></div>
    <div class='item'></div>
    <div class='item'></div>
    <div class='item'></div>
</div>

Antwoord 1, autoriteit 100%

  • Flexbox heeft geen inklapbare marges.
  • Flexbox heeft niets dat lijkt op border-spacing voor tabellen (edit: CSS-eigenschap gap vervult deze rol in nieuwere browsers, Kan ik gebruiken)

Daarom is het wat moeilijker om te bereiken waar je om vraagt.

Naar mijn ervaring is dit de “schoonste” manier die geen gebruik maakt van :first-child/:last-child en zonder enige wijziging werkt op flex-wrap:wrap is om padding:5px in te stellen op de container en margin:5px op de kinderen. Dat levert een kloof van 10px op tussen elk kind en tussen elk kind en hun ouder.

Demo

.upper {
  margin: 30px;
  display: flex;
  flex-direction: row;
  width: 300px;
  height: 80px;
  border: 1px red solid;
  padding: 5px; /* this */
}
.upper > div {
  flex: 1 1 auto;
  border: 1px red solid;
  text-align: center;
  margin: 5px;  /* and that, will result in a 10px gap */
}
.upper.mc /* multicol test */ {
  flex-direction: column;
  flex-wrap: wrap;
  width: 200px;
  height: 200px;
}
<div class="upper">
  <div>aaa<br/>aaa</div>
  <div>aaa</div>
  <div>aaa<br/>aaa</div>
  <div>aaa<br/>aaa<br/>aaa</div>
  <div>aaa</div>
  <div>aaa</div>
</div>
<div class="upper mc">
  <div>aaa<br/>aaa</div>
  <div>aaa</div>
  <div>aaa<br/>aaa</div>
  <div>aaa<br/>aaa<br/>aaa</div>
  <div>aaa</div>
  <div>aaa</div>
</div>

Antwoord 2, autoriteit 43%

Dit is geen hack.
Dezelfde techniek wordt ook gebruikt door bootstrap en zijn raster, maar in plaats van marge gebruikt bootstrap opvulling voor zijn cols.

.row {
  margin:0 -15px;
}
.col-xx-xx {
  padding:0 15px;
}

Antwoord 3, autoriteit 27%

Flexbox en css calc met ondersteuning voor meerdere rijen

Hallo, hieronder is mijn werkende oplossing voor alle browsers die flexbox ondersteunen. Geen negatieve marges.

Fiddle-demo

   
.flexbox {
  display: flex;
  flex-direction: row;
  flex-wrap: wrap;
  justify-content: space-between;
}
.flexbox > div {
  /*
    1/3  - 3 columns per row
    10px - spacing between columns 
  */
  box-sizing: border-box;
  margin: 10px 10px 0 0;
  outline: 1px dotted red;
  width: calc(1/3*100% - (1 - 1/3)*10px);
}
/*
  align last row columns to the left
  3n - 3 columns per row
*/
.flexbox > div:nth-child(3n) {
  margin-right: 0;
}
.flexbox::after {
  content: '';
  flex: auto;
}
/*
  remove top margin from first row
  -n+3 - 3 columns per row 
*/
.flexbox > div:nth-child(-n+3) {
  margin-top: 0;
}
<div class="flexbox">
  <div>col</div>
  <div>col</div>
  <div>col</div>
  <div>col</div>
  <div>col</div>
</div>

Antwoord 4, autoriteit 26%

U kunt & > * + * als selector om een ​​flex-gap te emuleren (voor een enkele regel):

#box { display: flex; width: 230px; outline: 1px solid blue; }
.item { background: gray; width: 50px; height: 100px; }
/* ----- Flexbox gap: ----- */
#box > * + * {
  margin-left: 10px;
}
<div id='box'>
    <div class='item'></div>
    <div class='item'></div>
    <div class='item'></div>
    <div class='item'></div>
</div>

Antwoord 5, autoriteit 25%

CSS gap eigenschap:

Er is een nieuwe gap CSS-eigenschap voor lay-outs met meerdere kolommen, flexboxen en rasters die nu in nieuwere browsers werken! (Zie Kan ik link 1 gebruiken; link 2). Het is een afkorting voor row-gap en column-gap.

#box {
  display: flex;
  flex-wrap: wrap;
  width: 200px;
  background-color: red;
  gap: 10px;
}
.item {
  background: gray;
  width: 50px;
  height: 50px;
  border: 1px black solid;
}
<div id='box'>
    <div class='item'></div>
    <div class='item'></div>
    <div class='item'></div>
    <div class='item'></div>
</div>

Antwoord 6, autoriteit 18%

U kunt transparante randen gebruiken.

Ik heb dit probleem overwogen toen ik probeerde een flex grid-model te bouwen dat kan terugvallen op een tabellen + table-cell-model voor oudere browsers. En Borders voor kolomgoten leek mij de meest geschikte keuze. d.w.z. tabelcellen hebben geen marges.

bijv.

.column{
  border-left: 5px solid transparent;
  border-right: 5px solid transparent;
  border-bottom: 10px solid transparent;
}

Houd er ook rekening mee dat je min-width: 50px; nodig hebt voor flexbox. Het flex-model kan geen vaste maten aan tenzij u flex: none; doet op het specifieke onderliggende element dat u als vast wilt hebben en daarom wordt uitgesloten van het zijn van "flexi". http://jsfiddle.net/GLpUp/4/
Maar alle kolommen samen met flex:none; is niet langer een flexmodel.
Hier is iets dat meer in de buurt komt van een flexmodel: http://jsfiddle.net/GLpUp/5/

Je kunt marges dus normaal gebruiken als je de table-cell fallback voor oudere browsers niet nodig hebt. http://jsfiddle.net/GLpUp/3/

Het instellen van background-clip: padding-box; is nodig bij gebruik van een achtergrond, omdat de achtergrond anders in het transparante randgebied zal vloeien.


Antwoord 7, autoriteit 15%

Deze oplossing werkt in alle gevallen, zelfs als er meerdere rijen of een willekeurig aantal elementen zijn. Maar het aantal van de sectie zou hetzelfde moeten zijn als je wilt 4 in de eerste rij en 3 is de tweede rij, zo werkt het niet, de ruimte voor de 4e inhoud zal leeg zijn, de container zal niet vullen.

We gebruiken display: grid; en zijn eigenschappen.

#box {
  display: grid;
  width: 100px;
  grid-gap: 5px;
  /* Space between items */
  grid-template-columns: 1fr 1fr 1fr 1fr;
  /* Decide the number of columns and size */
}
.item {
  background: gray;
  width: 100%;
  /* width is not necessary only added this to understand that width works as 100% to the grid template allocated space **DEFAULT WIDTH WILL BE 100%** */
  height: 50px;
}
<div id='box'>
  <div class='item'></div>
  <div class='item'></div>
  <div class='item'></div>
  <div class='item'></div>
  <div class='item'></div>
  <div class='item'></div>
  <div class='item'></div>
  <div class='item'></div>
</div>

Antwoord 8, autoriteit 6%

Laten we zeggen dat als u 10px ruimte tussen de items wilt instellen, u gewoon .item {margin-right:10px;} voor iedereen kunt instellen en deze opnieuw kunt instellen op de laatste .item:last-child {margin-right:0;}

U kunt ook algemene broer/zus ~ of volgende + broer/zus selector gebruiken om de linkermarge op de items in te stellen, behalve de eerste .item ~ .item {margin-left:10px;} of gebruik .item:not(:last-child) {margin-right: 10px;}

Flexbox is zo slim dat het het raster automatisch herberekent en gelijkmatig verdeelt.

body {
  margin: 0;
}
.container {
  display: flex;
}
.item {
  flex: 1;
  background: gray;
  height: 50px;
}
.item:not(:last-child) {
  margin-right: 10px;
}
<div class="container">
  <div class="item"></div>
  <div class="item"></div>
  <div class="item"></div>
  <div class="item"></div>
</div>

Antwoord 9, autoriteit 4%

Update: gap voor flexbox wordt nu ondersteund in alle moderne browsers (Edge/Chrome/Opera/Samsung Internet/Safari/Firefox)

Uiteindelijk zullen ze de eigenschap gap aan flexbox toevoegen. Tot die tijd zou je in plaats daarvan een CSS-raster kunnen gebruiken dat al de eigenschap gap heeft en slechts één rij heeft. Leuker dan omgaan met marges.


Antwoord 10, autoriteit 3%

Ik heb een oplossing gevonden die is gebaseerd op de algemene selector voor broers en zussen, ~, en die oneindige nesting mogelijk maakt.

Bekijk deze codepen voor een werkend voorbeeld

Kortom, binnen kolomcontainers krijgt elk kind dat wordt voorafgegaan door een ander kind een bovenmarge. Evenzo krijgt binnen elke rijcontainer elk kind dat wordt voorafgegaan door een ander een linkermarge.

.box {
  display: flex;
  flex-grow: 1;
  flex-shrink: 1;
}
.box.columns {
  flex-direction: row;
}
.box.columns>.box~.box {
  margin-left: 5px;
}
.box.rows {
  flex-direction: column;
}
.box.rows>.box~.box {
  margin-top: 5px;
}
<div class="box columns">
  <div class="box" style="background-color: red;"></div>
  <div class="box rows">
    <div class="box rows">
      <div class="box" style="background-color: blue;"></div>
      <div class="box" style="background-color: orange;"></div>
      <div class="box columns">
        <div class="box" style="background-color: yellow;"></div>
        <div class="box" style="background-color: pink;"></div>
      </div>
    </div>
    <div class="box" style="background-color: green;"></div>
  </div>
</div>

Antwoord 11, autoriteit 3%

Volgens #ChromeDevSummit is er een implementatie van de eigenschap gap voor Flexbox in Firefox en Chromium-gebaseerde browsers.

Hier is een Live Demo


Antwoord 12, autoriteit 3%

Voortgaand op het antwoord van sawa, hier is een licht verbeterde versie waarmee u een vaste afstand tussen de items kunt instellen zonder de omringende marge.

http://jsfiddle.net/chris00/s52wmgtq/49/

Ook inbegrepen is de Safari “-webkit-flex” versie.

.outer1 {
    background-color: orange;
    padding: 10px;
}
.outer0 {
    background-color: green;
    overflow: hidden;
}
.container
{
    display: flex;
    display: -webkit-flex;
    flex-wrap: wrap;    
    -webkit-flex-wrap: wrap;
    background-color: rgba(0, 0, 255, 0.5);
    margin-left: -10px;
    margin-top: -10px;
}
.item
{
    flex-grow: 1;
    -webkit-flex-grow: 1;
    background-color: rgba(255, 0, 0, 0.5);
    width: 100px;
    padding: 10px;
    margin-left: 10px;
    margin-top: 10px;
    text-align: center;
    color: white;
}
<div class="outer1">
    <div class="outer0">
        <div class="container">
            <div class="item">text</div>
            <div class="item">text</div>
            <div class="item">text</div>
            <div class="item">text</div>
            <div class="item">text</div>
            <div class="item">text</div>
        </div>
    </div>
</div>

Antwoord 13, autoriteit 2%

Ik heb dit gebruikt voor ingepakte kolommen en kolommen met een vaste breedte. De sleutel hier is calc()

SCSS-voorbeeld

$gap: 10px;
dl {
  display: flex;
  flex-wrap: wrap;
  padding: $gap/2;
  dt, dd {
    margin: $gap/2;}
  dt { // full width, acts as header
    flex: 0 0 calc(100% - #{$gap});}
  dd { // default grid: four columns 
    flex: 0 0 calc(25% - #{$gap});}
  .half { // hall width columns
    flex: 0 0 calc(50% - #{$gap});}
}

Volledig codepen-voorbeeld


Antwoord 14, autoriteit 2%

Een flex container met -x (negatieve) marge en flex items met x (positieve) marge of opvulling leiden beide tot het gewenste visuele resultaat: Flex-items hebben een vaste afstand van 2x alleen tussen elkaar.

Het lijkt gewoon een kwestie van voorkeur te zijn, of je marge of opvulling wilt gebruiken voor de flex-items.

In dit voorbeeld worden de flex-items dynamisch geschaald om de vaste opening te behouden:

.flex-container { 
  margin: 0 -5px;
  display: flex;
  flex-flow: row wrap;
  justify-content: space-between;
}
.flex-item {
  margin: 0 5px; // Alternatively: padding: 0 5px;
  flex: 1 0 auto;
}

Antwoord 15

Flexbox gebruiken in mijn oplossing Ik heb de eigenschap justify-content gebruikt voor het bovenliggende element (container) en ik heb de marges gespecificeerd binnen de flex-basis eigendom van de artikelen.
Bekijk het codefragment hieronder:

.container {
  display: flex;
  flex-flow: row wrap;
  justify-content: space-around;
  margin-bottom: 10px;
}
.item {
  height: 50px;
  display: flex;
  justify-content: center;
  align-items: center;
  background-color: #999;
}
.item-1-4 {
  flex-basis: calc(25% - 10px);
}
.item-1-3 {
  flex-basis: calc(33.33333% - 10px);
}
.item-1-2 {
  flex-basis: calc(50% - 10px);
}
<div class="container">
  <div class="item item-1-4">1</div>
  <div class="item item-1-4">2</div>
  <div class="item item-1-4">3</div>
  <div class="item item-1-4">4</div>
</div>
<div class="container">
  <div class="item item-1-3">1</div>
  <div class="item item-1-3">2</div>
  <div class="item item-1-3">3</div>
</div>
<div class="container">
  <div class="item item-1-2">1</div>
  <div class="item item-1-2">2</div>
</div>

Antwoord 16

Met flexbox is het maken van goten lastig, vooral als het gaat om inpakken.

U moet negatieve marges gebruiken (zoals weergegeven in de vraag):

#box {
  display: flex;
  width: 100px;
  margin: 0 -5px;
}

… of wijzig de HTML (zoals weergegeven in een ander antwoord):

<div class='flex-wrapper'>
  <div class='flex'>
    <div class='box'></div>
    <div class='box'></div>
            ...
  </div>
</div>

… of iets anders.

In ieder geval heb je een lelijke hack nodig om het te laten werken, omdat flexbox geen “flex-gap“-functie biedt
(althans voorlopig).

Het probleem van dakgoten is echter eenvoudig en gemakkelijk met CSS-rasterlay-out.

De Grid-specificatie biedt eigenschappen die ruimte creëren tussen rasteritems, terwijl de ruimte tussen items en de container wordt genegeerd. Deze eigenschappen zijn:

  • grid-column-gap
  • grid-row-gap
  • grid-gap (de afkorting voor beide eigenschappen hierboven)

Onlangs is de specificatie bijgewerkt om te voldoen aan de CSS Box Alignment Module , dat een set uitlijningseigenschappen biedt voor gebruik in alle boxmodellen. Dus de eigenschappen zijn nu:

  • column-gap
  • row-gap
  • gap (afgekort)

Niet alle Grid-ondersteunende browsers ondersteunen de nieuwere eigenschappen, dus ik gebruik de originele versies in de demo hieronder.

Als er ruimte nodig is tussen items en de container, werkt padding op de container ook prima (zie het derde voorbeeld in de demo hieronder).

Vanaf de specificatie:

10.1. Dakgoten: de row-gap, column-gap en gap
eigenschappen

De eigenschappen row-gap en column-gap (en hun afkorting van gap),
indien gespecificeerd op een rastercontainer, definieer de goten tussen raster
rijen en rasterkolommen. Hun syntaxis is gedefinieerd in CSS Box Alignment 3
8 hiaten tussen dozen
.

Het effect van deze eigenschappen is alsof de betrokken rasterlijnen
verworven dikte: het rasterspoor tussen twee rasterlijnen is de spatie
tussen de goten die hen vertegenwoordigen.

.box {
  display: inline-grid;
  grid-auto-rows: 50px;
  grid-template-columns: repeat(4, 50px);
  border: 1px solid black;
}
.one {
  grid-column-gap: 5px;
}
.two {
  grid-column-gap: 10px;
  grid-row-gap: 10px;
}
.three {
  grid-gap: 10px;
  padding: 10px;
}
.item {
  background: lightgray;
}
<div class='box one'>
  <div class='item'></div>
  <div class='item'></div>
  <div class='item'></div>
  <div class='item'></div>
</div>
<hr>
<div class='box two'>
  <div class='item'></div>
  <div class='item'></div>
  <div class='item'></div>
  <div class='item'></div>
  <div class='item'></div>
  <div class='item'></div>
  <div class='item'></div>
  <div class='item'></div>
</div>
<hr>
<div class='box three'>
  <div class='item'></div>
  <div class='item'></div>
  <div class='item'></div>
  <div class='item'></div>
  <div class='item'></div>
  <div class='item'></div>
  <div class='item'></div>
  <div class='item'></div>
</div>

Antwoord 17

Waarom doe je het niet zo:

.item + .item {
    margin-left: 5px;
}

Hiermee wordt de aangrenzende broer of zus-selector gebruikt om alle .item elementen, behalve de eerste een margin-left. Dankzij flexbox resulteert dit zelfs in even brede elementen. Dit kan natuurlijk ook met verticaal geplaatste elementen en margin-top.


Antwoord 18

Hier is mijn oplossing, waarvoor geen klassen op de onderliggende elementen hoeven te worden ingesteld:

.flex-inline-row {
    display: inline-flex;
    flex-direction: row;
}
.flex-inline-row.flex-spacing-4px > :not(:last-child) {
    margin-right: 4px;
}

Gebruik:

<div class="flex-inline-row flex-spacing-4px">
  <span>Testing</span>
  <span>123</span>
</div>

Dezelfde techniek kan worden gebruikt voor normale flexrijen en kolommen als aanvulling op het bovenstaande inline-voorbeeld, en uitgebreid met klassen voor andere spaties dan 4px.


Antwoord 19

Voor dergelijke gevallen gebruik ik vaak de operator +

#box {
  display: flex;
  width: 100px;
}
.item {
  background: gray;
  width: 50px;
  height: 50px;
}
.item + .item {
    margin-left: 5px;
}
<div id='box'>
    <div class='item'></div>
    <div class='item'></div>
    <div class='item'></div>
    <div class='item'></div>
</div>

Antwoord 20

Ik vind dat de gemakkelijkste manier om dit te doen is met percentages en de marge gewoon te laten kloppen met je breedte

Dit betekent dat je zoiets krijgt als je je voorbeeld gebruikt

#box {
   display: flex;
}
.item {
   flex: 1 1 23%;
   margin: 0 1%;
}

Betekent wel dat je waarden gebaseerd zijn op de breedte, wat misschien niet voor iedereen goed is.


Antwoord 21

Hier is een raster van kaart-UI-elementen met spatiëring voltooid met behulp van een flexibele doos:

voer hier de afbeeldingsbeschrijving in

Ik was gefrustreerd over het handmatig plaatsen van de kaarten door opvulling en marges te manipuleren met dubieus resultaat. Dus hier zijn de combinaties van CSS-kenmerken die ik erg effectief heb gevonden:

.card-container {
  width: 100%;
  height: 900px;
  overflow-y: scroll;
  max-width: inherit;
  background-color: #ffffff;
  /*Here's the relevant flexbox stuff*/
  display: flex;
  flex-direction: row;
  justify-content: center;
  align-items: flex-start;
  flex-wrap: wrap; 
}
/*Supplementary styles for .card element*/
.card {
  width: 120px;
  height: 120px;
  background-color: #ffeb3b;
  border-radius: 3px;
  margin: 20px 10px 20px 10px;
}
<section class="card-container">
        <div class="card">
        </div>
        <div class="card">
        </div>
        <div class="card">
        </div>
        <div class="card">
        </div>
      </section>

Antwoord 22

Columnify – Een soloklasse voor N kolommen

Flexbox en SCSS

.columnify {
  display: flex;
  > * {
    flex: 1;
    &:not(:first-child) {
      margin-left: 2rem;
    }
  }
}

Flexbox en CSS

.columnify {
  display: flex;
}
.columnify > * {
  flex: 1;
}
.columnify > *:not(:first-child) {
  margin-left: 2rem;
}
<div class="columnify">
  <div style="display: inline-block; height: 20px; background-color: blue;"></div>
  <div style="display: inline-block; height: 20px; background-color: blue"></div>
  <div style="display: inline-block; height: 20px; background-color: blue"></div>
</div>

Antwoord 23

Je zou de nieuwe eigenschap gap kunnen gebruiken. Ik kopieer en plak de uitleg die ik in dit artikel heb gevonden, evenals meer informatie

De lay-out van het CSS-raster vertoont al enige tijd een hiaat (voorheen een raster-gap). Door de interne afstand van een bevattend element te specificeren in plaats van de afstand rond onderliggende elementen, lost gap veel veelvoorkomende lay-outproblemen op. Met gap hoeft u zich bijvoorbeeld geen zorgen te maken over marges op onderliggende elementen die ongewenste witruimte rond de randen van een bevattend element veroorzaken:

Helaas ondersteunt momenteel alleen FireFox hiaten in flexibele lay-outs.

@use postcss-preset-env {
  stage: 0;
  browsers: last 2 versions
}
section {
  width: 30vw;
  display: grid;
  gap: 1rem;
  grid-template-columns: repeat(auto-fit, minmax(12ch, 1fr));
  &[flex] {
    display: flex;
    flex-wrap: wrap;
  }
  margin-bottom: 3rem;
}
.tag {
  color: white;
  background: hsl(265 100% 47%);
  padding: .5rem 1rem;
  border-radius: 1rem;
}
button {
  display: inline-flex;
  place-items: center;
  gap: .5rem;
  background: hsl(265 100% 47%);
  border: 1px solid hsl(265 100% 67%);
  color: white;
  padding: 1rem 2rem;
  border-radius: 1rem;
  font-size: 1.25rem;
}
body {
  min-height: 100vh;
  display: flex;
  flex-direction: column;
  justify-content: center;
  align-items: center;
}
<section>
  <h1>Grid</h1> 
  <div class="tag">Awesome</div>
  <div class="tag">Coo</div>
  <div class="tag">Rad</div>
  <div class="tag">Math</div>
</section>
<br>
<section flex>
  <h1>Flex</h1>
  <div class="tag">Awesome</div>
  <div class="tag">Coo</div>
  <div class="tag">Rad</div>
  <div class="tag">Math</div>
</section>

Antwoord 24

#box {
  display: flex;
  width: 100px;
}
.item {
  background: gray;
  width: 50px;
  height: 50px;
}
/* u mean utility */
.u-gap-10 > *:not(:last-child) {
  margin-right: 10px;
}
<div id='box' class="u-gap-10">
  <div class='item'></div>
  <div class='item'></div>
  <div class='item'></div>
  <div class='item'></div>
</div>

Antwoord 25

Gebruik gewoon .item + .item in selector om te matchen vanaf tweede .item

#box {
  display: inline-flex;
  margin: 0 -5px;
}
.item {
  background: gray;
  width: 10px;
  height: 50px;
}
#box .item + .item {
  margin-left: 10px;
}
<div id='box'>
    <div class='item'></div>
    <div class='item'></div>
    <div class='item'></div>
    <div class='item'></div>
</div>

Antwoord 26

Ik heb een hack gevonden omdat ik dit zelf echt nodig heb.

/* grid */
.container {
  display: flex;
  flex-flow: row wrap;
  justify-content: space-between;
}
.container::after, /* this makes sure odd element goes left and not space between */
.item {
  content:"";
  width: calc(33.3333% - 20px);
  margin-bottom: 40px;
}
/* extra styling - not important */
.item {
  height: 100px;
  background: #787878;
}
<div class="container">
  <div class="item"></div>
  <div class="item"></div>
  <div class="item"></div>
  <div class="item"></div>
  <div class="item"></div>
</div>

Antwoord 27

Ervan uitgaande:

  • U wilt een rasterlay-out van 4 kolommen met terugloop
  • Het aantal items is niet noodzakelijk een veelvoud van 4

Stel een linkermarge in op elk item behalve het 1e, 5e, 9e item enzovoort; en stel een vaste breedte in op elk item. Als de linkermarge 10px is, heeft elke rij een marge van 30px tussen 4 items, de procentuele breedte van het item kan als volgt worden berekend:

100% / 4 - horizontal-border - horizontal-padding - left-margin * (4 - 1) / 4

Dit is een goede oplossing voor problemen met de laatste rij flexbox.

.flex {
  display: flex;
  flex-direction: row;
  flex-wrap: wrap;
  margin: 1em 0;
  background-color: peachpuff;
}
.item {
  margin-left: 10px;
  border: 1px solid;
  padding: 10px;
  width: calc(100% / 4 - 2px - 20px - 10px * (4 - 1) / 4);
  background-color: papayawhip;
}
.item:nth-child(4n + 1) {
  margin-left: 0;
}
.item:nth-child(n + 5) {
  margin-top: 10px;
}
<div class="flex">
  <div class="item">1</div>
  <div class="item">2</div>
  <div class="item">3</div>
  <div class="item">4</div>
</div>
<div class="flex">
  <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>
<div class="flex">
  <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>

Antwoord 28

Er is inderdaad een mooie, nette, alleen CSS-manier om dit te doen (die men als “beter” zou kunnen beschouwen).

Van alle antwoorden die hier zijn gepost, heb ik er maar één gevonden die calc() met succes gebruikt (door Dariusz Sikorski). Maar toen geposeerd met: “maar het lukt niet als er maar 2 items in de laatste rij staan” was er geen oplossing uitgebreid.

Deze oplossing beantwoordt de vraag van het OP met een alternatief voor negatieve marges en pakt het probleem aan dat aan Dariusz werd gesteld.

opmerkingen:

  • Dit voorbeeld toont alleen een lay-out met 3 kolommen
  • Het gebruikt calc() om de browser wiskunde te laten doen zoals hij wil —
    100%/3 (hoewel 33,3333% net zo goed zou moeten werken), en
    (1em/3)*2 (hoewel .66em ook goed zou moeten werken).
  • Het gebruikt ::after om de laatste rij op te vullen als er minder elementen zijn dan kolommen
.flex-container {
  display: flex;
  justify-content: space-between;
  flex-wrap: wrap;
}
.flex-container:after {
  content: "";
}
.flex-container > div,
.flex-container:after {
  box-sizing: border-box;
  width: calc((100%/3) - ((1em/3)*2));
}
.flex-container > :nth-child(n + 4) {
  margin-top: 1em;
}
/* the following is just to visualize the items */
.flex-container > div,
.flex-container:after {
  font-size: 2em;
}
.flex-container {
  margin-bottom:4em;
}
.flex-container > div {
  text-align: center;
  background-color: #aaa;
  padding: 1em;
}
.flex-container:after {
  border: 1px dashed red;
}
<h2>Example 1 (2 elements)</h2>
<div class="flex-container">
  <div>1</div>
  <div>2</div>
</div>
<h2>Example 2 (3 elements)</h2>
<div class="flex-container">
  <div>1</div>
  <div>2</div>
  <div>3</div>
</div>

Antwoord 29

Het zal niet in alle gevallen werken, maar als je flexibele onderliggende breedtes (%) hebt en het aantal items per rij weet, kun je de marges van de benodigde elementen heel duidelijk specificeren door nth-child selector/s.

Het hangt grotendeels af van wat je bedoelt met ‘beter’. Op deze manier is er geen extra wrapper-opmaak nodig voor onderliggende elementen of negatieve elementen, maar die dingen hebben allebei hun plaats.

section {
  display: block
  width: 100vw;
}
.container {
  align-content: flex-start;
  align-items: stretch;
  background-color: #ccc;
  display: flex;
  flex-flow: row wrap;
  justify-content: flex-start;
  width: 100%;
}
.child-item {
  background-color: #c00;
  margin-bottom: 2%;
  min-height: 5em;
  width: 32%;
}
.child-item:nth-child(3n-1) {
  margin-left: 2%;
  margin-right: 2%;
}
<html>
  <body>
      <div class="container">
        <div class="child-item"></div>
        <div class="child-item"></div>
        <div class="child-item"></div>
        <div class="child-item"></div>
        <div class="child-item"></div>
        <div class="child-item"></div>
        <div class="child-item"></div>
      </div>
   </body>
</html>

Antwoord 30

Ik kwam eerder hetzelfde probleem tegen en stuitte toen op het antwoord hiervoor. Ik hoop dat het anderen zal helpen voor toekomstig gebruik.

lang antwoord kort, voeg een rand toe aan de flex-items van je kind.
dan kunt u marges tussen flex-items specificeren naar wat u maar wilt.
In het fragment gebruik ik zwart voor illustratiedoeleinden, je kunt ‘transparant’ gebruiken als je wilt.

#box {
  display: flex;
  width: 100px;
  /* margin: 0 -5px; *remove this*/
}
.item {
  background: gray;
  width: 50px;
  height: 50px;
  /* margin: 0 5px; *remove this*/
  border: 1px solid black; /* add this */
}
.item.special{ margin: 0 10px; }
<div id='box'>
  <div class='item'></div>
  <div class='item'></div>
  <div class='item'></div>
  <div class='item'></div>
  <div class='item special'></div>
</div>

LEAVE A REPLY

Please enter your comment!
Please enter your name here

9 + 11 =

Other episodes