Mantenga el elemento central centrado cuando los elementos laterales tengan diferentes anchos.

Resuelto Mark asked hace 9 años • 13 respuestas

ingrese la descripción de la imagen aquí

Imagine el siguiente diseño, donde los puntos representan el espacio entre los cuadros:

[Left box]......[Center box]......[Right box]

Cuando elimino el cuadro derecho, me gusta que el cuadro central siga en el centro, así:

[Left box]......[Center box].................

Lo mismo ocurre si quitara el cuadro de la izquierda.

................[Center box].................

Ahora, cuando el contenido dentro del cuadro central se alargue, ocupará todo el espacio disponible que sea necesario mientras permanece centrado. Los cuadros izquierdo y derecho nunca se reducirán y, por lo tanto, cuando no quede espacio, overflow:hiddenentrará text-overflow: ellipsisen vigor para dividir el contenido;

[Left box][Center boxxxxxxxxxxxxx][Right box]

Todo lo anterior es mi situación ideal, pero no tengo idea de cómo lograr este efecto. Porque cuando creo una estructura flexible así:

.parent {
    display : flex; // flex box
    justify-content : space-between; // horizontal alignment
    align-content   : center; // vertical alignment
}

Si los cuadros izquierdo y derecho tuvieran exactamente el mismo tamaño, obtendría el efecto deseado. Sin embargo, cuando uno de los dos es de diferente tamaño, el cuadro centrado ya no está realmente centrado.

¿Hay alguien que pueda ayudarme?

Actualizar

A justify-selfestaría bien, esto sería ideal:

.leftBox {
     justify-self : flex-start;
}

.rightBox {
    justify-self : flex-end;
}
Mark avatar Sep 03 '15 21:09 Mark
Aceptado

Si los cuadros izquierdo y derecho tuvieran exactamente el mismo tamaño, obtendría el efecto deseado. Sin embargo, cuando uno de los dos tiene un tamaño diferente, el cuadro centrado ya no está realmente centrado. ¿Hay alguien que pueda ayudarme?

Aquí hay un método que usa flexbox para centrar el elemento del medio, independientemente del ancho de los hermanos.

Características clave:

  • CSS puro
  • sin posicionamiento absoluto
  • sin JS/jQuery

Utilice márgenes y contenedores flexibles anidados auto:

.container {
  display: flex;
}
.box {
  flex: 1;
  display: flex;
  justify-content: center;
}

.box:first-child > span { margin-right: auto; }

.box:last-child  > span { margin-left: auto;  }

/* non-essential */
.box {
  align-items: center;
  border: 1px solid #ccc;
  background-color: lightgreen;
  height: 40px;
}
p {
  text-align: center;
  margin: 5px 0 0 0;
}
<div class="container">
  <div class="box"><span>short text</span></div>
  <div class="box"><span>centered text</span></div>
  <div class="box"><span>loooooooooooooooong text</span></div>
</div>
<p>&#8593;<br>true center</p>
Expandir fragmento

Así es como funciona:

  • El div de nivel superior ( .container) es un contenedor flexible.
  • Cada div secundario ( .box) ahora es un elemento flexible.
  • Cada .boxelemento se proporciona flex: 1para distribuir el espacio del contenedor por igual ( más detalles ).
  • Ahora los elementos consumen todo el espacio de la fila y tienen el mismo ancho.
  • Haga de cada elemento un contenedor flexible (anidado) y agregue justify-content: center.
  • Ahora cada spanelemento es un elemento flexible centrado.
  • Utilice márgenes flexibles autopara desplazar los spanbordes exteriores hacia la izquierda y hacia la derecha.

También puede renunciar justify-contenty utilizar automárgenes exclusivamente.

Pero justify-contentpuede funcionar aquí porque autolos márgenes siempre tienen prioridad.

8.1. Alinearse con auto los márgenes

Antes de la alineación mediante justify-contenty align-self, cualquier espacio libre positivo se distribuye a los márgenes automáticos en esa dimensión.

Michael Benjamin avatar Sep 13 '2015 03:09 Michael Benjamin
  1. Utilice tres elementos flexibles en el contenedor.
  2. Establezca flex: 1el primero y el último. Esto hace que crezcan igualmente hasta llenar el espacio disponible que deja el del medio.
  3. Así, el del medio tenderá a estar centrado.
  4. Sin embargo, si el primer o último elemento tiene un contenido amplio, ese elemento flexible también crecerá debido al nuevo min-width: autovalor inicial.

    Nota Chrome no parece implementar esto correctamente. Sin embargo, puede configurarlo min-widthen -webkit-max-contento -webkit-min-contenty también funcionará.

  5. Sólo en este caso el elemento central será empujado fuera del centro.

.outer-wrapper {
  display: flex;
}
.item {
  background: lime;
  margin: 5px;
}
.left.inner-wrapper, .right.inner-wrapper {
  flex: 1;
  display: flex;
  min-width: -webkit-min-content; /* Workaround to Chrome bug */
}
.right.inner-wrapper {
  justify-content: flex-end;
}
.animate {
  animation: anim 5s infinite alternate;
}
@keyframes anim {
  from { min-width: 0 }
  to { min-width: 100vw; }
}
<div class="outer-wrapper">
  <div class="left inner-wrapper">
    <div class="item animate">Left</div>
  </div>
  <div class="center inner-wrapper">
    <div class="item">Center</div>
  </div>
  <div class="right inner-wrapper">
    <div class="item">Right</div>
  </div>
</div>
<!-- Analogous to above --> <div class="outer-wrapper"><div class="left inner-wrapper"><div class="item">Left</div></div><div class="center inner-wrapper"><div class="item animate">Center</div></div><div class="right inner-wrapper"><div class="item">Right</div></div></div><div class="outer-wrapper"><div class="left inner-wrapper"><div class="item">Left</div></div><div class="center inner-wrapper"><div class="item">Center</div></div><div class="right inner-wrapper"><div class="item animate">Right</div></div></div>
Expandir fragmento

Oriol avatar Dec 22 '2015 00:12 Oriol

La clave es usar flex-basis. Entonces la solución es simple como:

.parent {
    display: flex;
    justify-content: space-between;
}

.left, .right {
   flex-grow: 1;
   flex-basis: 0;
}

CodePen está disponible aquí .

gamliela avatar Jan 07 '2021 10:01 gamliela