Por que o alinhamento vertical: middle não está funcionando no meu intervalo ou div?


246

Estou tentando centralizar verticalmente um elemento spanou divdentro de outro divelemento. No entanto, quando eu coloco vertical-align: middle, nada acontece. Eu tentei alterar as displaypropriedades de ambos os elementos, e nada parece funcionar.

É o que estou fazendo atualmente na minha página da web:

.main {
  height: 72px;
  vertical-align: middle;
  border: 1px solid black;
  padding: 2px;
}
    
.inner {
  vertical-align: middle;
  border: 1px solid red;    
}
    
.second {
  border: 1px solid blue; 
}
<div class="main">
  <div class="inner">
    This box should be centered in the larger box
    <div class="second">Another box in here</div>
  </div>
</div>

Aqui está um jsfiddle da implementação, mostrando que ela não funciona: http://jsfiddle.net/gZXWC/

Respostas:


207

Esta parece ser a melhor maneira - já passou algum tempo desde o meu post original e é isso que deve ser feito agora: http://jsfiddle.net/m3ykdyds/200

/* CSS file */

.main {
    display: table;
}

.inner {
    border: 1px solid #000000;
    display: table-cell;
    vertical-align: middle;
}

/* HTML File */
<div class="main">
    <div class="inner"> This </div>
</div>

2
Então, como alguém faz o que o OP quer fazer?
Ryan Mortensen

Alguma idéia sobre parágrafos de linha variável? ie se não há como saber se serão uma ou duas linhas. Eu precisaria usar o jQuery então?
Foochow

E se a altura precisar ser dinâmica, qual é a solução?
Murhaf Sousli

não deve ser a resposta aceita, depende da altura do conhecimento de '.inner'; portanto, não exatamente o que o OP estava pedindo e algumas respostas muito melhores abaixo, consulte as respostas @timbergus ou Tim Perkins ', bem abaixo do fundo.
Mike-source

@ mike-source, sabendo que a altura do inner é 100% possível, mesmo que a altura seja dinâmica, já que um pouco de javascript pode descobrir isso e alterar dinamicamente a regra CSS para esse objeto DOM.
Charles Addis

143

Usando CSS3:

<div class="outer">
   <div class="inner"/>
</div>

Css:

.outer {
  display : flex;
  align-items : center;
  justify-content: center;
}

Nota: Isso pode não funcionar nos IE antigos


16
Isso é suportado por todos os principais navegadores modernos e pela solução mais simples e limpa.
18715 Sam

2
Lembre- inline-flexse também de ter vários elementos seguidos dentro do elemento interno.
Dan Nissenbaum

1
No meu caso, como também queria centralizar o conteúdo do .inner horizontalmente, tive que adicionar .inner { width: 100%; }. Dessa forma, parece funcionar, .outer { display: table; } .inner { display: table-cell; vertical-align: middle; }mas sem forçar uma largura mínima.
Bart S

I utilizado justify-content: center;para alinhar na horizontal, que funcionou muito bem
Ruth Young

140

Tente isso, funciona muito bem para mim:

/* Internet Explorer 10 */
display:-ms-flexbox;
-ms-flex-pack:center;
-ms-flex-align:center;

/* Firefox */
display:-moz-box;
-moz-box-pack:center;
-moz-box-align:center;

/* Safari, Opera, and Chrome */
display:-webkit-box;
-webkit-box-pack:center;
-webkit-box-align:center;

/* W3C */
display:box;
box-pack:center;
box-align:center;

4
excelente resposta, isso me deu uma solução totalmente funcional que não causou outros problemas comuns (um aplicativo usando jquerymobile + phonegap e todas as outras soluções levaram a problemas de dimensionamento de css e div). Apenas para salientar que esses parâmetros precisam ser adicionados a um bloco CSS específico para os elementos a serem centralizados / mediados, por exemplo: #element span {height:100%;display:-webkit-box;-webkit-box-pack:center;-webkit-box-align:center;}- observe que a altura é importante para garantir que a extensão herda toda a altura do seu contêiner (provavelmente uma div), caso contrário você ainda não terá a centralização vertical!
Andy Lorenz

