Estava eu passeando pela net fazendo minhas pesquisas para me manter sempre atualizado, quando me deparei com um tutorial do meu amigo Ryan Doherty (link para o tutorial em inglês: http://blog.mozilla.com/webdev/2009/02/20/cross-browser-inline-block/), com uma abordagem bem interessante para resolver a questão o inline-block do CSS que deveria ser algo simples, mas que infelizmente, não funciona em todos os navegadores.
Por isto decidi traduzir o artigo e publicar aqui.
Para notar a importancia do inline-block, imagine que você tem uma lista de produtos de que precisa ser reposicionada de acordo com o redimensionamento do navegador pelo usuário e cujos textos são variáveis em quantidade de caracteres, num layout liquido, assim digamos. A forma mais precisa de se fazer isto é com um lista desordenada.
Veja a solução com o resultado final abaixo:
<style>
li {
width: 200px;
min-height: 250px;
border: 1px solid #000;
display: -moz-inline-stack;
display: inline-block;
vertical-align: top;
margin: 5px;
zoom: 1;
*display: inline;
_height: 250px;
}
</style>
<li>
<div>
<h4>This is awesome</h4>
<img src="http://farm4.static.flickr.com/3623/3279671785_d1f2e665b6_s.jpg"
alt="lobster" width="75" height="75"/>
</div>
</li>
Tutorial traduzido abaixo:
Ah, inline-block, que ilusivamente é, oh, uma declaração de exibição tão tentadora que promete tanto, e que na verdade faz tão pouco.
Muitas vezes eu recebo um PSD como este:
e começo a chorar.
Geralmente, este tipo de layout deveria ser uma moleza. Largura fixa, altura fixa, float à esquerda, e pronto! Maaaaas, o design precisa trabalhar junto com uma quantidade de conteúdo variável, o que significa que se um destes blocos contiver mais conteúdo que os outros, ele irá quebrar o layout:
Pelo fato do primeiro item da galeria ser mais alto do que os demais, o quinto item tem o atributo float:left contra ele ao invés de ficar abaixo. Basicamente, nós queremos um layout com a flexibilidade de uma tabela, mas apropriado, marcação semantica.
Nós começamos com uma simples página com uma lista desordenada e com display ajustado para inline-block:
<ul>
<li>
<h4>This is awesome</h4>
<img src="http://farm4.static.flickr.com/3623/3279671785_d1f2e665b6_s.jpg" alt="lobster" width="75" height="75"/>
</li> <!-- Duplique os elemetos LI aqui para fazer os testes-->
<ul>
<style>
li {
width: 200px;
min-height: 250px;
border: 1px solid #000;
display: inline-block;
margin: 5px;
}
</style>
E ele fica bem no Firefox 3, Safari 3 e Opera
Obviamente, algo está incorreto com o alinhamento vertical. Bem, não exatamente incorreto, porque este é o comportamento correto, mas não é isto que nós queremos.
O que está acontecendo aqui é que a linha base (baseline) de cada <li>está alinha com a linha base de seu pai <ul>. O que é uma linha base, você deve estar perguntando? Uma imagem fala mais do que mil palavras:
A linha base (baseline) é a linha preta passando abaixo do texto acima. Resumindo o máximo, o valor padrão do alinhamento vertical inline ou inline-block de um elemento é a linha base (baseline) , que quer dizer que a linha base do elemento estará alinha com a linha base do elemento ai. Eis aqui a nossa primeira tentativa com inline-block com as linhas bases sendo mostradas:
Como você pode ver, cada linha base é alinha com a linha base do texto “This is the baseline”. Este texto não está em um <li>, mas é somente um nó de texto do pai <ul>, para ilustrar onde esta a linha base do pai.
De qualquer forma, a correção para isto é simples: vertical-align:top, que resultaria numa grade bem atrativa:
Apesar dele ainda não funcionar no Firefox 2, IE6 e 7.
Vamos começar pelo Firefox 2.
O Firefox 2 não suport inline-block, mas suporta uma propriedade display especifica do Mozilla ‘-moz-inline-stack’, que exibe exatamente igual inline-block. E então nós adicionamos ela antes de display:inline-block, FF2 ignora esta declaração e mantem -moz-inline-stack pois ele não suporta inline-block. Navegadores que suportem inline-block irão utiliza-lo e igrnora a propriedade anterior.
<style>
li {
width: 200px;
min-height: 250px;
border: 1px solid #000;
display: -moz-inline-stack;
display: inline-block;
vertical-align: top;
margin: 5px;
}
</style>
Infelizmente, ele possui um bug:
Sinceramente, eu não sei o que causa este bug. Mas há uma correção rápida. Envolva tudo dentro do <li> com um <div>.
<ul>
<li>
<div>
<h4>This is awesome</h4>
<img src="http://farm4.static.flickr.com/3623/3279671785_d1f2e665b6_s.jpg" alt="lobster" width="75" height="75"/>
</div>
</li>
<ul>
Ele parece “resetar” tudo dentro do <li>e faz com que eles exibam apropriadamente:
Agora, partindo para o IE 7. O IE 7 não suporta inline-block, mas nós podemos fazer um truque para que ele exiba os <li>s
como se eles fossem inline-block. Como? hasLayout,
uma propriedade magica que permite todos os tipos de divertimento! Nós não podemos ajustar hasLaout explicitamente em um elemento com hasLayout:true; ou qualquer coisa facil como esta, mas podemos disparar com outra declaração como zoom:1.
Tecnicamente, o que hasLayout significa é que um elemento com hasLayout configurado pra true seja responsável pela exibição de si mesmo e de seus filhos ( combinando ele com um min-height e width, e acabamos tendo algo muito similar com display:block). Isto é um tipo de coisa mágica que você pode usar à vontade para problemas com renderização e fazê-los desaparecer.
Quando adicionamos zoom:1 e *display:inline (hack estrela para alcançar IE6 & 7)aos <li>s, nós fazemos o IE 7 display exibi-los como se eles fossem inline-block:
<style>
li {
width: 200px;
min-height: 250px;
border: 1px solid #000;
display: -moz-inline-stack;
display: inline-block;
vertical-align: top;
margin: 5px;
zoom: 1;
*display: inline;
}
</style>
Ebá! Quase pronto. Só resta o IE 6:
O IE 6 não suporta min-height, mas graças à sua inadequada manipulação da propriedade height, nós podemos usar esta ao invés. Definindo _height (IE6 underscore hack) para 250px fará com que todos os <li>s tenham um height de 250px, e se o conteúdo deles for maior do que isto, ele expandirá até se ajustar. Todos os outros navegadores irão ignorar _height.
E após todo este trabalho, eis o CSS e o HTML finais:
<style>
li {
width: 200px;
min-height: 250px;
border: 1px solid #000;
display: -moz-inline-stack;
display: inline-block;
vertical-align: top;
margin: 5px;
zoom: 1;
*display: inline;
_height: 250px;
}
</style>
<li>
<div>
<h4>This is awesome</h4>
<img src="http://farm4.static.flickr.com/3623/3279671785_d1f2e665b6_s.jpg"
alt="lobster" width="75" height="75"/>
</div>
</li>
5 respostas em “Cross-browser Inline-block”
Excelente!!!
Funciona perfeitamente, obrigado.
Bela solu??o!
Funciona maravilhosamente bem!
Testado em IE 7/8 – Chrome – F.F 3.6!
=D
Obrigado!
?timo combo zoom:1 + *display:inline
funcionou perfeitamente no IE 7 e 6. Resolveu meu problema!
Value!!
Caracaaa!!! cara e num ? que deu certo mesmo!! kkkkkk
Brigad?o!!!!!!!
Que bom que deu certo!