Web,ruby, Ajax ou qualquer outra coisa que me venha a cabeça (com prioridade para esta última)

20 outubro, 2005

Limpeza de Primavera (de facto de Inverno)

A equipa de de desenvolvimento do Internet Explorer pede que os programadores de página as limpem de truques CSS que possam falhar no IE7 quando publicado. Assim vou falar-lhe do que sei sobre o assunto e como é que criei uma concepção de emergência há já uns dois meses.

O meu plano não era no início criar código que fosse à prova do futuro mas para retirar tantos truques de CSS quanto possível para reescrever um pequeno síte tipo brochura, rapidamente e depois passá-lo a outro responsável de desenvolvimento cuja experiência e capacidades me eram desconhecidas. O resultado final foi retirar quase todos os truques excepto um. Um efeito secundário foi tornar o código mais estruturado e mais fácil de manter (julgo) e mais lógico.

Para que servem os truques CSS

Os truques CSS permitem aos responsáveis pelo desenvolvimento de páginas web enviar um conjunto de regras diferentes a diferentes navegadores, normalmente (paradoxalmente) para que cada navegador reproduza o site com o mesmo aspecto. É necessário normalmente visto o Internet Explorer 5 e 6 terem muitos defeitos e assim tornarem más boas regras.

Há dois tipos de truques CSS:

  • Análise - Os truques de erro baseiam-se no facto do navegador deixar de ler quando numa regra vê uma combinação esquisita de caracteres tal como“\”}\”", enquanto o navegador "Y" continua e recebe as regras que se lhe seguem. O problema com isto é que se não estiverem bem comentadas não se percebe o que fazem pois estão mal documentadas.
  • Truques devidos a suporte incompleto das CSS - usa o facto de o IE não poder suportar selectores avançados CSS, e o responsável pelo desenvolvimento usa esses selectores para alimentar um navegador mais avançado. O problema com estes é que o IE7 está a aparecer no horizonte e irá perceber estas regras. Pode ou não haver um problema, mas se quizer ter a certeza de que o seu sítio não rebenta com o IE7 deve tratar deste assunto.

Há uma imensidade de truques CSS documentados, mas um dos mais usados é o truque do modelo de caixa devido ao modelo de caixa errado no IE5. É um truque de erro de análise, a maior parte do qual existe para enganar os navegadores para verem ou não o truque. Por exemplo, todos os contorcionismos da "voice family" existe para enganar o IE5 para não ler o resto da regra, de forma a não sobrepôr as suas dimensões excessivamente grandes:


  #conteudo{margin:0; padding: 0 15px;
  width: 194px; /*IE 5.5 Truque do Tantek *
  voice-family: "\"}\"";
  voice-family:inherit;
  width: 164px; /*Largura devida*/ }
  html>body #conteudo{
  width:164px;}
 

Uma segunda regra ("html>body") é uma regra para ser simpático com o Opera pois o Opera também pararia no lixo da "voice family" e herdaria 194px, o que não desejamos e o seu modelo de caixa está correcto. Agora no IE7 embora leia a regra simpática para o Opera essa será a largura necessária de qualquer modo e nenhum dano é feito.

Com a excepção do pobrezinho que venha depois de mim, poluir o CSS desta forma ofende a alma. Visto tudo isto servir para corrigir um defeito do Internet Explorer seria ou não muito bom se pudessemos ter uma folha de estilo, boa, válida, sem truques e uma com a marcação para o IE5! Isto é consigo! Podemos usando comentários condicionais.

Como funcionam os comentários condicionais

Isto são comentários html, com um marcador de forma a que o Internet Explorer os distinga e pode usá-los para envolver qualquer código html - incluindo a ligação a folhas de estilo. Visto serem comentários html são invisíveis aos restantes navegadores e passam a validação, pelo menos de um ponto de vista formal.

Eis a sintaxe que uso para alimentar regras para o IE5:


 <link rel="stylesheet" href="estilos.css" type="text/css" />
 <!--[if < IE 6]>
 <link rel="stylesheet"  href="modelocaixa.css" type="text/css" />
 <![endif]-->

Assim o ficheiro principal estilos.css tem uma regra simples:


 #conteudo{margin:0; padding: 0 15px;
 width: 164px;} /*ver modelocaixa.css para regra específica do IE5 */
e o ficheiro modelocaixa.css - que seria só servido ao IE5 - utilizaria esta regra:

 #conteudo{width: 194px;} /*as outras regras encontram-se em estilos.css */

Nada de truques "voice-family" ou regras de simpatia para o Opera! Porreiro!

AsneirasIE.css - Correção dos principais erros do IE6 e anteriores

Muitos dos truques são usados para alimentar o IE6 e anteriores versões para compensar a ausência de capacidades importantes de um desenvolvimento moderno da Web como por exemplo transparência Alfa de ficheiros PNG, "min-height" (altura mínima de um elemento) CSS, por exemplo.

Podemos retirar os truques chamando uma folha de estilos designada por AsneirasIE.css para navegadores Internet Explorer com versão igual ou anterior à 6, desta forma:


 <!--[if lte IE 6]>
 <link rel="stylesheet"  href="AsneirasIE.css" type="text/css" />
 <![endif]-->