BTW, você pode escrever código flexbox padrão sem prefixos navegador e, em seguida, se navegador prefixado com autoprefixer github.com/postcss/autoprefixer ou via online demonstração simevidas.jsbin.com/gufoko/quiet
starikovs

2
valor da propriedade inválida boxemdisplay
Joaquinglezsantos 17/02

Além disso, a resposta do @ user1782556 funciona melhor quando a caixa externa possui preenchimento.
iautomation

34

Definir a altura da linha para a mesma altura em que contém div também funcionará

DEMO http://jsfiddle.net/kevinPHPkevin/gZXWC/7/

.inner {
    line-height:72px;
    border: 1px solid #000000;
}

1
Eu publiquei um link que explicava esse método também. Porém, não é o meu método preferido, se o restante do layout não tiver tamanho fixo - eu deparei com problemas em diferentes viewports de tamanho com esse método.
Charles Addis

2
sim, a técnica de altura da linha funciona bem, mas SOMENTE SE você tiver conteúdo de linha única. Linhas adicionais serão perdidas / serão derramadas fora do contêiner e você precisará começar novamente!
Andy Lorenz

a) line-heighttambém mudará a altura do elemento interno. b) O elemento interno ainda não está centralizado com precisão na vertical. c) Não funciona em elementos que não contêm texto, por exemplo:, <img>ou elementos com altura fixa.
Alph.Dev

Também pode falhar no sistema operacional cruzado (Windows / Mac) devido a diferenças de renderização de fonte
LocalPCGuy 27/10/2015

1
Isso é muito imprevisível e geralmente resulta em altura extra no contêiner.
Undistraction

25

Caso você não possa confiar no flexbox ... Coloque .childno .parentcentro. Funciona quando os tamanhos de pixel são desconhecidos (em outras palavras, sempre) e sem problemas com o IE9 + também.

.parent { position: relative; }

.child {
    position: absolute;
    top : 50%;
    left: 50%;
    -ms-transform: translate(-50%, -50%);
    transform    : translate(-50%, -50%);    
}
<div class="parent" style="background:lightyellow; padding:6em"> 
  <div class="child" style="background:gold; padding:1em">&mdash;</div> 
</div>


Esta é realmente a solução mais bem feito, especialmente desde que a maioria dos projetos que eu vi compatibilidade IE9 até agora precisa
Jabberwocky

20

Você deve colocar vertical-align: middleo elemento interno, não o externo. Defina a line-heightpropriedade no elemento externo para corresponder à heightdo elemento externo. Em seguida, defina display: inline-blocke line-height: normalno elemento interno. Ao fazer isso, o texto no elemento interno será quebrado com uma altura de linha normal. Funciona no Chrome, Firefox, Safari e IE 8+

.main {
    height: 72px;
    line-height:72px;
    border: 1px solid black;
}
.inner {
    display: inline-block;
    vertical-align: middle;
    line-height: normal;
}
<div class="main">
    <div class="inner">Vertically centered text</div>
</div>

Violino


Esta é provavelmente a maneira mais simples ... todas as outras respostas nesta página são desnecessariamente desajeitadas / hacky OU não são suportadas em navegadores antigos OU dependem do conhecimento da altura do elemento interno. Você realmente não precisa do line-height: normal;e display:inline;também funciona. O bônus desse método é que ele não interfere text-align:center;, com o qual o uso display: table-cell;pode criar problemas. Muitas vezes, queremos alinhar horizontalmente e verticalmente. Veja este violino editado: jsfiddle.net/br090prs/36
mike-source

2
@ mike-source a razão para usar line-height: normale display: inline-blocké para que o texto interno seja quebrado corretamente. Se você tiver certeza de que o texto na div interna nunca será quebrado, essas propriedades não serão necessárias.
Tim Perkins

