Centrare e allineare a destra gli elementi flexbox


147

Mi piacerebbe avere A Be Callineato nel mezzo.

Come posso arrivare Dcompletamente a destra?

PRIMA:

inserisci qui la descrizione dell'immagine

DOPO:

inserisci qui la descrizione dell'immagine

ul {
  padding: 0;
  margin: 0;
  display: flex;
  flex-direction: row;
  justify-content: center;
  align-items: center;
}
li {
  display: flex;
  margin: 1px;
  padding: 5px;
  background: #aaa;
}
li:last-child {
  background: #ddd;
  /* magic to throw to the right*/
}
<ul>
  <li>A</li>
  <li>B</li>
  <li>C</li>
  <li>D</li>
</ul>

https://jsfiddle.net/z44p7bsx/

Risposte:


214

Di seguito sono cinque opzioni per ottenere questo layout:

  • Posizionamento CSS
  • Flexbox con elemento DOM invisibile
  • Flexbox con pseudo-elemento invisibile
  • Flexbox con flex: 1
  • Layout griglia CSS

Metodo n. 1: proprietà di posizionamento CSS

Applicare position: relativesul contenitore flessibile.

Applica position: absoluteall'articolo D.

Ora questo oggetto è assolutamente posizionato all'interno del contenitore flessibile.

Più specificamente, l'elemento D viene rimosso dal flusso del documento ma rimane entro i limiti dell'antenato posizionato più vicino .

Utilizzare le proprietà di offset CSS tope rightspostare questo elemento in posizione.

Un avvertimento a questo metodo è che alcuni browser potrebbero non rimuovere completamente un elemento flessibile assolutamente posizionato dal flusso normale. Ciò modifica l'allineamento in modo non standard, inaspettato. Maggiori dettagli: l' elemento flessibile posizionato in modo assoluto non viene rimosso dal flusso normale in IE11


Metodo n. 2: Margini automatici Flex e articolo flessibile invisibile (elemento DOM)

Con una combinazione di automargini e un nuovo elemento flessibile invisibile, è possibile ottenere il layout.

Il nuovo oggetto flessibile è identico all'articolo D ed è posizionato all'estremità opposta (il bordo sinistro).

Più specificamente, poiché l'allineamento flessibile si basa sulla distribuzione di spazio libero, il nuovo elemento è un contrappeso necessario per mantenere le tre scatole centrali centrate orizzontalmente. Il nuovo oggetto deve avere la stessa larghezza dell'oggetto D esistente, altrimenti le caselle centrali non saranno centrate con precisione.

Il nuovo elemento viene rimosso dalla vista con visibility: hidden.

In breve:

  • Crea un duplicato Ddell'elemento.
  • Posizionalo all'inizio dell'elenco.
  • Uso flex automargini per mantenere A, Be Ccentrato, con entrambi gli Delementi creando equilibrio uguale da entrambe le estremità.
  • Applica visibility: hiddenal duplicatoD


Metodo n. 3: Margini automatici Flex e elemento flessibile invisibile (pseudo-elemento)

Questo metodo è simile al n. 2, tranne che è semanticamente più pulito e la larghezza di Ddeve essere nota.

  • Crea uno pseudo-elemento con la stessa larghezza di D.
  • Posizionalo all'inizio del contenitore con ::before.
  • Utilizzare flex automargini di mantenere A, Be Cperfettamente centrato, con la pseudo e Delementi creando equilibrio uguale da entrambe le estremità.


Metodo n. 4: aggiungi flex: 1agli elementi sinistro e destro

Iniziando con il metodo n. 2 o n. 3 sopra, invece di preoccuparti della stessa larghezza per gli elementi sinistro e destro per mantenere l'equilibrio, basta dare a ciascuno di essi flex: 1. Ciò li costringerà entrambi a consumare spazio disponibile, centrando così l'elemento centrale.

È quindi possibile aggiungere display: flexsingoli elementi per allinearne il contenuto.

NOTA sull'utilizzo di questo metodo con min-height: Attualmente in Chrome, Firefox, Edge e possibilmente altri browser, la regola abbreviata siflex: 1suddivide in questo:

  • flex-grow: 1
  • flex-shrink: 1
  • flex-basis: 0%

Quell'unità percentuale (%) su flex-basisprovoca l'interruzione di questo metodo quando min-heightviene utilizzato sul contenitore. Questo perché, come regola generale, le altezze percentuali sui figli richiedono un'impostazione esplicita della heightproprietà sul genitore.

