Besserer Weg, um den Abstand zwischen Flexbox-Elementen einzustellen

779

So stellen Sie den minimalen Abstand zwischen Flexbox-Elementen ein, die ich margin: 0 5pxam .itemund margin: 0 -5pxam Container verwende. Für mich scheint es ein Hack zu sein, aber ich kann keinen besseren Weg finden, dies zu tun.

Beispiel

#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>

Sasha Koss
quelle
29
Es ist kein Hack - es ist eine der beabsichtigten Methoden zum Ausrichten von Elementen. Es gibt jedoch noch andere Eigenschaften. Siehe w3.org/TR/css3-flexbox/#alignment
BoltClock
4
Ja, ich verstehe. Aber zum Beispiel gibt es eine Spalte-Lücke-Eigenschaft, die es uns ermöglicht, die Entfernung vom Container zu steuern: w3.org/TR/css3-multicol/#column-gap
Sasha Koss
Natürlich ist es ein Rand, der in der Flexbox zusammenbricht. Die andere Frage hat die richtige Antwort auf [Wie kann ich verhindern, dass der letzte Rand in der Flexbox zusammenbricht? ] ( stackoverflow.com/questions/38993170/… )
Jack Yang
6
Das CSS Box Alignment Module Level 3 enthält einen Abschnitt über Lücken zwischen Boxen, der für mehrspaltige Elemente, Flex-Container und Grid-Container gilt. So wird dies schließlich einfach sein wie: row-gap: 5px- erledigt.
Danield
2
@ JohnCarrell Firefox unterstützt tatsächlich bereits die gapEigenschaft auf Flex-Container ( caniuse )
Danield

Antworten:

428
  • Flexbox hat keine reduzierenden Ränder.
  • Flexbox hat nichts Ähnliches border-spacingfür Tabellen (außer für CSS-Eigenschaften, gapdie in den meisten Browsern nicht gut unterstützt werden, caniuse )

Daher ist es etwas schwieriger, das zu erreichen, wonach Sie fragen.

Nach meiner Erfahrung, die „saubersten“ Weg, der nicht verwendet :first-child/ :last-childohne Änderung und Werke auf flex-wrap:wrapgesetzt ist padding:5pxauf dem Behälter und margin:5pxauf die Kinder. Dies führt zu einer 10pxLücke zwischen jedem Kind und zwischen jedem Kind und seinem Elternteil.

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>

Alle Arbeiter sind wesentlich
quelle
219
Dies führt nicht zu dem gleichen Ergebnis wie in der Frage. Sie haben ganz links und rechts einen 10-Pixel-Einzug, von dem ich annehme, dass sie dies nicht beabsichtigen. Daher die negativen Ränder in der ursprünglichen Frage.
Chris Nicola
17
Was ist, wenn die orderEigenschaft festgelegt ist? :first-child/:last-childwird nicht wie erwartet funktionieren.
Guria
4
"Flexbox hat keine kollabierenden Ränder." Sehr aufschlussreich und anscheinend wahr, aber darf ich um ein Zitat bitten?
Chharvey
2
Ist das nicht eine schlechtere Antwort als die ursprüngliche Frage? Diese Methode erfordert Platz um den Behälter herum und die Rinne muss immer eine gerade Zahl sein.
Limitlessloop
7
@chharvey, aus der Spezifikation w3.org/TR/css-flexbox-1/#item-margins , "Die Ränder benachbarter Flex-Elemente fallen nicht zusammen."
Romellem
196

Dies ist kein Hack. Dieselbe Technik wird auch von Bootstrap und seinem Raster verwendet, obwohl Bootstrap anstelle von Rand Padding für seine Spalten verwendet.