Desde que a Microsoft terminou o suporte para versões antigas do IE , usei o flexbox para esse tipo de coisa (como sugeriu @ user1782556). Minha resposta original é o caminho a seguir, se você ainda precisar oferecer suporte ao IE 10 ou mais antigo.
Tim Perkins

100% concorda, mas eu ainda não optaria pessoalmente pelo flex box, apenas 76% dos navegadores o suportam totalmente a partir de maio de 2016 (94% se você incluir suporte parcial), consulte: caniuse.com/#search=flexible% 20box . Está chegando muito perto de ser a opção mais sensata, dependendo da sua base de usuários.
Mike-source

10

Usei isso para alinhar tudo no centro da div do wrapper, caso isso ajude alguém - achei mais simples:

div.wrapper {
  /* --- This works --- */
  display: flex;
  /* Align Vertically */
  align-items: center;
  /* Align Horizontally */
  justify-content: center;
  /* --- ---------- ----- */
  width: 100%;
  height:100px;
  background-color: blue;
}
div.inner {
  width: 50px;
  height: 50px;
  background-color: orange;
}
<div class="wrapper">
  <div class="inner">
  </div>
</div>


7

Aqui você tem um exemplo de duas maneiras de fazer um alinhamento vertical. Eu os uso e eles funcionam muito bem. Um é usando posicionamento absoluto e o outro usando flexbox .

Exemplo de alinhamento vertical

Usando o flexbox, você pode alinhar um elemento sozinho dentro de outro elemento com o display: flex;uso align-self. Se você precisar alinhá-lo horizontalmente, poderá usar align-itemse justify-contentno contêiner.

Se você não quiser usar o flexbox, poderá usar a propriedade position. Se você tornar o contêiner relativo e o conteúdo absoluto, o conteúdo poderá se mover livremente dentro do contêiner. Portanto, se você usar top: 0;e left: 0;no conteúdo, ele será posicionado no canto superior esquerdo do contêiner.

Posicionamento absoluto

Para alinhá-lo, basta alterar as referências superior e esquerda para 50%. Isso posicionará o conteúdo no centro do contêiner no canto superior esquerdo do conteúdo.

Alinhar no meio do contêiner

Portanto, você precisa corrigir isso traduzindo o conteúdo com metade do tamanho para a esquerda e a parte superior.

Absoluto centrado


5

Aqui está um ótimo artigo sobre como alinhar veticamente. Gosto da maneira flutuante.

http://www.vanseodesign.com/css/vertical-centering/

O HTML:

<div id="main">
    <div id="floater"></div>
    <div id="inner">Content here</div>
</div>

E o estilo correspondente:

#main {
   height: 250px;
}

#floater {
   float: left;
   height: 50%;
   width: 100%;
   margin-bottom: -50px;
}

#inner {
   clear: both;
   height: 100px;
}

3
Acho que se você definir a altura do bloco interno, invalida o conceito de centralização vertical adequada. O OPS estava pedindo para torná-lo automático, então eu imagino que isso significa que a altura da caixa interna não é conhecida no momento da concepção.
Alexis Wilke

5

HTML

<div id="myparent">
  <div id="mychild">Test Content here</div>
</div>

CSS

#myparent {
  display: table;
}
#mychild {
  display: table-cell;
  vertical-align: middle;
}

Definimos a div pai para exibir como uma tabela e a div filho para exibir como uma célula da tabela. Podemos então usar o alinhamento vertical na div filho e definir seu valor para o meio. Qualquer coisa dentro dessa div criança será centralizada verticalmente.


4

É simples. Basta adicionar display:table-cellna sua classe principal.

.main {
  height: 72px;
  vertical-align: middle;
  display:table-cell;
  border: 1px solid #000000;
}

Confira este jsfiddle !


4

Aqui está a solução mais simples e mais recente - não há necessidade de alterar nada, basta adicionar três linhas de regras CSS ao seu contêiner da div em que você deseja se concentrar. Eu amo Flex Box#LoveFlexBox

.main {
  /* I changed height to 200px to make it easy to see the alignment. */
  height: 200px;
  vertical-align: middle;
  border: 1px solid #000000;
  padding: 2px;
  
  /* Just add the following three rules to the container of which you want to center at. */
  display: flex;
  flex-direction: column;
  justify-content: center;
  /* This is true vertical center, no math needed. */
}
.inner {
  border: 1px solid #000000;
}
.second {
  border: 1px solid #000000;
}
<div class="main">
  <div class="inner">This box should be centered in the larger box
    <div class="second">Another box in here</div>
  </div>
  <div class="inner">This box should be centered in the larger box
    <div class="second">Another box in here</div>
  </div>
</div>

Bônus

o justify-contentvalor pode ser definido para as seguintes opções:

  • flex-start, que alinhará a div filho até onde o fluxo flexível começa em seu contêiner pai. Nesse caso, ele permanecerá no topo.

  • center, que alinhará a div filho ao centro do contêiner pai. Isso é realmente legal, porque você não precisa adicionar uma div adicional para envolver todos os filhos para colocar o wrapper em um contêiner pai para centralizar os filhos. Por esse motivo, esse é o verdadeiro centro vertical (no column flex-directionarquivo. Da mesma forma, se você alterar o flow-directionpara row, ele ficará centralizado horizontalmente.

  • flex-end, que alinhará a div filho até onde o fluxo flexível termina em seu contêiner pai. Nesse caso, ele será movido para o fundo.

  • space-between, que espalhará todos os filhos desde o início do fluxo até o final do fluxo. Se a demonstração, eu adicionei outra div filho, para mostrar que eles estão espalhados.

  • space-around, semelhante a space-between, mas com metade do espaço no início e no final do fluxo.


Solução perfeita. Os navegadores incompatíveis podem deixar o conteúdo desalinhado e o usuário deve lidar com ele ou atualizar seu navegador.
twicejr

0

Como vertical-alignfunciona como esperado em um td, você pode colocar uma única célula tableno divpara alinhar seu conteúdo.

<div>
    <table style="width: 100%; height: 100%;"><tr><td style="vertical-align: middle; text-align: center">
        Aligned content here...
    </td></tr></table>
</div>

Desajeitado, mas funciona até onde eu sei. Pode não ter os inconvenientes das outras soluções alternativas.


5
Não, por favor, não há mais mesas. CSS pode fazer isso de uma maneira limpa. Não há necessidade de usar <table> neste caso.
enguerranws

0

Basta colocar o conteúdo dentro de uma tabela com altura 100% e definir a altura para a div principal

<div style="height:80px;border: 1px solid #000000;">
<table style="height:100%">
<tr><td style="vertical-align: middle;">
  This paragraph should be centered in the larger box
</td></tr>
</table>
</div>

0

Para centralizar verticalmente um elemento de amplitude ou div dentro de outra div, adicione a posição relativa à div pai e a posição absoluta à div filho. Agora, a div filho pode ser posicionada em qualquer lugar dentro da div. Exemplo abaixo centraliza horizontal e verticalmente.

<div class="parent">
    <div class="child">Vertically and horizontally centered child div</div>
</div>

css:

.parent{
    position: relative;
}
.child{
    position: absolute;
    top: 0;
    bottom: 0;
    left: 0;
    right: 0;
    margin: auto;
}

0

Essa é uma abordagem moderna e utiliza a funcionalidade CSS Flexbox. Agora você pode alinhar verticalmente o conteúdo no contêiner pai, adicionando esses estilos ao .maincontêiner

.main {
        display: flex;
        flex-direction: column;
        justify-content: center;
}

E você está pronto para ir!

Ao utilizar nosso site, você reconhece que leu e compreendeu nossa Política de Cookies e nossa Política de Privacidade.
Licensed under cc by-sa 3.0 with attribution required.