Questa è una vecchia regola CSS risalente al 1998 ( CSS Level 2 ) che è ancora in vigore in molti browser in un modo o nell'altro. Per i dettagli completi vedere qui e qui .

Ecco un'illustrazione del problema pubblicato nei commenti di user2651804 :

La soluzione è non utilizzare l'unità percentuale. Prova pxo semplicemente niente ( che è ciò che le specifiche effettivamente raccomandano , nonostante il fatto che almeno alcuni dei principali browser abbiano aggiunto un'unità percentuale per qualsiasi motivo).


Metodo n. 5: layout griglia CSS

Questo può essere il metodo più pulito ed efficiente. Non è necessario il posizionamento assoluto, elementi falsi o altri hacker.

Basta creare una griglia con più colonne. Quindi posiziona i tuoi articoli nelle colonne centrali e finali. Fondamentalmente, lascia vuota la prima colonna.

ul {
  display: grid;
  grid-template-columns: 1fr repeat(3, auto) 1fr;
  grid-column-gap: 5px;
  justify-items: center;
}

li:nth-child(1) { grid-column-start: 2; }
li:nth-child(4) { margin-left: auto; }

/* for demo only */
ul { padding: 0; margin: 0; list-style: none; }
li { padding: 5px; background: #aaa; }
p  { text-align: center; }
<ul>
  <li>A</li>
  <li>B</li>
  <li>C</li>
  <li>D</li>
</ul>
<p><span>| true center |</span></p>


1
Molto bello, grazie per la spiegazione! Immagino che i nuovi frammenti di codice aggiunti trarrebbero beneficio dall'accorciamento del testo di esempio poiché non è in realtà evidente dall'output che il contenuto è centrato / non centrato a causa della visualizzazione ridotta. Solo io?
user2651804

"Il nuovo oggetto deve avere la stessa larghezza dell'oggetto D esistente, altrimenti le caselle centrali non saranno centrate con precisione." - fa schifo che deve avere la stessa larghezza, ma grazie a dio per la griglia CSS :)
Vucko

Usando la tecnica Grid, gli oggetti non sono nel punto morto, c'è un modo per far sì che l'elemento logo sia morto nel centro? imgur.com/a/SVg9xsj
J86

Non abbastanza familiare con la soluzione grid anche se funziona come un fascino ed è il più pulito. Una domanda che ho è come dare più spazio alla colonna centrale non uguale a tutti e tre?
Saba Ahang,

5

Il modo più semplice

.box{
  display:flex;
  justify-content:center;
}
.item1{
   flex:1;
   display: flex;
   justify-content: center;
   transform: translateX(10px);/*D element Width[if needed]*/
}
 <div class="box">
   <div class="item1">
      <div>A</div>
      <div>B</div>
      <div>C</div>
   </div>
   <div class="item2">D</div>
 </div>


2

Se vuoi renderlo allineato, puoi semplicemente collegare una campata vuota e dividere le tre campate figlio in esse.


2
puoi fornire una breve demo per il backup della tua dichiarazione?
Klewis,

2

La soluzione più semplice sarà quella di giustificare il centro del contenuto nel contenitore padre e dare l'auto a margine sinistro al primo e all'ultimo elemento figlio.

ul {
  display:flex;
  justify-content:center;
}


.a,.d {
  margin-left:auto;
}
<ul>
  <li class="a">A</li>
  <li>B</li>
  <li>C</li>
  <li class="d">D</li>
</ul>


1

Utilizzando l' display:gridapproccio, puoi semplicemente mettere tutti i ulbambini nella stessa cella e quindi impostare justify-self:

ul {
  display: grid;
}

ul > * {
  grid-column-start: 1;
  grid-row-start: 1;
  justify-self:center;
}

ul > *:last-child {
  justify-self: right;
}

/* Make Fancy */
li {
  display:inline-block;
  margin: 1px;
  padding: 5px;
  background: #bbb;
}
<ul>
  <span>
  <li>A</li>
  <li>B</li>
  <li>C</li>
  </span>
  <li>D</li>
</ul>


0

Domanda molto chiara. Non ho potuto fare a meno di pubblicare la risposta dopo alcune ore di scavo. Potremmo risolverlo con tabelle, celle di tabella, posizioni assolute, trasformazioni, ma abbiamo dovuto farlo con flexbox :)

.parent {
  display: flex;
  justify-content: flex-end;
}

.center {
  margin: auto;
}

http://codepen.io/rgfx/pen/BLorgd


8
Questo non centra veramente gli oggetti intermedi perché considera solo lo spazio rimanente , non l' intero spazio. codepen.io/anon/pen/QKGrRk
Michael Benjamin,