.row {
  margin:0 -15px;
}
.col-xx-xx {
  padding:0 15px;
}
Roumelis George
quelle
1
Das einzige Problem bei dieser Methode ist die Beibehaltung von Elementen gleicher Höhe mit Hintergrundfarben. Bei der absoluten Positionierung mit wird height:100%; width:100%die Polsterung des Elements ignoriert.
Steven Vachon
3
Das Problem hierbei ist, dass IE10- und 11.- flex-basisWerte nicht berücksichtigt werden box-sizing: border-box, sodass ein untergeordnetes Element mit einem Auffüllen oder Rand das übergeordnete Element (oder in diesem Fall einen Zeilenumbruch) überläuft. Quelle
Carson
18
Bei diesem Ansatz gibt es ein weiteres Problem: Durch Anpassen des Randes kann die Seitenbreite vergrößert werden. Demo: jsfiddle.net/a97tatf6/1
Nathan Osman
4
Obwohl ich zustimme, dass dies kein Hack ist, bedeutet die Tatsache, dass etwas weit verbreitet ist, nicht, dass es kein Hack ist. Siehe Polyfills, temporäre Sicherheitspatches, Hex-Bearbeitung usw. usw.
William
15
Das ist natürlich ein Hack. Da Bootstrap diese Methode verwendet, bedeutet dies nicht, dass es sich nicht um einen Hack handelt. Es bedeutet nur, dass Bootstrap einen Hack verwendet.
Michael Benjamin
108

Flexbox und CSS-Berechnung mit Unterstützung für mehrere Zeilen

Hallo, unten ist meine Arbeitslösung für alle Browser, die Flexbox unterstützen. Keine negativen Margen.

Geigen-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>

Beachten Sie, dass dieser Code mit SASS kürzer sein kann

Update 2020.II.11 Ausgerichtete Spalten in der letzten Zeile links

Update 2020.II.14 Rand unten in der letzten Zeile entfernt

Dariusz Sikorski
quelle
13
Ich mag diese Lösung, aber sie schlägt fehl, wenn sich nur 2 Elemente in der letzten Zeile befinden. Die Gegenstände sind aufgrund der nicht gestapelt justify-content.
James Brantly
4
Um das Problem mit zwei Elementen zu beheben, wechseln Sie einfach zu justify-content: space-evenly;oder justify-content: space-around;.
Paul Rooney
6
@PaulRooney Vor Ort mit mehreren Listen kennen Sie möglicherweise nicht immer die Anzahl der Elemente, wenn die Listen von einem CMS generiert werden.
NinjaFart
1
@ 1.21gigawatts Bitte nehmen Sie keine willkürlichen Änderungen am Code / der Antwort eines anderen vor. Schreiben Sie stattdessen Ihre eigene Antwort.
TylerH
2
@ TylerH Es war nicht willkürlich. Die Frage lautete: "... um den Abstand zwischen Flexbox-Elementen festzulegen". Diese Antwort zeigt nicht die Größe der Rinne. Das Einstellen einer Hintergrundfarbe zeigt die Rinne. Das Hinzufügen eines Rahmens zeigt, dass sich unter der letzten Zeile ein Rand befindet.
1,21 Gigawatt
93

Sie können transparente Ränder verwenden.

Ich habe dieses Problem in Betracht gezogen, als ich versucht habe, ein Flex-Grid-Modell zu erstellen, das für ältere Browser auf ein Tabellen- + Tabellenzellenmodell zurückgreifen kann. Und Grenzen für Säulenrinnen schienen mir die am besten geeignete Wahl zu sein. dh Tabellenzellen haben keine Ränder.

z.B

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

Beachten Sie auch, dass Sie min-width: 50px;für Flexbox benötigen . Das Flex-Modell behandelt keine festen Größen, es sei denn, Sie tun dies flex: none;für das bestimmte untergeordnete Element, das Sie als fest festlegen möchten, und sind daher vom Sein ausgeschlossen "flexi". http://jsfiddle.net/GLpUp/4/ Aber alle Spalten zusammen flex:none;sind kein Flex-Modell mehr. Hier ist etwas näher an einem Flex-Modell: http://jsfiddle.net/GLpUp/5/

