Centrar y alinear a la derecha los elementos flexbox

147

Me gustaría tener A By Calineado en el medio.

¿Cómo puedo llegar Da ir completamente a la derecha?

ANTES DE:

ingrese la descripción de la imagen aquí

DESPUÉS:

ingrese la descripción de la imagen aquí

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/

empañado
fuente

Respuestas:

214

A continuación hay cinco opciones para lograr este diseño:

  • Posicionamiento CSS
  • Flexbox con elemento DOM invisible
  • Flexbox con pseudo-elemento invisible
  • Flexbox con flex: 1
  • Diseño de cuadrícula CSS

Método # 1: Propiedades de posicionamiento CSS

Aplicar position: relativeal envase flexible.

Aplicar position: absoluteal artículo D.

Ahora este artículo está absolutamente ubicado dentro del contenedor flexible.

Más específicamente, el elemento D se elimina del flujo de documentos pero permanece dentro de los límites del antepasado posicionado más cercano .

Use las propiedades de desplazamiento CSS topy rightpara mover este elemento a su posición.

Una advertencia para este método es que algunos navegadores pueden no eliminar completamente un elemento flexible en posición absoluta del flujo normal. Esto cambia la alineación de una manera inesperada y no estándar. Más detalles: el elemento flexible colocado de forma absoluta no se elimina del flujo normal en IE11


Método n. ° 2: márgenes automáticos flexibles y elemento flexible invisible (elemento DOM)

Con una combinación de automárgenes y un nuevo elemento flexible invisible, se puede lograr el diseño.

El nuevo elemento flexible es idéntico al elemento D y se coloca en el extremo opuesto (el borde izquierdo).

Más específicamente, debido a que la alineación flexible se basa en la distribución del espacio libre, el nuevo elemento es un contrapeso necesario para mantener los tres cuadros centrales centrados horizontalmente. El nuevo elemento debe tener el mismo ancho que el elemento D existente, o los cuadros centrales no estarán centrados con precisión.

El nuevo elemento se elimina de la vista con visibility: hidden.

En breve:

  • Crea un duplicado del Delemento.
  • Colóquelo al principio de la lista.
  • Use automárgenes flexibles para mantener A, By Ccentrado, con ambos Delementos creando el mismo equilibrio desde ambos extremos.
  • Aplicar visibility: hiddenal duplicadoD


Método n. ° 3: márgenes automáticos flexibles y elemento flexible invisible (pseudo-elemento)

Este método es similar al n. ° 2, excepto que es más semántico y el ancho Ddebe ser conocido.

  • Cree un pseudo-elemento con el mismo ancho que D.
  • Colóquelo al comienzo del contenedor con ::before.
  • Use automárgenes flexibles para mantener A, By Cperfectamente centrado, con el pseudo y los Delementos creando un equilibrio igual desde ambos extremos.


Método # 4: Agregar flex: 1a elementos izquierdos y derechos

Comenzando con el Método n. ° 2 o n. ° 3 anterior, en lugar de preocuparse por el mismo ancho para los elementos izquierdo y derecho para mantener el mismo equilibrio, solo dele cada uno flex: 1. Esto los obligará a ambos a consumir el espacio disponible, centrando así el elemento central.

Luego puede agregar display: flexelementos individuales para alinear su contenido.

NOTA sobre el uso de este método con min-height: Actualmente en Chrome, Firefox, Edge y posiblemente otros navegadores, la regla abreviada seflex: 1divide en esto:

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

Esa unidad de porcentaje (%) en flex-basishace que este método se rompa cuando min-heightse usa en el contenedor. Esto se debe a que, como regla general, las alturas de porcentaje en los elementos secundarios requieren una heightconfiguración de propiedad explícita en el elemento primario.

Esta es una antigua regla CSS que data de 1998 ( CSS Nivel 2 ) que todavía está vigente en muchos navegadores en algún grado u otro. Para detalles completos ver aquí y aquí .

Aquí hay una ilustración del problema publicado en los comentarios del usuario2651804 :

