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.