Sie können also normalerweise Ränder verwenden, wenn Sie den Fallback für Tabellenzellen für ältere Browser nicht benötigen. http://jsfiddle.net/GLpUp/3/

background-clip: padding-box;Bei Verwendung eines Hintergrunds ist eine Einstellung erforderlich, da sonst der Hintergrund in den transparenten Randbereich fließt.

Hexalys
quelle
5
gute Antwort. Ränder werden in Flexboxen unterschiedlich verwendet (um zusätzlichen Platz zu absorbieren), sodass transparente Ränder eine hervorragende Lösung für gleichmäßig verteilte Elemente darstellen, die mit einem
randartigen
4
Außer wenn Sie Hintergrundfarbe verwenden, überschreitet Ihr Hintergrund Ihre gewünschten Grenzen.
Ahnbizcad
2
@ahnbizcad Nun, mit verschiedenen Hintergrundfarben können Sie Weiß oder die entsprechende Farbe verwenden, je nachdem, in welche Richtung der Hintergrund ist.
Hexalys
27
@ahnbizcad: Wenn Sie keine IE8-Unterstützung benötigen, ist dies eine bessere Lösung:background-clip: padding-box
Albin
5
Albins Kommentar hier braucht mehr Stimmen! Dies ist die beste Lösung. Transparente Ränder in Kombination mit Hintergrundclip: Padding-Box (und bei Bedarf negative Ränder am Container für eine korrekte Kantenausrichtung) sind eine perfekte Lösung. IE8 unterstützt ohnehin keine Flexbox, daher sollte die mangelnde Unterstützung für Hintergrundclips keine Rolle spielen.
Brian
74

Diese Lösung funktioniert in allen Fällen, auch wenn mehrere Zeilen oder eine beliebige Anzahl von Elementen vorhanden sind. Die Anzahl der Abschnitte sollte jedoch gleich sein, Sie möchten 4 in der ersten Zeile und 3 in der zweiten Zeile. Dies funktioniert nicht. Der Platz für den 4. Inhalt ist leer, der Container füllt ihn nicht.

Wir benutzen display: grid; und seine Eigenschaften.

#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>

Der Nachteil dieser Methode ist, dass in Mobile Opera Mini nicht unterstützt wird und in PC dies erst nach IE10 funktioniert .

Hinweis für vollständige Browserkompatibilität einschließlich IE11 verwenden Sie bitte Autoprefixer


ALTE ANTWORT

Betrachten Sie es nicht als eine alte Lösung, es ist immer noch eine der besten, wenn Sie nur eine einzelne Reihe von Elementen möchten und es mit allen Browsern funktioniert.

Diese Methode wird von der CSS-Geschwisterkombination verwendet , sodass Sie sie auch auf viele andere Arten bearbeiten können. Wenn Ihre Kombination jedoch falsch ist, kann dies ebenfalls zu Problemen führen.

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

Der folgende Code reicht aus. Bei dieser Methode muss margin: 0 -5px;der #boxWrapper nicht übergeben werden.

Ein Arbeitsprobe für Sie:

#box {
  display: flex;
  width: 100px;
}
.item {
  background: gray;
  width: 22px;
  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>

weBBer
quelle
Ich habe Ihre gitterbasierte Antwort bearbeitet, um zu demonstrieren, dass sie ordnungsgemäß funktioniert, auch wenn die letzte Zeile weniger Elemente enthält. Um zu beweisen, dass es in diesem Fall funktioniert. (Sie können jederzeit zurückkehren, wenn Ihnen diese Änderung nicht gefällt.)
ToolmakerSteve
Gemäß dieser Frage haben sie nur darum gebeten, den Raum ohne Hack ordnungsgemäß mit den untergeordneten Elementen zu füllen. Das, was ich getan habe, mithilfe eines Rasters, das wir gemäß dem von grid-template-columnsuns definierten nicht dynamisch verwalten können. Wenn Sie also den Wert angeben, 1fr 1fr 1fr 1frwird das div in aufgeteilt 4fractionsund versucht, die fractionsuntergeordneten Elemente in jedem zu füllen. Meines Wissens ist dies der einzige Weg grid. Was ich in der Antwort angegeben habe, ist, dass, wenn der Benutzer das div in 4 aufteilen und sie mit vielen Elementen auch für mehrere Zeilen verwenden muss, dies gidhelfen wird.
weBBer
69

Sie können & > * + *als Selektor verwenden, um a flex-gap(für eine einzelne Zeile) zu emulieren :

#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>

Wenn Sie Flex Wrapping unterstützen müssen , können Sie ein Wrapper-Element verwenden:

.flex { display: flex; flex-wrap: wrap;  }
.box { background: gray; height: 100px; min-width: 100px; flex: auto; }
.flex-wrapper {outline: 1px solid red; }

/* ----- Flex gap 10px: ----- */

.flex > * {
  margin: 5px;
}
.flex {
  margin: -5px;
}
.flex-wrapper {
  width: 400px; /* optional */
  overflow: hidden; /* optional */
}
<div class='flex-wrapper'>
  <div class='flex'>
    <div class='box'></div>
    <div class='box'></div>
    <div class='box'></div>
    <div class='box'></div>
    <div class='box'></div>
  </div>
</div>

Asynchronisieren
quelle
3
Saubere Lösung. Funktioniert für eine beliebige Anzahl von untergeordneten Flex-Elementen.
Konrad Gałęzowski
1
Das war es, wonach ich gesucht und für mich großartig gearbeitet habe 👍
Paul Odeon
Ein zu beachtender Punkt ist jedoch, dass der *Operator die Spezifität nicht wie erwartet erhöht. Abhängig von Ihrem vorhandenen CSS müssen Sie möglicherweise entweder die Spezifität des .flex > *Selektors erhöhen oder !importantdie Regel ergänzen , wenn andere Selektoren einen Rand auf dieses Element anwenden.
Paul Odeon
Beste Lösung 👍
o01
26

Angenommen, Sie möchten einen 10pxAbstand zwischen den Elementen festlegen , den Sie einfach .item {margin-right:10px;}für alle festlegen und auf den letzten zurücksetzen können.item:last-child {margin-right:0;}

Sie können auch die allgemeine Geschwister- ~oder die nächste +Geschwisterauswahl verwenden, um den linken Rand für die Elemente festzulegen, die das erste ausschließen .item ~ .item {margin-left:10px;}oder verwenden.item:not(:last-child) {margin-right: 10px;}

Flexbox ist so clever, dass es das Raster automatisch neu berechnet und gleichmäßig verteilt.

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>

Wenn Sie Flex Wrap zulassen möchten , sehen Sie sich das folgende Beispiel an.

body {
  margin: 0;
}

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

.item {
  flex: 0 0 calc(50% - 10px);
  background: gray;
  height: 50px;
  margin: 0 0 10px 10px;
}
<div class="container">
  <div class="item"></div>
  <div class="item"></div>
  <div class="item"></div>
  <div class="item"></div>
</div>

Aufkleber
quelle
6
Dies würde nicht funktionieren, wenn die Elemente verpackt sind, da :last-childnicht jedes letzte Kind am Ende einer Zeile betroffen ist, richtig?
Flimm
2
@Flimm Ich habe einen Ansatz für die Arbeit mit Flex Wrap hinzugefügt, siehe den zweiten Teil oben.
Aufkleber
Beste Antwort für mich ... einfach, sauber, effizient! Arbeitete perfekt mit Flex Wrap, danke
Matthieu Marcé
16

Ich habe eine Lösung gefunden, die auf dem allgemeinen Geschwister-Selektor basiert ~und eine unendliche Verschachtelung ermöglicht.

In diesem Codestift finden Sie ein funktionierendes Beispiel

Grundsätzlich erhält innerhalb von Spaltencontainern jedes Kind, dem ein anderes Kind vorangestellt ist, einen oberen Rand. Ebenso erhält in jedem Zeilencontainer jedes Kind, dem ein anderes vorangestellt ist, einen linken Rand.

.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>

Simon Epskamp
quelle
Dies führt zu Elementen unterschiedlicher Größe, da die Ränder nicht global angewendet werden.
Steven Vachon
Sie müssen auch zusätzliches CSS hinzufügen, um kleinere Bildschirme zu verarbeiten, da es auf Mobilgeräten etwas seltsam aussieht. Ich würde die .box ~ .box-Regel auf größere Bildschirme anwenden und für kleinere Bildschirme die .box-Klasse auf eine maximale Breite einstellen von 100% und einem Rand unten.
Rhysclay
14

In Anlehnung an Sawas Antwort finden Sie hier eine leicht verbesserte Version, mit der Sie einen festen Abstand zwischen den Elementen ohne den umgebenden Rand festlegen können.

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

Ebenfalls enthalten ist die Safari "-webkit-flex" -Version.

.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>
chris
quelle
2
Ist das nicht im Wesentlichen dasselbe wie das Beispiel in der Frage?
Ford
10

Laut #ChromDevSummit gibt es eine Implementierung der gapEigenschaft für Flexbox, obwohl sie derzeit (14. November 2019) nur in Firefox unterstützt wird, aber bald in Chrome implementiert werden sollte:

Geben Sie hier die Bildbeschreibung ein

Live-Demo

Ich werde meine Antwort aktualisieren, sobald sie auch in Chrome eingeht.

Eliya Cohen
quelle
9

Ich habe dies für gewickelte und feste Spalten verwendet. Der Schlüssel hier istcalc()

SCSS-Probe

$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});}

}

