Texto de alinhamento vertical CSS dentro de li

99

Estou exibindo várias caixas em uma linha com altura e largura fixas, geradas a partir de <li> tags. agora preciso alinhar o texto no centro vertical. O alinhamento vertical do CSS não tem impacto, talvez eu esteja faltando alguma coisa ???

Não estou procurando truques usando (margem, preenchimento, altura da linha), eles não funcionarão porque alguns textos são longos e se quebram em duas linhas.

Encontre o código real:

Código CSS

ul.catBlock{
  width:960px; 
  height: 270px; 
  border:1px solid #ccc; 
}

ul.catBlock li{
  list-style: none; 
  float:left; 
  display:block; 
  text-align: center; 
  width:160px; 
  height: 100px;
}

ul.catBlock li a{ 
  display: block;  
  padding: 30px 10px 5px 10px; 
  height:60px;
}

Código HTML

<ul class="catBlock">
 <li><a href="#">IP Phone</a></li>
 <li><a href="#">Dual SIM Switch Server</a></li>
 <li><a href="#">IP PBX</a></li>
</ul>
AK4668
fonte
2
você pode precisar fornecer mais informações. As caixas têm a mesma altura? Você está alinhando o texto dentro das caixas na li? "porque alguns textos são longos ... duas linhas" ??? Pode ser uma captura de tela ou um violino ajudaria.
KMC
1
Tentei postar uma captura de tela, mas não permite, pois minha conta é nova.
AK4668 de

Respostas:

100

Defina o pai com display: tablee o próprio elemento com vertical-align: middlee display: table-cell.

Asaf Chertkoff
fonte
4
1 para usar a tabela de exibição / célula de tabela. Parece que muitas pessoas não estão cientes de sua existência.
powerbuoy
5
Isso é de W3CSchool ... Observação: Os valores "tabela inline", "run-in", "tabela", "legenda da tabela", "célula da tabela", "coluna da tabela", "coluna da tabela group "," table-row "," table-row-group "e" inherit "não são suportados no IE7 e anteriores. O IE8 requer um! DOCTYPE. IE9 suporta os valores.
AK4668
20
esta solução é uma merda, pois bloqueia completamente qualquer efeito de margem. A única solução para isso é criar toneladas de pseudo-elementos. Por que o css é uma merda tanto.
Muhammad Umer
Que tal <li>ficar em uma única linha?
polkovnikov.ph
1
Além disso, isso não é compatível com a acessibilidade CATO se você, de fato, NÃO estiver exibindo dados tabulares.
Stevo Perisic
59

line-heighté como você alinha o texto verticalmente. É bastante normal e não o considero um "hack". Basta adicionar line-height: 100pxao seu ul.catBlock lie tudo ficará bem.

Nesse caso, pode ser necessário adicioná-lo a, ul.catBlock li apois todo o texto dentro de litambém está dentro de um a. Já vi coisas estranhas acontecerem quando você faz isso, então tente as duas e veja qual delas funciona.

Logan Serman
fonte
21
Usei a altura da linha inicialmente, mas quando o conteúdo for longo, ele se dividirá em 2 linhas e, digamos, uma lacuna de 100px em cada linha fará com que pareça pior. existe alguma outra maneira?
AK4668
2
Eu acho que há uma maneira de ter, vertical-align: middlese você tiver display: table-cell. Eu nunca usei isso. Dê uma olhada aqui: phrogz.net/css/vertical-align/index.html
Logan Serman
Ótima solução - eu defino o li 'line height' para ser o mesmo que min-height, e o texto é alinhado verticalmente - pelo menos perto o suficiente para uma inspeção visual. A solução de 'tabela' acima certamente não é semântica e é hackish por natureza. Sempre que fazemos isso, aumentamos as chances de telas quebradas ou comportamento estranho em algum lugar do cenário responsivo.
CodeFinity
Obrigado! Funciona muito bem no elemento <a>! Que solução simples :-) Basta ajustá-lo para corrigir o valor e centrar verticalmente perfeito!
Asle
45

Por mais anos que esta resposta possa estar atrasada, qualquer pessoa que encontrar isso pode apenas querer tentar

li {
    display: flex;
    flex-direction: row;
    align-items: center;
}

O suporte do navegador para flexbox é muito melhor do que era quando @scottjoudry postou sua resposta acima, mas você ainda pode querer considerar prefixar ou outras opções se estiver tentando oferecer suporte a navegadores muito mais antigos. caniuse: flex

Flyingace
fonte
Isso não list-style-image
combina
1
Eu usei isso no bootstrap 4 nav-item e funcionou perfeitamente. THX.
010110110101
flex box salvando ao vivo como sempre
Arthur Medeiros
16

Surpreendentemente (ou não), a vertical-alignferramenta realmente funciona melhor para esse trabalho. O melhor de tudo é que nenhum Javascript é necessário.

No exemplo a seguir, estou posicionando a outerclasse no meio do corpo e a innerclasse no meio da outerclasse.

Visualização: http://jsfiddle.net/tLkSV/513/

HTML:

<div id="container">
    <span></span><div class="outer">
        <span></span><div class="inner">

        </div>
    </div>
</div>

CSS:

html, body {
    height: 100%;
    margin: 0;
    padding: 0; }
#container {
    text-align: center;
    height: 100%; }
span { 
    height: 100%;
    vertical-align: middle;
    display: inline-block; }
.outer {
    width: 100px;
    height: 200px;
    padding: 0;
    border: 1px solid #000;
    vertical-align: middle;
    display: inline-block; }
.inner {
    background: red;
    width: 30px;
    height: 20px;    
    vertical-align: middle;
    display: inline-block; }

