Cross-browser Inline-block

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 comentários sobre “Cross-browser Inline-block

Deixe uma resposta

O seu endereço de email não será publicado Campos obrigatórios são marcados *

Você pode usar estas tags e atributos de HTML: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <strike> <strong>

 

WP-SpamFree by Pole Position Marketing

Please note: JavaScript is required to post comments.