Vollständiges Codepen-Beispiel

Veiko Jääger
quelle
2
Dies fügt noch eine Rinne vor dem ersten und nach dem letzten Element hinzu, wodurch OP die Verwendung negativer Ränder verhindert.
Hermann
2
Flexbox unterstützt calc () in "flex" in IE 11 nicht.
Adam Šipický
Kann nicht immer verwendet werden. Stellen Sie sich vor, es gibt auch eine Grenze für direkte Kinder
Andris
9

Ein Flexcontainer mit -x (negativem) Rand und Flex-Elemente mit x (positivem) Rand oder Polsterung führen beide zum gewünschten visuellen Ergebnis: Flex-Elemente haben nur einen festen Abstand von 2x dazwischen ihnen.

Es scheint einfach eine Frage der Präferenz zu sein, ob für die Flex-Elemente ein Rand oder eine Polsterung verwendet werden soll.

In diesem Beispiel werden die Flex-Elemente dynamisch skaliert, um die feste Lücke beizubehalten:

.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;
}
Tim
quelle
3
Entschuldigung, ich habe es nicht verstanden. Welche neue Einführung führt Ihre Antwort ein, die nicht direkt in der Frage steht?
Benutzer
Zunächst wollte ich zusammenfassen, dass sowohl der Rand als auch die Polsterung des Flex-Elements zum gewünschten Ergebnis führen, da in den vorhandenen Antworten nur das eine oder das andere erwähnt wird. Zweitens wollte ich ein Beispiel geben, bei dem Lücken durch Skalieren der Flex-Elemente selbst erhalten bleiben.
Tim
Hier ist ein Codepen-Beispiel, das diesen Effekt zeigt. codepen.io/dalgard/pen/Dbnus
Pedalpete
8

Schließlich werden sie die gapEigenschaft zu flexbox hinzufügen. Bis dahin könnten Sie stattdessen ein CSS-Raster verwenden, das bereits über die gapEigenschaft verfügt und nur eine einzelne Zeile enthält. Schöner als mit Margen umzugehen.

Ollie Williams
quelle
Diskussion hier: github.com/w3c/csswg-drafts/issues/1696 - Sie werden auch die Benennung in CSS Grid-, Flexbox- und CSS-Spalten optimieren.
Frank Lämmer
6

CSS gap Eigenschaft:

Es gibt eine neue gapCSS-Eigenschaft für mehrspaltige, Flexbox- und Grid-Layouts, die jetzt in einigen Browsern funktioniert! (Siehe Kann ich Link 1 verwenden ? Link 2 ).

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

Zum Zeitpunkt des Schreibens funktioniert dies leider nur in Firefox. Es funktioniert derzeit in Chrome, wenn Sie "Experimentelle Webplattformfunktionen aktivieren" in aktivieren about:flags.

Flimm
quelle
5

Bei Verwendung von Flexbox in meiner Lösung habe ich die justify-contentEigenschaft für das übergeordnete Element (Container) verwendet und die Ränder innerhalb der flex-basisEigenschaft der Elemente angegeben. Überprüfen Sie das folgende Code-Snippet:

.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>

iClusterDev
quelle
5

Mit der Flexbox ist das Erstellen von Dachrinnen ein Problem, insbesondere wenn es um das Wickeln geht.

Sie müssen negative Ränder verwenden ( wie in der Frage gezeigt ):

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

... oder ändern Sie den HTML-Code ( wie in einer anderen Antwort gezeigt ):

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

... oder etwas anderes.

In jedem Fall benötigen Sie einen hässlichen Hack, damit es funktioniert, da die Flexbox flex-gap( zumindest für den Moment) keine " " -Funktion bietet .

Das Problem der Dachrinnen ist jedoch mit CSS Grid Layout einfach und unkompliziert.

Die Rasterspezifikation bietet Eigenschaften, die Platz zwischen Rasterelementen schaffen, während der Abstand zwischen Elementen und dem Container ignoriert wird. Diese Eigenschaften sind:

  • grid-column-gap
  • grid-row-gap
  • grid-gap (die Abkürzung für beide Eigenschaften oben)

Vor kurzem wurde die Spezifikation aktualisiert, um sie an das CSS-Box-Ausrichtungsmodul anzupassen , das eine Reihe von Ausrichtungseigenschaften für alle Box-Modelle bereitstellt. Die Eigenschaften sind also jetzt:

  • column-gap
  • row-gap
  • gap (Stenografie)

Da jedoch nicht alle Grid-unterstützenden Browser die neueren Eigenschaften unterstützen, verwende ich die Originalversionen in der folgenden Demo.

Wenn zwischen den Elementen und dem Container ein Abstand erforderlich ist, paddingfunktioniert der Container einwandfrei (siehe das dritte Beispiel in der Demo unten).

Aus der Spezifikation:

10.1. Dachrinnen: dierow-gap , column-gapund gap Eigenschaften

Das row-gapundcolumn-gap Eigenschaften (und ihre gapKurzform) definieren, wenn sie in einem Rastercontainer angegeben werden, die Rinnen zwischen Rasterzeilen und Rasterspalten. Ihre Syntax ist in CSS Box Alignment 3 §8 Lücken zwischen Boxen definiert .

Diese Eigenschaften wirken so, als ob die betroffenen Gitterlinien an Dicke gewonnen hätten: Die Gitterbahn zwischen zwei Gitterlinien ist der Abstand zwischen den Dachrinnen, die sie darstellen.

.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>

Mehr Informationen:

Michael Benjamin
quelle
4

Warum nicht so:

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

Dies verwendet den benachbarten Geschwister-Selektor , um alle .itemElemente außer dem ersten a anzugeben margin-left. Dank der Flexbox ergeben sich sogar gleich breite Elemente. Dies könnte margin-topnatürlich auch mit vertikal positionierten Elementen erfolgen .

Tillersander
quelle
8
Dies würde funktionieren, solange sich die Flex-Elemente immer in einer einzelnen Reihe befinden. Wenn das Umwickeln erlaubt ist, wird es wahrscheinlich nicht ausreichen.
Nick F
4

Hier ist meine Lösung, für die keine Klassen für die untergeordneten Elemente festgelegt werden müssen:

.flex-inline-row {
    display: inline-flex;
    flex-direction: row;
}

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

Verwendungszweck:

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

Dieselbe Technik kann zusätzlich zu dem oben angegebenen Inline-Beispiel für normale Flex-Zeilen und -Spalten verwendet und um Klassen für andere Abstände als 4 Pixel erweitert werden.

MK10
quelle
4

In solchen Fällen verwende ich oft den 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>

Wutzebaer
quelle
3

Ich finde, der einfachste Weg, dies zu tun, besteht darin, Prozentsätze zu verwenden und nur zuzulassen, dass der Rand Ihre Breite angleicht

Dies bedeutet, dass Sie am Ende so etwas haben, wenn Sie Ihr Beispiel verwenden

#box {
   display: flex;
}

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

Bedeutet jedoch, dass Ihre Werte auf der Breite basieren, was möglicherweise nicht für alle geeignet ist.

lukefrake
quelle
Ich bin gerade auf diese Lösung gestoßen und ja, es ist sehr schön. Funktioniert zumindest in meinem Fall (ein Stift für diejenigen, die es interessant finden könnten: codepen.io/rishatmuhametshin/pen/XXjpaV ).
Rishat
2

Hier ist ein Raster von Karten-UI-Elementen, deren Abstand mithilfe einer flexiblen Box vervollständigt wurde:

Geben Sie hier die Bildbeschreibung ein

Ich war frustriert, die Karten manuell voneinander zu trennen, indem ich Polster und Ränder mit zweifelhaften Ergebnissen manipulierte. Hier sind die Kombinationen von CSS-Attributen, die ich als sehr effektiv empfunden habe:

.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>

Hoffe, das hilft den Menschen, Gegenwart und Zukunft.

Buildpax
quelle
Update: Dieser Abstand gilt für das mobile Rendern von HTML-Elementen, die eine bestimmte Ausrichtung benötigen (z. B. Mitte, links usw.). Wenn Sie Flexbox für die mobile Entwicklung verwenden, habe ich Erleichterung bei der Umstellung auf eine rein randbasierte Ausrichtung gefunden.
Buildpax
2

Columnify - Eine Soloklasse für N Spalten

Flexbox und SCSS

.columnify {
  display: flex;

  > * {
    flex: 1;

    &:not(:first-child) {
      margin-left: 2rem;
    }
  }
}

Flexbox und 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>

Spielen Sie damit auf JSFiddle .

zurfyx
quelle
1

#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>

Amo Wu
quelle
1

Verwenden Sie einfach .item + .itemin der Auswahl, um von der Sekunde abzugleichen.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>

Andrew Luca
quelle
1

Angenommen:

  • Sie möchten ein 4-Spalten-Raster mit Umbruch
  • Die Anzahl der Elemente ist nicht unbedingt ein Vielfaches von 4

Stellen Sie für jeden Artikel einen linken Rand ein, außer für den 1., 5., 9. Artikel usw. und stellen Sie für jedes Element eine feste Breite ein. Wenn der linke Rand 10 Pixel beträgt, hat jede Zeile einen Rand von 30 Pixel zwischen 4 Elementen. Die prozentuale Breite des Elements kann wie folgt berechnet werden:

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

Dies ist eine anständige Problemumgehung für Probleme mit der letzten Reihe der 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>

Salman A.
quelle
1

Es gibt in der Tat eine nette, ordentliche, nur CSS-fähige Möglichkeit, dies zu tun (die man als "besser" betrachten kann).

Von allen hier veröffentlichten Antworten habe ich nur eine gefunden, die calc () erfolgreich verwendet (von Dariusz Sikorski). Aber wenn gestellt mit: "aber es schlägt fehl, wenn es nur 2 Elemente in der letzten Zeile gibt", wurde keine Lösung erweitert.

Diese Lösung adressiert die Frage des OP mit einer Alternative zu negativen Margen und adressiert das Problem, das Dariusz stellt.

Anmerkungen:

  • Dieses Beispiel zeigt nur ein dreispaltiges Layout
  • Damit kann calc()der Browser 100%/3 rechnen, wie er will - (obwohl 33,3333% genauso gut (1em/3)*2 funktionieren sollten ) und (obwohl .66em auch gut funktionieren sollte) .
  • Es wird verwendet ::after, um die letzte Zeile aufzufüllen, wenn weniger Elemente als Spalten vorhanden sind

.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>

Auch unter https://codepen.io/anon/pen/rqWagE

aequalsb
quelle
1

Sie könnten die neue Eigenschaft verwenden gap. Ich kopiere die Erklärung, die ich in diesem Artikel gefunden habe , sowie weitere Informationen

Das CSS-Rasterlayout weist seit einiger Zeit eine Lücke (zuvor Rasterlücke) auf. Durch Angabe des internen Abstands eines enthaltenen Elements anstelle des Abstands um untergeordnete Elemente werden viele häufig auftretende Layoutprobleme gelöst. Bei Lücken müssen Sie sich beispielsweise keine Gedanken über Ränder bei untergeordneten Elementen machen, die unerwünschte Leerzeichen an den Rändern eines enthaltenen Elements verursachen:

Leider unterstützt derzeit nur FireFox Lücken in Flex-Layouts.

@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>

Andres Paul
quelle
gapwurde bereits in einer Antwort hier empfohlen stackoverflow.com/a/58041749/2756409 Auch dies ist kein CSS.
TylerH
0

Es funktioniert nicht in jedem Fall, aber wenn Sie flexible untergeordnete Breiten (%) haben und die Anzahl der Elemente pro Zeile kennen, können Sie die Ränder der erforderlichen Elemente mithilfe von sehr genau angeben nth-child Selektoren .

Es hängt weitgehend davon ab, was Sie unter "besser" verstehen. Auf diese Weise ist kein zusätzliches Wrapper-Markup für untergeordnete oder negative Elemente erforderlich - aber beide Dinge haben ihren Platz.

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>

jnmrobinson
quelle
Nicht ansprechbar. Funktioniert nur für übergeordnete Elemente mit fester Breite.
Grün
1
Die OP nicht fragen , für eine ansprechende Lösung und dessen Beispiel verwendet eine fix Breite. Angesichts der Tatsache, dass hierfür% -Werte verwendet werden, ist es leicht zu argumentieren, dass dies reagiert, da sich die Elemente an die Größe des übergeordneten Elements anpassen, die in Prozent festgelegt wird.
jnmrobinson
0

Ich bin früher auf dasselbe Problem gestoßen und bin dann auf die Antwort darauf gestoßen. Hoffe, es wird anderen als zukünftige Referenz helfen.

lange Antwort kurz, fügen Sie Ihrem Kind Flex-Items einen Rand hinzu. Dann können Sie Ränder zwischen Flex-Elementen nach Belieben festlegen. Im Snippet verwende ich Schwarz zur Veranschaulichung. Sie können "transparent" verwenden, wenn Sie möchten.

#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>

Tunasing
quelle
0

Der Trick mit dem negativen Rand des Boxcontainers funktioniert einfach großartig. Hier ist ein weiteres Beispiel, das hervorragend mit Ordnung, Verpackung und was nicht funktioniert.

.container {
   border: 1px solid green;
   width: 200px;
   display: inline-block;
}

#box {
  display: flex;
  flex-wrap: wrap-reverse;
  margin: -10px;
  border: 1px solid red;
}
.item {
  flex: 1 1 auto;
  order: 1;
  background: gray;
  width: 50px;
  height: 50px;
  margin: 10px;
  border: 1px solid blue;
}
.first {
  order: 0;
}
<div class=container>
<div id='box'>
  <div class='item'>1</div>
  <div class='item'>2</div>
  <div class='item first'>3*</div>
  <div class='item'>4</div>
  <div class='item'>5</div>
</div>
</div>

cghislai
quelle