O alinhamento vertical funciona alinhando os centros dos elementos que estão próximos uns dos outros. Aplicar o alinhamento vertical a um único elemento não faz absolutamente nada. Se você adicionar um segundo elemento que não tem largura, mas é a altura do contêiner, seu único elemento se moverá para o centro vertical com este elemento sem largura, centralizando-o verticalmente. Os únicos requisitos são que você defina ambos os elementos como inline (ou inline-block) e defina seu atributo de alinhamento vertical como vertical-align: middle.

Nota: Você pode notar no meu código abaixo que minha <span>tag e <div>tag estão se tocando. Como ambos são elementos inline, um espaço adicionará um espaço entre o elemento no-width e seu div, portanto, certifique-se de deixá-lo de fora.

Wex
fonte
1
Fantástico, faz sentido. // Não posso votar sua resposta agora porque minha reputação mínima deve ser 15.
AK4668
1
Para aqueles de vocês que procuram esta técnica aplicada diretamente à pergunta - jsfiddle.net/utGVt/385
Wex
15

No futuro, esse problema será resolvido pelo flexbox. No momento, o suporte do navegador é desanimador, mas é compatível de uma forma ou de outra em todos os navegadores atuais.

Suporte para navegador: http://caniuse.com/flexbox

.vertically_aligned {

    /* older webkit */
    display: -webkit-box;
    -webkit-box-align: center;
    -webkit-justify-content: center;

    /* older firefox */
    display: -moz-box;
    -moz-box-align: center;
    -moz-box-pack: center;

    /* IE10*/
    display: -ms-flexbox;
    -ms-flex-align: center;
    -ms-flex-pack: center;

    /* newer webkit */
    display: -webkit-flex;
    -webkit-align-items: center;
    -webkit-box-pack: center;

    /* Standard Form - IE 11+, FF 22+, Chrome 29+, Opera 17+ */
    display: flex;
    align-items: center;
    justify-content: center;
}

Histórico do Flexbox: http://css-tricks.com/snippets/css/a-guide-to-flexbox/

Scott Joudry
fonte
1
No momento em que esta pergunta foi feita, não tenho certeza se essa seria uma boa resposta, mas hoje estamos vendo ~ 95% de suporte prefixado, então certamente acho que esta é uma opção viável.
Wex
Se você deseja que os elementos <li> sejam quebrados (em vez de serem reduzidos), adicione flex-wrap: wrap; no nível <ul>
Thierry
Que elemento devo adicionar esta classe também?
Matt M.
6

Não há respostas perfeitas fornecidas aqui, exceto a resposta de Asaf que não fornece nenhum código ou exemplo, então eu gostaria de contribuir com a minha ...

Para fazer vertical-align: middle;funcionar, você precisa usar display: table;para seu ulelemento e display: table-cell;para lielementos e do que pode usar vertical-align: middle;para lielementos.

Você não precisa fornecer nenhum conteúdo explícito margins, paddingspara tornar seu texto verticalmente no meio.

Demo

ul.catBlock{
    display: table;
    width:960px; 
    height: 270px; 
    border:1px solid #ccc; 
}

ul.catBlock li {
    list-style: none;
    display: table-cell; 
    text-align: center; 
    width:160px; 
    vertical-align: middle;
}

ul.catBlock li a { 
    display: block;
}
Sr. estrangeiro
fonte
Isso não ajuda, pois o único motivo pelo qual ele foi alinhado verticalmente é porque você o forçou para baixo com preenchimento na tag a
str11
@ Mr.Alien, vou reiterar que o único problema com esta solução é que as regras de margem são ignoradas.
Thomas
4

Conforme explicado aqui: https://css-tricks.com/centering-in-the-unknown/ .

Conforme testado na prática real, a solução mais confiável, porém elegante, é inserir um elemento embutido auxiliar no <li />elemento como o primeiro filho, cuja altura deve ser definida como 100% (da altura de seu pai, o <li />), e seu vertical-aligndefinido como meio . Para fazer isso, você pode colocar um <span />, mas a maneira mais conveniente é usar a li:afterpseudo classe.

Captura de tela: insira a descrição da imagem aqui

ul.menu-horizontal {
    list-style-type: none;
    margin: 0;
    padding: 0;
    display: inline-block;
    vertical-align: middle;
}

ul.menu-horizontal:after {
    content: '';
    clear: both;
    float: none;
    display: block;
}

ul.menu-horizontal li {
    padding: 5px 10px;
    box-sizing: border-box;
    height: 100%;
    cursor: pointer;
    display: inline-block;
    vertical-align: middle;
    float: left;
}

/* The magic happens here! */
ul.menu-horizontal li:before {
    content: '';
    display: inline;
    height: 100%;
    vertical-align: middle;
}
Jeff Tian
fonte
1

Experimente esta solução

Funciona melhor na maioria dos casos

você pode ter que usar div em vez de li para isso

.DivParent {
    height: 100px;
    border: 1px solid lime;
    white-space: nowrap;
}
.verticallyAlignedDiv {
    display: inline-block;
    vertical-align: middle;
    white-space: normal;
}
.DivHelper {
    display: inline-block;
    vertical-align: middle;
    height:100%;
}
<div class="DivParent">
    <div class="verticallyAlignedDiv">
        <p>Isnt it good!</p>
     
    </div><div class="DivHelper"></div>
</div>

keshav
fonte
1
Por que isso precisa de um divHelper para alinhar verticalmente? Eu vi em outro tópico, mas não consigo entender porque não se alinha sem outra div ..
Sasha Chirico
0

Solução simples para o alinhamento vertical do meio ... para mim, funciona perfeitamente

ul{display:table; text-align:center; margin:0 auto;}
li{display:inline-block; text-align:center;}
li.items_inside_li{display:inline-block; vertical-align:middle;}
Fahad Ali
fonte