Simulação de "min-height"

Suponha que tem uma caixa que nunca deve ter uma altura inferior a 100px - pode ter por exemplo uma imagem de fundo com 95px que deseja que seja vista sempre, mas não pode prever a quantidade de conteúdo. Num navegador respeitador das normas utilizaria "min-height", o que não funciona nas actuais versões de produção do IE.

Para contornar este problema adicionamos uma regra especificando a altura (que funciona da mesma forma que min-height devia funcionar). Assim a regra na folha de estilos principal temos algo como #caixa {min-height:100px;} que no AsneirasIE deve ser ultrapassado por


 #caixa {height:100px; overflow:visible;} /*simula min-height */

Dar GIFs ao IE e PNGs aos bons

Muita gente que tem uma maior orientação para a componente gráfica das páginas do que eu já usa há muito tempo o formato PNG nas suas páginas visto permitir uma maior liberdade. Infelizmente o IE6 não usa o PNG de forma adequada e assim temos vindo a usar um outro truque para enviar GIF ao IE e PNG aos restantes. Eis um exemplo do truque * html que só o IE entende:


 #amoroso  {background: url(amoroso.png) no-repeat;}
 * html #amoroso {background: url(amoroso.gif) no-repeat;}

Agora que o IE7 pode usar adequadamente os PNG e não irá compreender a regra * html, irá receber o PNG enviado com a primeira regra: tudo bem. Mas esta regra é para navegadores pré IE7 e assim deve ser enviado para o canil AsneirasIE.CSS.

Uma vez banido deixará de ser necessário o prefixo * html visto a folha de estilo ser só enviada para IE<7, e irá ultrapassar a regra principal. Assim a folha de estilo principal mantem:

#amoroso  {background: url(amoroso.png)no-repeat;}

e no AsneirasIE.css é adicionado


 #amoroso {background: url(amoroso.gif) no-repeat;}

Evitar que palavras muito compridas estraguem o layout

Ao contrário do que as especificações determinam o IE permite que palavras muito compridas deitem para fora da caixa em que estejam - o que pode facilmente destruir um arranjo de página se outras caixas flutuarem para a direita o que pode ser perigoso quando o conteúdo não pode ser rigidamente controlado e testado, tal como em comentários de diários onde uma pessoa pode acidentalmente (ou maliciosamente) inserir uma palavra particularmente grande que estrague o arranjo.

Há uma extensão CSS específica do Internet Explorer a qual corrige o problema mas não é validável. Por mim estou perfeitamente satizfeito quando uso lixo para corrigir o lixo do IE em particular fora da folha de estilos principal claro que os puristas me podem bater na cabeça.

Adicione esta regra à caixa que contem os comentários do seu diário (blog) (ou faça como eu adicione ao marcador «body»):


body {word-wrap: break-word;}
(Não sei se o IE7 elimina este erro e por isso talvez seja melhor colocar esta regra numa folha de estilo para todos os navegadores IE - cf. IE.css).

Correção IE6 avançada

No caso de o design do seu site exigir uma capacidade de poder ter um comportamento "hover" (rato por cima) num elemento que não seja uma âncora (<a>) o IE normalmente impede-o de o fazer. Pode adicionar o comportamento csshover na folha de estilo AsneirasIE:


body { behavior:url("csshover.htc"); }

(Pode ainda simular a totalidade do IE7 com a Biblioteca de JavaScript do Dean Edwards, usando comentários condicionais para puxar a biblioteca JavaScript.)

Outra razão potêncial para um IE.css que ainda não investiguei a fundo pode ser adicionar Arranjo IE a certos elementos que podem ajudar a corrigir tantos erros de reprodução do IE6.

IE.css - alimentar de estilos todas as versões IE

Outro bom uso de comentários condicionais é segregar extensões só do IE de CSS normalizado, pois tais extensões se usadas na folha principal de estilos fazem com que esta não seja validada (e não são necessárias em navegadores que não o IE e portanto não devem sequer ser enviadas).

Tais extensões são por exemplo filtros para imagens, ou elevadores lateriais coloridos.

Eis o código para a cabeça da página:


 <!--[if  IE]>
 <link rel="stylesheet"  href="IE.css" type="text/css" />
 <![endif]-->

