Eu quero ter um menu vertical com uma altura específica.
Cada filho deve preencher a altura dos pais e ter um texto alinhado ao meio.
O número de filhos é aleatório, então eu tenho que trabalhar com valores dinâmicos.
Div .container
contém um número aleatório de filhos ( .item
) que sempre precisam preencher a altura do pai. Para conseguir isso, usei o flexbox.
Para criar links com o texto alinhado ao meio, estou usando a display: table-cell
técnica. Mas o uso de exibições de tabela exige o uso de uma altura de 100%.
Meu problema é que .item-inner { height: 100% }
não está funcionando no webkit (Chrome).
- Existe uma correção para esse problema?
- Ou existe uma técnica diferente para fazer com que todos
.item
preencham a altura dos pais com o texto alinhado na vertical ao meio?
Exemplo aqui jsFiddle, deve ser visualizado no Firefox e Chrome
.container {
height: 20em;
display: flex;
flex-direction: column;
border: 5px solid black
}
.item {
flex: 1;
border-bottom: 1px solid white;
}
.item-inner {
height: 100%;
width: 100%;
display: table;
}
a {
background: orange;
display: table-cell;
vertical-align: middle;
}
<div class="container">
<div class="item">
<div class="item-inner">
<a>Button</a>
</div>
</div>
<div class="item">
<div class="item-inner">
<a>Button</a>
</div>
</div>
<div class="item">
<div class="item-inner">
<a>Button</a>
</div>
</div>
</div>
css
google-chrome
webkit
flexbox
Ricardo Castañeda
fonte
fonte
top:0
eleft:0
fazê-lo aparecer conforme o esperado.Respostas:
Solução
Use contêineres flexíveis aninhados.
Livre-se das alturas percentuais. Livre-se das propriedades da tabela. Livre-se
vertical-align
. Evite posicionamento absoluto. Basta ficar com o flexbox todo o caminho.Aplique
display: flex
ao item flex (.item
), tornando-o um contêiner flex. Isso define automaticamentealign-items: stretch
, o que instrui o filho (.item-inner
) a expandir toda a altura do pai.Importante: Remova as alturas especificadas dos itens flexíveis para que este método funcione. Se uma criança tiver uma altura especificada (por exemplo
height: 100%
), ela ignorará aalign-items: stretch
vinda dos pais. Para que ostretch
padrão funcione, a altura da criança deve ser calculada comoauto
(explicação completa ).Tente isso (sem alterações no HTML):
Mostrar snippet de código
Demonstração do jsFiddle
Explicação
Não está funcionando porque você está usando a porcentagem de altura de uma maneira que não está de acordo com a implementação tradicional da especificação.
Em outras palavras, para que a altura percentual funcione em um filho em fluxo, o pai deve ter uma altura definida.
No seu código, o contêiner de nível superior tem uma altura definida:
.container { height: 20em; }
O contêiner de terceiro nível tem uma altura definida:
.item-inner { height: 100%; }
Mas entre eles, o contêiner de segundo nível -
.item
- não tem uma altura definida. Webkit vê isso como um link ausente..item-inner
está dizendo ao Chrome: me dêheight: 100%
. O Chrome procura referência nos pais (.item
) e responde: 100% do que? Não vejo nada (ignorando aflex: 1
regra que existe). Como resultado, aplica-seheight: auto
(altura do conteúdo), de acordo com as especificações.O Firefox, por outro lado, agora aceita a altura flexível de um pai como referência para a porcentagem de altura da criança. O IE11 e o Edge também aceitam alturas flexíveis.
Além disso, o Chrome aceitará
flex-grow
como uma referência pai adequada se usado em conjunto comflex-basis
(qualquer valor numérico funciona (auto
não funcionará), inclusiveflex-basis: 0
). No momento da redação deste artigo, no entanto, essa solução falha no Safari.Mostrar snippet de código
Quatro Soluções
1. Especifique uma altura em todos os elementos pai
Uma solução confiável entre navegadores é especificar uma altura em todos os elementos pai. Isso evita a falta de links, que os navegadores baseados no Webkit consideram uma violação das especificações.
Observe que
min-height
emax-height
não são aceitáveis. Deve ser aheight
propriedade.Mais detalhes aqui: Trabalhando com a
height
propriedade CSS e os valores percentuais2. Posicionamento relativo e absoluto do CSS
Aplique
position: relative
aos pais eposition: absolute
à criança.Tamanho da criança com
height: 100%
ewidth: 100%
ou use as propriedades de deslocamento:top: 0
,right: 0
,bottom: 0
,left: 0
.Com o posicionamento absoluto, a altura percentual funciona sem uma altura especificada no pai.
3. Remova os contêineres HTML desnecessários (recomendado)
Há necessidade de dois contêineres por aí
button
? Por que não remover.item
ou.item-inner
, ou ambos? Embora osbutton
elementos às vezes falhem como contêineres flexíveis , eles podem ser itens flexíveis. Considere criarbutton
um filho.container
ou.item
remover uma marcação gratuita.Aqui está um exemplo:
Mostrar snippet de código
4. Recipientes flexíveis aninhados (recomendado)
Livre-se das alturas percentuais. Livre-se das propriedades da tabela. Livre-se
vertical-align
. Evite posicionamento absoluto. Basta ficar com o flexbox todo o caminho.Aplique
display: flex
ao item flex (.item
), tornando-o um contêiner flex. Isso define automaticamentealign-items: stretch
, o que instrui o filho (.item-inner
) a expandir toda a altura do pai.Importante: Remova as alturas especificadas dos itens flexíveis para que este método funcione. Se uma criança tiver uma altura especificada (por exemplo
height: 100%
), ela ignorará aalign-items: stretch
vinda dos pais. Para que ostretch
padrão funcione, a altura da criança deve ser calculada comoauto
(explicação completa ).Tente isso (sem alterações no HTML):
Mostrar snippet de código
jsFiddle
fonte
Solução: Remover
height: 100%
em .item-interior e adicionardisplay: flex
em .itemDemo: https://codepen.io/tronghiep92/pen/NvzVoo
fonte
A especificação de um atributo flex para o contêiner funcionou para mim:
Isso garante que a altura seja definida e também não cresça.
fonte
Para o Mobile Safari Há uma correção no navegador. você precisa adicionar -webkit-box para dispositivos iOS.
Ex.
se você estiver usando a
align-items: stretch;
propriedade do elemento pai, remova oheight : 100%
do elemento filho.fonte
Eu tive um problema semelhante no iOS 8, 9 e 10 e as informações acima não puderam corrigi-lo, no entanto, descobri uma solução depois de um dia trabalhando nisso. Concedido que não funcionará para todos, mas, no meu caso, meus itens foram empilhados em uma coluna e tinham 0 altura quando deveria ter sido a altura do conteúdo. Mudar o css para ser linha e quebra resolveu o problema. Isso só funciona se você tiver um único item e eles estiverem empilhados, mas como levei um dia para descobrir isso, pensei em compartilhar minha correção!
fonte
Eu tive um bug semelhante, mas enquanto usava um número fixo para altura e não uma porcentagem. Era também um contêiner flexível dentro do corpo (que não possui altura especificada). Parecia que, no Safari, meu container flexível tinha uma altura de 9px por algum motivo, mas em todos os outros navegadores, ele exibia a altura correta de 100px especificada na folha de estilo.
Consegui fazê-lo funcionar adicionando as propriedades
height
emin-height
à classe CSS.O seguinte funcionou para mim no Safari 13.0.4 e no Chrome 79.0.3945.130:
Espero que isto ajude!
fonte