@Michael_B, la tua destra non l'ha notato, mia cattiva. Tornando all'utilizzo di posizioni assolute :( Forse con il tuo alto rappresentante dovresti impostare una taglia per risolverlo per sempre. Vorrei ma ho un rappresentante molto basso, anche inferiore ora
sto

Nessuna ricompensa aggiungerà un nuovo comportamento al modello di flexbox, la risposta data da Michael_B è buona come quella che arriva oggi.
Ason,

0

Ho ampliato la risposta di Michael_B

.center-flex__2-of-3 > :nth-child(1), .center-flex__2-of-3 > :nth-child(3) {
  flex: 1;
}
.center-flex__2-of-3 > :nth-child(1) {
  justify-content: flex-start;
}
.center-flex__2-of-3 > :nth-child(3) {
  justify-content: flex-end;
}
.center-flex__1-of-2 > :nth-child(1) {
  margin: auto;
}
.center-flex__1-of-2 > :nth-child(2) {
  flex: 1;
  justify-content: flex-end;
}
.center-flex__2-of-2 > :nth-child(1) {
  flex: 1;
  justify-content: flex-start;
}
.center-flex__2-of-2 > :nth-child(2) {
  margin: auto;
}
.center-flex__1-of-2:before, .center-flex__1-of-1:before {
  content: '';
  flex: 1;
}
.center-flex__1-of-1:after, .center-flex__2-of-2:after {
  content: '';
  flex: 1;
}

[class*=center-flex] {
  display: flex;
  list-style: none;
  margin: 0;
  padding: 0;
  border: 10px solid rgba(0, 0, 0, 0.1);
}
[class*=center-flex] > * {
  display: flex;
}
li {
  padding: 3px 5px;
}
2 of 3
<ul class="center-flex__2-of-3">
  <span>
    <li>Accusamus</li>
    <li>Porro</li>
  </span>
  <span>
    <li>Lorem</li>
    <li>Dolor</li>
  </span>
  <span>
    <li>Porro</li>
    <li>Culpa</li>
    <li>Sit</li>
  </span>
</ul>

<br><br>
1 of 2
<ul class="akex center-flex__1-of-2">
  <span>
    <li>Lorem</li>
    <li>Dolor</li>
  </span>
  <span>
    <li>Porro</li>
    <li>Culpa</li>
    <li>Sit</li>
  </span>
</ul>

<br><br>
2 of 2
<ul class="akex center-flex__2-of-2">
  <span>
    <li>Porro</li>
    <li>Culpa</li>
    <li>Sit</li>
  </span>
  <span>
    <li>Lorem</li>
    <li>Dolor</li>
  </span>
</ul>

<br><br>
1 of 1
<ul class="center-flex__1-of-1">
  <span>
    <li>Lorem</li>
    <li>Dolor</li>
  </span>
</ul>

Qui con l'aiuto di SASS come codepen


0

Ispirato al metodo n. 5: CSS Grid Layout della soluzione di @Michal Benjamin e perché sto usando Tailwind e per ora non ho ancora accesso a tutte le opzioni della griglia di default. Questo sembra funzionare:

ul {
  display: grid;
  grid-template-columns: repeat(3, minmax(0, 1fr));
}
li:nth-child(1) { justify-content: flex-start; } // OR: margin-right: auto
li:nth-child(3) { justify-content: flex-end; } // OR: margin-left:auto
li: {align-self: center;}
<ul>
  <li>A</li>
  <li>B</li>
  <li>C</li>
</ul>

PS: Non sono sicuro che mescolare flex e griglia in questo modo sia una buona idea!


1
non stai mescolando la griglia e la flessibilità, il contenuto di giustificazione è una proprietà della griglia CSS E la proprietà della flexbox (la stessa cosa per align-self)
Temani Afif

-1

La risposta accettata può essere modificata un po 'perché è possibile utilizzare aree del modello di griglia e farlo senza elemento falso

grid-template-areas '. b c'
grid-template-columns: 1fr 1fr 1fr

-1
ul { 
  padding: 0; 
  margin: 0;
  display: flex;
  flex-direction: row;
  justify-content: center;
  align-items: center;
}
li {
  display: flex;
  margin: 1px;
  padding: 5px;
  background: #aaa;
}
li:last-child {
  background: #ddd;
  position:absolute;
  right:10px;

}
<ul>
  <li>A</li>
  <li>B</li>
  <li>C</li>
  <li>D</li>
</ul>
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.