Se não necessita destas extensões ou não se importa de ter este tipo de coisa na sua folha de estilos principal que não poderá ser validada (e num mundo prático, não há nenhum efeito secundário pernicioso se o fizer pode simplesmente deixar isto na folha de estilos principal, embora eu prefira separar isto completamente.

IE/Mac: o novo Netscape 4

Não sendo bafejado pela sorte para usar um Mac, não testei isto que se segue, mas por razões de alargamento do âmbito aqui vai. O quirksmode diz-nos que os comentários condicionais só funcionam no IE/ Windows. Se necessitar de fornecer regras ao IE/Mac (que nos dizem estar tão moribundo quanto o Netscape 4), há truques disponíveis, mas deve levar em conta a possibilidade de os importar numa folha especifica onde tenha todas as regras para o IE/Mac:


 <style type="text/css">
 @import("IEMac.css");
 </style>

A formatação de importação deve ser exactamente como mostrado acima. (A nota do chapéu)

Em Resumo

Para recapitular eis todo o código que deve figurar no «header» (cabeçalho) (é provável que não necessite dele todo):


 <link rel="stylesheet" href="styles.css" type="text/css" />
 <!--[if  IE]>
  <link rel="stylesheet"  href="IE.css" type="text/css" />
 <![endif]-->
 <!--[if <= IE 6]>
  <link rel="stylesheet"  href="AsneirasIE.css" type="text/css" />
 <![endif]-->
 <!--[if < IE 6]>
  <link rel="stylesheet"  href="modelocaixa.css" type="text/css" />
 <![endif]-->
 <style type="text/css">
 @import("IEMac.css");
 </style>

Reduzindo os pedidos http

Cada folha de estilo puxada exige um pedido extra http, o que pode fazer com que as coisas fiquem mais lentas pois os obreiros do http podem ficar facilmente cansados. Assim, de forma a minimizar os seus esforços pode juntar todos os truques relativos ao IE num único ficheiro mas teria que manter mesmo neste caso um ficheiro separado para o truque do modelo da caixa para o IE5 de forma a que este fique com a caixa maior. Para enviar 164px ao IE6 e 194px ao IE5 é necessário recorrer como anteriormente ao voice-family para o IE mas não ao Ser Simpático com o Opera. Eis o código:

 #conteudo{width: 194px; /*Largura IE 5.5 truque do Tantek */
 voice-family: "\"}\"";
   voice-family:inherit;
 width: 164px; /*largura devidah*/ }

O grão de areia no teste

Se usar as versões de teste múltiplas do IE, não entre em pânico quando o seu modelo de caixa (modelocaixa.css) parecer não funcionar. Independentemente de qual o IE que manda executar para teste o analisador de comentários condicionais julga que está a usar a última versão instalada. Para aqueles que se sentem confortáveis a alterar directamente o Registo há uma solução (Chapelada de Simon Pieters).

Final

Embora não tenha objecções religiosas ao uso de truques CSS, temos que ter em conta que rapidadamente o novo navegador da MS chegará ao mercado. É boa prática, de desenvolvimento, modularizar o nosso código espera-se que o IE7 um ano após o respectivo lançamento se torne no principal navegador (não sei de onde vem esta previsão) e assim os truques podem deixar de ser tão úteis.

Pessoalmente acho mais fácil desenvolver em Firefox em primeiro lugar com uma folha de estilo limpinha, quando as coisas ficam esquisitas o validador de CSS é uma ferramenta últil de diagnóstico. Este utilitário fica maluco quando as folhas de estilo ficam cheias de truques. Assim gosto de ter tudo a funcionar num browser moderno e só depois aplico os truques, usando comentários condicionais.

Quer acredite que alimentar os navegadores diferentes com conteúdos diferentes é filosoficamente válido ou o Trabalho do Diabo que irá resultar Na Destruição da Web é algo que não me preocupa grandemente. Pode ter a opinião de que sendo específicos do IE os comentários condicionais são ainda piores do que os truques css. Assim seja, está no seu direito. Sou um purista pragmático e esta metodologia funciona comigo.

Vejamos então, sr. Santos

É fantástico que a Microsoft esteja

  1. a escutar e
  2. fale conosco
. Chegou o momento de começarmos a brincar com a versão beta do IE7 e ver o que sucede e dar a nossa opinião à sua equipa de desenvolvimento de forma a que melhore.

Actualização: E os comutadores de folhas de estilo?

Esta técnica funciona quando se pode estabelecer um número relativamente baixo de navegadores alvo. No caso do seu site ter várias peles que sejam carregadas com folhas alternativas poderá que ter que manter os truques CSS. Tudo bem. A maior parte dos seus truques devem funcionar no IE7 (embora fosse bom que tal seja testado

Estou a falar de sítios com uma capacidade quase camaliónica ao nível de um Zen Garden onde a totalidade da página muda de arranjo. Estou a construir um sítio que se limita a permitir ao utilizador alterar tipos de letra, combinações de cores, etc. E isto pode ser facilmente efectuado com as técnicas do comentário condicional visto que nesse aspecto o IE não estar tão roto que necessite de páginas alternativas para declarações de cores e tipos.

E um dia, quando o IE6 desaparecer simplesmente tiro os comentários condicionais e com um sorriso apago o AsneirasIE.css do meu servidor. Um dia.

Bem sei que os comentários não são uma forma totalmente correcta de fornecer conteúdos alternativos a vários navegadores contudo parece-me a forma mais pragmática de o fazer.

Segunda observação de encerramento sei que não usei os truques mais breves para fazer algumas das coisas por exemplo o truque relativo à largura poderia ser feito como aqui:

width:164px;width /**/: 194px;

Mas tal em minha opinião tem um defeito não ter comentários.

P.S. Onde virem no código < vejam lt e onde virem <= vejam lte

Sem comentários: