Centrar divs flutuantes dentro de outra div

142

Pesquisei outras perguntas e, embora esse problema pareça um par de outras, nada do que vi até agora parece abordar o problema que estou tendo.

Eu tenho um div que contém um número de outros divs, cada um dos quais é flutuado para a esquerda. Essas divs contêm uma foto e uma legenda. Tudo o que eu quero é que o grupo de fotos seja centralizado na div que contém.

Como você pode ver no código abaixo, tentei usar ambos overflow:hiddene margin:x autonos divs principais e também adicionei um clear:both(como sugerido em outro tópico) após as fotos. Nada parece fazer a diferença.

Obrigado. Agradeço todas as sugestões.

<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
fonte
possível duplicação de Como centralizar elementos de flutuação?
TylerH
@TylerH Como é que é? Basta ver a data em que foi solicitado. Parece que a pergunta no seu link é a duplicata real.
The Pragmatick
@ThePragmatick Por ter duas vezes mais visualizações, mais respostas, mais (e mais recente) atividade, e sua redação serve como uma pergunta canônica melhor que esta.
TylerH

Respostas:

266

Primeiro, remova o floatatributo no interior div. Em seguida, coloque text-align: centera parte externa principal div. E para o interior div, use display: inline-block. Também pode ser prudente fornecer larguras explícitas também.


<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
fonte
6
@ Darren: você parou de flutuar quando tentou? Você não será capaz de realizar o que deseja enquanto estiver flutuando / a menos que defina uma largura fixa no contêiner dos carros alegóricos.
11119 Ken Browning
1
Oh ... eu estou errado. A remoção do flutuador parece realizar exatamente o que eu quero. Não sei ao certo por que, mas ... Muito obrigado.
1211 Darren
9
@ Darren, observe no meu exemplo de código que eu não incluí o flutuante;) Leia com mais cuidado da próxima vez, isso poupará uma certa frustração :) Que bom que você conseguiu descobrir isso. Continue com o bom trabalho e seja bem-vindo ao SO.
13339 Sampson
2
Essa abordagem começa a falhar quando algumas das legendas da imagem são longas o suficiente para quebrar a linha. Alguma outra sugestão?
greg.kindel
3
Deixa pra lá, descobriu que o problema das legendas com contagem de linhas variadas pode ser corrigido com 'vertical-align: top'. =)
greg.kindel
33

Com o Flexbox, você pode facilmente centralizar crianças horizontalmente (e verticalmente) dentro de uma div.

Portanto, se você tem uma marcação simples como esta:

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

com 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 é o esperado (- e indesejável) RESULTADO )

Agora adicione as seguintes regras ao wrapper:

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

e as crianças flutuadas ficam alinhadas no centro ( DEMO )

Apenas por diversão, para obter alinhamento vertical, basta adicionar:

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

DEMO

Danield
fonte
ainda temos que verificar a compatibilidade do navegador, mas isso parece ser incrível!
low_rents
Você também pode usar display: inline em vez de flex para divs de centralização. O Flex tem problemas com o safari e o Opera.
VOCÊ
inline não funciona para mim. O problema desta solução é que, então, as caixas não vão para a segunda linha se excederem a largura da div. Então você realmente transformou-os em uma mesa ...
Pavel Jiri Strnad
10

Eu realizei o acima usando posicionamento relativo e flutuando para a direita.

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/

Isso funcionará no IE8 e superior, mas não antes (surpresa, surpresa!)

Infelizmente, não me lembro da fonte desse método, portanto não posso dar crédito ao autor original. Se alguém mais souber, por favor poste o link!

Kendolein
fonte
+1 Isso funciona lindamente. A resposta aceita não funcionou para mim. Criou problemas de alinhamento vertical ...
TimH - Codidact
@TimH atrasado para a festa, eu sei, mas o problema de alinhamento vertical pode ser corrigido adicionando 'vertical-align: top' para o recipiente
Alfie
Desculpe, eu quis dizer div interior, não recipiente div *
Alfie
Está quase funcionando perfeitamente. Os itens vão para a próxima linha, se o estouro, mas quando o fazem, eles não são centralizados.
Pavel Jiri Strnad
5

A solução a seguir não usa blocos embutidos. No entanto, ele requer duas divs auxiliares:

  1. O conteúdo é flutuado
  2. O ajudante interno é flutuado (estende tanto quanto o conteúdo)
  3. O ajudante interno é empurrado para a direita 50% (sua esquerda se alinha ao centro do ajudante externo)
  4. O conteúdo é puxado para a esquerda 50% (seu centro se alinha à esquerda do ajudante interno)
  5. O ajudante externo está definido para ocultar o estouro

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

display: inline-block;não funcionará em nenhum navegador IE. Aqui está o que eu usei.

// 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
fonte
3

Solução:

<!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
fonte
Esta solução está fora de tópico. O interior deve ser flutuado: deixado para atender aos requisitos do OP.
S15199d
1

No meu caso, não consegui que a resposta de @Sampson funcionasse para mim, na melhor das hipóteses, tinha uma única coluna centralizada na página. No processo, no entanto, aprendi como o float realmente funciona e criei esta solução. No seu núcleo, a correção é muito simples, mas difícil de encontrar, como evidente por este segmento, que teve mais de 146 mil visualizações no momento deste post, sem menção.

Tudo o que é necessário é totalizar a quantidade de largura do espaço da tela que o layout desejado ocupará, tornar o pai a mesma largura e aplicar a margem: auto. É isso aí!

Os elementos no layout ditarão a largura e a altura da div "externa". Pegue na largura ou altura de cada "myFloat" ou elemento + suas bordas + suas margens e seus preenchimentos e adicione-os todos juntos. Em seguida, adicione os outros elementos da mesma maneira. Isso fornecerá a largura principal. Todos eles podem ter tamanhos um pouco diferentes e você pode fazer isso com menos ou mais elementos.

Ex. (Cada elemento tem 2 lados, para que a borda, a margem e o preenchimento sejam multiplicados x2)

Portanto, um elemento com largura de 10 px, borda 2px, margem 6px, preenchimento de 3px ficaria assim: 10 + 4 + 12 + 6 = 32

Em seguida, adicione todas as larguras totais do seu elemento.

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

Neste exemplo, a largura da div "externa" seria 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
fonte
Esta é a resposta que eu estava procurando, obrigado. Como você calcula o px de que precisa? Não está claro para mim.
SilverSurfer