Centrar divs flotantes dentro de otro div

142

He buscado otras preguntas y, aunque este problema parece similar a un par de otras, nada de lo que he visto hasta ahora parece abordar el problema que estoy teniendo.

Tengo un div que contiene varios otros divs, cada uno de los cuales está flotando a la izquierda. Estos divs contienen una foto y una leyenda. Todo lo que quiero es que el grupo de fotos se centre en el div que lo contiene.

Como puede ver en el siguiente código, he intentado usar ambos overflow:hiddeny margin:x autoen los divs principales, y también he agregado un clear:both(como se sugiere en otro tema) después de las fotos. Nada parece hacer la diferencia.

Gracias. Agradezco cualquier sugerencia.

<div style="position: relative; margin: 0 auto; overflow: hidden; text-align: center;">
    <h4>Section Header</h4>

    <div style="margin: 2em auto;">

        <div style="float: left; margin: auto 1.5em;">
            <img src="photo1.jpg" /><br />
             Photo Caption
        </div>
        <div style="float: left; margin: auto 1.5em;">
            <img src="photo2.jpg" /><br />
             Photo Caption
        </div>
        <div style="float: left; margin: auto 1.5em;">
            <img src="photo3.jpg" /><br />
             Photo Caption
        </div>

        <div style="clear: both; height: 0; overflow: hidden;"> </div>

    </div>

</div>
Darren
fuente
posible duplicado de ¿Cómo centro los elementos flotantes?
TylerH
@TylerH ¿Cómo es que? Solo vea la fecha en que se le preguntó. Parece que la pregunta en su enlace es el duplicado real.
The Pragmatick
@ThePragmatick Debido a que uno tiene el doble de visitas, más respuestas, más (y más reciente) actividad, y su redacción sirve como una mejor pregunta canónica que esta.
TylerH

Respuestas:

266

Primero, elimine el floatatributo en el divs interno . Luego, ponte text-align: centerel exterior principal div. Y para el divs interno , use display: inline-block. También podría ser prudente darles anchos explícitos también.


<div style="margin: auto 1.5em; display: inline-block;">
  <img title="Nadia Bjorlin" alt="Nadia Bjorlin" src="headshot.nadia.png"/>
  <br/>
  Nadia Bjorlin
</div>
Sampson
fuente
66
@Darren: ¿dejaste de flotar cuando lo intentaste? No podrá lograr lo que quiere mientras esté flotando / a menos que establezca un ancho fijo en el contenedor de los flotadores.
Ken Browning
1
Oh ... estoy equivocado Parece que quitar el flotador logra exactamente lo que quiero. No estoy seguro de entender por qué, pero ... Muchas gracias.
Darren
9
@Darren, fíjate en mi ejemplo de código que no incluí el flotante;) Lee más detenidamente la próxima vez, te ahorrará algo de frustración :) Me alegro de que lo hayas resuelto. Sigan con el buen trabajo, y bienvenidos a SO.
Sampson el
2
Este enfoque comienza a fallar cuando algunos de los subtítulos de las imágenes son lo suficientemente largos como para ajustar la línea. ¿Cualquier otra sugerencia?
greg.kindel
3
No importa, descubrió que el problema de los subtítulos de recuento de línea variable se puede solucionar con 'vertical-align: top'. =)
greg.kindel
33

Con Flexbox puede centrar fácilmente a los niños flotantes en el centro (y verticalmente) dentro de un div.

Entonces, si tiene un marcado simple como este:

<div class="wpr">
    <span></span>
    <span></span>
    <span></span>
    <span></span>
    <span></span>
</div>

con CSS:

.wpr
{
    width: 400px;
    height: 100px;
    background: pink;
    padding: 10px 30px;
}

.wpr span
{
    width: 50px;
    height: 50px;
    background: green;
    float: left; /* **children floated left** */
    margin: 0 5px;
}

(Este es el RESULTADO (esperado e indeseable) )

Ahora agregue las siguientes reglas al contenedor:

display: flex;
justify-content: center; /* align horizontal */

y los niños flotantes se alinean en el centro ( DEMO )

Solo por diversión, para obtener una alineación vertical, simplemente agregue:

align-items: center; /* align vertical */

MANIFESTACIÓN

Danield
fuente
todavía tengo que verificar las compatibilidades del navegador, ¡pero esto parece ser increíble!
low_rents
También puede usar display: inline en lugar de flex para centrar divs. Flex tiene problemas con safari y Opera.
USTED
en línea no funciona para mí. El problema de esta solución es que los cuadros no van a la segunda línea si desbordan el ancho del div. Entonces los convertiste en una mesa ...
Pavel Jiri Strnad
10

Logré lo anterior usando posicionamiento relativo y flotando a la derecha.

Código HTML:

<div class="clearfix">                          
    <div class="outer-div">
        <div class="inner-div">
            <div class="floating-div">Float 1</div>
            <div class="floating-div">Float 2</div>
            <div class="floating-div">Float 3</div>
        </div>
    </div>
</div>

CSS:

.outer-div { position: relative; float: right; right: 50%; }
.inner-div { position: relative; float: right; right: -50%; }
.floating-div { float: left; border: 1px solid red; margin: 0 1.5em; }

.clearfix:before,
.clearfix:after { content: " "; display: table; }
.clearfix:after { clear: both; }
.clearfix { *zoom: 1; }

JSFiddle: http://jsfiddle.net/MJ9yp/

Esto funcionará en IE8 y versiones posteriores, pero no antes (¡sorpresa, sorpresa!)

Lamentablemente, no recuerdo la fuente de este método, por lo que no puedo dar crédito al autor original. Si alguien más lo sabe, ¡publique el enlace!

Kendolein
fuente
+1 Esto funciona muy bien. La respuesta aceptada no funcionó para mí. Creó problemas de alineación vertical ...
TimH - Codidact
@TimH Tarde a la fiesta, lo sé, pero el problema de alineación vertical se puede solucionar agregando 'vertical-align: top' al contenedor
Alfie
Lo siento, quise decir div interno, no contenedor div *
Alfie
Casi funciona perfecto. Los elementos van a la siguiente línea si se desbordan, pero cuando lo hacen no están centrados.
Pavel Jiri Strnad
5

La siguiente solución no utiliza bloques en línea. Sin embargo, requiere dos divs auxiliares:

  1. El contenido es flotante.
  2. El ayudante interno es flotante (se estira tanto como el contenido)
  3. El ayudante interno se empuja 50% hacia la derecha (su izquierda se alinea con el centro del ayudante externo)
  4. El contenido se extrae el 50% a la izquierda (su centro se alinea con la izquierda del ayudante interno)
  5. El ayudante externo está configurado para ocultar el desbordamiento

.ca-outer {
  overflow: hidden;
  background: #FFC;
}
.ca-inner {
  float: left;
  position: relative;
  left: 50%;
  background: #FDD;
}
.content {
  float: left;
  position: relative;
  left: -50%;
  background: #080;
}
/* examples */
div.content > div {
  float: left;
  margin: 10px;
  width: 100px;
  height: 100px;
  background: #FFF;
}
ul.content {
  padding: 0;
  list-style-type: none;
}
ul.content > li {
  margin: 10px;
  background: #FFF;
}
<div class="ca-outer">
  <div class="ca-inner">
    <div class="content">
      <div>Box 1</div>
      <div>Box 2</div>
      <div>Box 3</div>
    </div>
  </div>
</div>
<hr>
<div class="ca-outer">
  <div class="ca-inner">
    <ul class="content">
      <li>Lorem ipsum dolor sit amet, consectetur adipiscing elit.</li>
      <li>Nullam efficitur nulla in libero consectetur dictum ac a sem.</li>
      <li>Suspendisse iaculis risus ut dapibus cursus.</li>
    </ul>
  </div>
</div>

Salman A
fuente
4

display: inline-block;no funcionará en ninguno de los navegadores IE. Aquí está lo que usé.

// change the width of #boxContainer to 
// 1-2 pixels higher than total width of the boxes inside:

#boxContainer {         
    width: 800px; 
    height: auto;
    text-align: center;
    margin-left: auto;
    margin-right: auto;
}

#Box{
    width: 240px; 
    height: 90px;
    background-color: #FFF;
    float: left;
    margin-left: 10px;
    margin-right: 10px;
}
Abdulla Kaleem
fuente
3

Solución:

<!DOCTYPE HTML>
<html>
    <head>
        <title>Knowledge is Power</title>
        <script src="js/jquery.js"></script>
        <script type="text/javascript">
        </script>
        <style type="text/css">
            #outer {
                text-align:center;
                width:100%;
                height:200px;
                background:red;
            }
            #inner {
                display:inline-block;
                height:200px;
                background:yellow;
            }
        </style>
    </head>
    <body>
        <div id="outer">
            <div id="inner">Hello, I am Touhid Rahman. The man in Light</div>
        </div>
    </body>
</html>
Touhid Rahman
fuente
Esta solución está fuera de tema. El interior debe ser flotante: dejado para cumplir con los requisitos del OP.
s15199d
1

En mi caso, no pude obtener la respuesta de @Sampson para trabajar para mí, en el mejor de los casos obtuve una sola columna centrada en la página. Sin embargo, en el proceso, aprendí cómo funciona realmente el flotador y creé esta solución. En esencia, la solución es muy simple pero difícil de encontrar, como lo demuestra este hilo que ha tenido más de 146k vistas en el momento de esta publicación sin mencionarlo.

Todo lo que se necesita es totalizar la cantidad de ancho de espacio de pantalla que ocupará el diseño deseado, luego hacer que el padre tenga el mismo ancho y aplicar margen: automático. ¡Eso es!

Los elementos en el diseño dictarán el ancho y la altura del div "exterior". Tome cada "myFloat" o ancho o altura del elemento + sus bordes + sus márgenes y sus rellenos y agréguelos todos juntos. Luego agregue los otros elementos juntos de la misma manera. Esto le dará el ancho principal. Todos pueden tener tamaños algo diferentes y puede hacerlo con menos o más elementos.

Ej. (Cada elemento tiene 2 lados, por lo que el borde, el margen y el relleno se multiplican x2)

Entonces, un elemento que tiene un ancho de 10px, borde 2px, margen 6px, relleno 3px se vería así: 10 + 4 + 12 + 6 = 32

Luego, agregue todos los anchos totalizados de su elemento.

Element 1 = 32
Element 2 = 24
Element 3 = 32
Element 4 = 24

En este ejemplo, el ancho para el div "exterior" sería 112.

.outer {
  /* floats + margins + borders = 270 */
  max-width: 270px;
  margin: auto;
  height: 80px;
  border: 1px;
  border-style: solid;
}

.myFloat {
    /* 3 floats x 50px = 150px */
    width: 50px;
    /* 6 margins x 10px = 60 */
    margin: 10px;
    /* 6 borders x 10px = 60 */
    border: 10px solid #6B6B6B;
    float: left;
    text-align: center;
    height: 40px;
}
<div class="outer">
  <div class="myFloat">Float 1</div>
  <div class="myFloat">Float 2</div>
  <div class="myFloat">Float 3</div>
</div>

dimmech
fuente
Esta es la respuesta que estaba buscando, gracias. ¿Cómo calculas el px que necesitas? No me queda claro.
SilverSurfer