La solución es no usar la unidad de porcentaje. Pruebe pxo simplemente nada ( que es lo que la especificación realmente recomienda , a pesar del hecho de que al menos algunos de los principales navegadores han agregado una unidad de porcentaje por cualquier razón).


Método 5: diseño de cuadrícula CSS

Este puede ser el método más limpio y eficiente. No hay necesidad de posicionamiento absoluto, elementos falsos u otros hackers.

Simplemente cree una cuadrícula con múltiples columnas. Luego coloque sus artículos en las columnas del medio y final. Básicamente, solo deje la primera columna vacía.

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>

Michael Benjamin
fuente
1
Muy bien, gracias por la explicación! Supongo que los fragmentos de código recién agregados se beneficiarían al acortar el texto de ejemplo, ya que en realidad no es evidente a partir de la salida que el contenido está centrado / no centrado debido a la pequeña ventana gráfica. ¿Sólo yo?
user2651804
"El nuevo elemento debe tener el mismo ancho que el elemento D existente, o los cuadros centrales no estarán centrados con precisión". - eso apesta que debe ser del mismo ancho, pero gracias a Dios por la cuadrícula CSS :)
Vucko
Usando la técnica de cuadrícula, los elementos no están en el centro muerto, ¿hay alguna manera de hacer que el elemento del logotipo esté muerto en el centro? imgur.com/a/SVg9xsj
J86
No está lo suficientemente familiarizado con la solución de cuadrícula, aunque funciona de maravilla y es la más limpia. Una pregunta que tengo es cómo dar más espacio a la columna central que no es igual a los tres.
Saba Ahang
5

La manera más fácil

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

Razib Hossain
fuente
2

Si desea alinearlo, simplemente puede adjuntar un espacio vacío y dividir los tres tramos secundarios en ellos.

Ali Korkmaz
fuente
2
¿Puede proporcionar una breve demostración para respaldar su estado de cuenta?
Klewis
2

La solución más simple será justificar el centro de contenido al contenedor principal y dar margen automático izquierdo al primer y último elemento secundario.

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>

Suhail AKhtar
fuente
1

Usando el display:gridenfoque, simplemente puede poner a todos los ulniños en la misma celda y luego configurar 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>

Steven Spungin
fuente
0

Pregunta muy clara. No pude evitar publicar la respuesta después de unas horas de excavación. Podríamos resolver esto con tablas, tablas de celdas, posiciones absolutas, transformaciones, pero solo teníamos que hacerlo con flexbox :)

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

.center {
  margin: auto;
}

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

rgfx
fuente
8
Esto realmente no centra los elementos intermedios porque solo tiene en cuenta el espacio restante , no todo el espacio. codepen.io/anon/pen/QKGrRk
Michael Benjamin
@Michael_B, tu derecho no se dio cuenta de eso, mi mal. Volver a usar posiciones absolutas :( Tal vez con tu alta reputación deberías establecer una recompensa para que esto se resuelva para siempre. Lo haría, pero tengo una muy baja repetición, incluso más baja ahora tratando de ayudarte.
rgfx
Ninguna recompensa va a agregar un nuevo comportamiento al modelo flexbox, el, por Michael_B, la respuesta dada es tan buena como parece ... hoy.
Ason
0

Amplié en Michael_b 's respuesta

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

Aquí con la ayuda de SASS como codepen

Yunzen
fuente
0

Inspirado por el Método # 5: Diseño de cuadrícula CSS de la solución de @Michal Benjamin y porque estoy usando Tailwind y por ahora todavía no tengo acceso a todas las opciones de cuadrícula por defecto. Esto parece funcionar:

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>

PD: ¡No estoy seguro si mezclar flex y grid como esta es una buena idea!

Saba Ahang
fuente
1
no está mezclando cuadrícula y flex, justifty-content es una propiedad de cuadrícula CSS Y propiedad de flexbox (lo mismo para align-self)
Temani Afif
-1

La respuesta aceptada se puede cambiar un poco porque puede usar áreas de plantilla de cuadrícula y hacerlo sin elemento falso

grid-template-areas '. b c'
grid-template-columns: 1fr 1fr 1fr
repo
fuente
-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>
SUDHIR KUMAR
fuente