Como “consertar” o position:fixed no IE.

Que era minha pergunta de ontem, mas ninguém respondeu… Apelei, claro, pro labirinto de Falken, que me respondeu em charadas, mas por fim respondeu. A dica que me foi útil veio daqui, e é uma gambiarra sem tamanho: Já que essa melda não funciona, use javascript e boas!

E foi o que fiz. Agora minha barra lateral de propagandas (aleatória, como sempre) funciona que é uma maravilha. Até no Internet Explorer (argh!). Então aqui vai o que eu fiz no wordpress pra funcionar:

Propagandas que ficam em posição fixa, fora da área útil da tela, no wordpress (e que claro, funcionem no Internet Explorer, senão era moleza).

Pois tudo começou assim: CSS é manha! basta então eu criar uma “div” com minha propaganda, e tacar um CSS pra colocar ela onde eu quero. E foi o que eu fiz: Acrescentei no “header.php”, logo abaixo do <body> o seguinte trecho:

<div id="banner_vertical">
        <!-- ... Trecho contendo minha propaganda, favor consultar seu provedor de propagandas ... -->
</div>

Feita essa “moleza”, fui atrás do CSS no arquivo “style.css” e lasquei-lhe um estilo correspondente à minha div:

#banner_vert {
        position: fixed;
        right: 1em;
        top: 2.5em;
        z-index: 0;
}
#page {
        z-index: 1 !important;
}

Tudo muito fácil, claro! E muito bom, no opera e no firefox a coisa tava maravilhosa! E eu lá lembrei de testar no IE? Claro que não… Até que fui testar outra coisa, sem a menor relação com isso e abri no IE. ARGH!!! A propaganda aparecia “centralizada” (sic, acho que o certo seria centrada, quem me corrige?), no alto da tela, jogando todo o resto pra baixo, fazendo até sumir tudo da tela! Desesperei! Tentei achar solução, e nada! O position:fixed simplesmente não funciona no IE. Pra poder ter tempo pra pensar, lasquei um “float: right” e torci pra dar certo. Até deu, mas o efeito não era nada do que eu queria. A página era “jogada” pra esquerda de uma distância correspondente à largura do banner. Mas eu não tinha o que fazer, era 1 da manhã, e eu resolvi ir dormir.

Dois dias depois, esperando que alguém respondesse meu post no blog, acabei desistindo. ninguém ia me dar essa dica, teria de descobrir sozinho. Mas pra isso que existe o gúgou, né verdade? E fui. Acabei achando uma página legal (ou pelo menos parece legal, não li tudo porque era grande e só copiei os exemplos, hehehehe): http://www.howtocreate.co.uk/fixedPosition.html.

Claro que os exemplos não eram aplicáveis to the foot of the letter… Mas juntando dois dos exemplos, tive exatamente o que eu queria. Que acabou se resumindo a acrescentar no meu “header.php” (de novo ele… mas é quem aparece em todas as páginas, então vai ele mesmo) o seguinte trecho de código:

<!-- hack for IE 5 fixed -->
<style type="text/css">
#banner_vert {
        /* Netscape 4, IE 4.x-5.0/Win and other lesser browsers will use this */
        position: absolute;
        right: 1em;
        top: 2.7em;
}
body > div#banner_vert {
        /* used by Opera 5+, Netscape6+/Mozilla, Konqueror, Safari, OmniWeb 4.5+, iCab, ICEbrowser */
        position: fixed;
}
</style>
<!--[if gte IE 5.5]>
<![if lt IE 7]>
<style type="text/css">
div#banner_vert {
        /* IE5.5+/Win - this is more specific than the IE 5.0 version */
        left: expression( ( -12 - banner_vert.offsetWidth
                             + ( document.documentElement.clientWidth
                                 ? document.documentElement.clientWidth
                                 : document.body.clientWidth )
                             + ( ignoreMe2 = document.documentElement.scrollLeft
                                             ? document.documentElement.scrollLeft
                                             : document.body.scrollLeft ) )
                           + 'px' );
        top: expression( ( 6 + ( ignoreMe = document.documentElement.scrollTop
                                            ? document.documentElement.scrollTop
                                            : document.body.scrollTop ) )
                         + 'px' );
}
</style>
<![endif]>
<![endif]-->

Uh! Mas esse trem é grande… o que ele faz??? Bom, vamos destrinchar! comecemos pelo que vocês já tinham visto antes…

#banner_vert {
        /* Netscape 4, IE 4.x-5.0/Win and other lesser browsers will use this */
        position: absolute;
        right: 1em;
        top: 2.7em;
}
body > div#banner_vert {
        /* used by Opera 5+, Netscape6+/Mozilla, Konqueror, Safari, OmniWeb 4.5+, iCab, ICEbrowser */
        position: fixed;
}

Cara, é igualzinho eu tinha tacado no CSS, nem precisava copiar aqui, podia continuar lá… Mas eu quis ser consistente com o exemplo, então taquei aqui e tirei de lá do CSS. Basicamente, tem umas diferencinhas: só usa uns recursos pra browsers antigos (position: absolute) que eu num quero nem ver como fica, e pra garantir que só browsers novos vão ler a coisa direito, usa o “body > div#banner_vert”. Isso aí só “diz” que o conteúdo ali se aplica só no que estiver dentro do “body”, for declarado como “div” e tiver o “ID” igual a “banner_vert”. E como essa sintaxe não existe em browsers velhos, browsers velhos vão ignorar (espero eu, nem quero estar vivo pra testar isso). Essa parte então foi manha, né? Vamos pro resto…

<!--[if gte IE 5.5]>
<![if lt IE 7]>
 ...
<![endif]>
<![endif]-->

Pra quem entende de CSS multibrowser, isso aí ficou fácil: fala que o que tá no meio (que eu substitui por “…”) só vai precisar rodar se minha versão for “gte” (maior ou igual) que “IE 5.5” e também se for “lt” (menor) que “IE 7”. Manha né? Então, próximo…

div#banner_vert {
        /* IE5.5+/Win - this is more specific than the IE 5.0 version */
        left: expression( ( -12 - banner_vert.offsetWidth
                             + ( document.documentElement.clientWidth
                                 ? document.documentElement.clientWidth
                                 : document.body.clientWidth )
                             + ( ignoreMe2 = document.documentElement.scrollLeft
                                             ? document.documentElement.scrollLeft
                                             : document.body.scrollLeft ) )
                           + 'px' );
        top: expression( ( 6 + ( ignoreMe = document.documentElement.scrollTop
                                            ? document.documentElement.scrollTop
                                            : document.body.scrollTop ) )
                         + 'px' );
}

Ugh! isso aí nem eu li direito! Basicamente, isso aí diz: use o seguinte código em javascript para ajustar a posição “left:” (ponta mais à esquerda) e “top:” (ponta mais ao alto) do meu “div” que se chama “banner_vert”. O que tem depois de “expression” e entre parentes é o código javascript que calcula a posição ideal na tela do que que eu quero. Vou tentar destrinchar…

-12 (ou no de baixo 6):

Duh! é a posição em pixels que eu quero o div. O “-” é porque eu quero à direita, e não à esquerda!

- banner_vert.offsetWidth

É o tamanho do banner. Eu subtraio ele pelo mesmo motivo acima: estou setando a posição mais a esquerda do banner, mas quero que ele apareça a direita. então calculo a posição do final da tela MENOS o tamanho do banner MENOS a margem que eu vou querer 😉

( document.documentElement.clientWidth
  ? document.documentElement.clientWidth
  : document.body.clientWidth )

A largura da tela. Se eu estiver dentro de um frame ou outra coisa assim (documentElement) eu pego ele, senão pego logo o body! Sacou?

( ignoreMe2 = document.documentElement.scrollLeft
              ? document.documentElement.scrollLeft
              : document.body.scrollLeft )

Isso daí é pra forçar o cara a calcular o tamanho do “scroll” que foi feito. Aí eu vou e “adiciono” isso. Nesse caso o “scroll” horizontal e no caso de:

( ignoreMe = document.documentElement.scrollTop
             ? document.documentElement.scrollTop
             : document.body.scrollTop ) )

o scroll vertical.

E é isso, então o javascript se resume a calcular a posição desejada em relação ao início da página, e somar isso com o scroll que venha a ser feito. Simples né? Vamos torcer pra que funcione sempre em qualquer situação.

6 thoughts on “Como “consertar” o position:fixed no IE.

  1. Ninguém ta aí pra como vc conseguiu pensar nisso… só poste a dica, mais nada… Se quer falar da sua vida crie um blog só pra isso… o problema é alguém querer visitar

  2. po cara que legal.!…
    ignora isso ai.;; ‘Ninguém ta aí pra como vc conseguiu pensar nisso’..
    em vez do cara agradecer ne… putz…
    flow veio

  3. Cara a sua dica, foi a mais próxima que encontrei do que queria.

    Tem como você passar uma dica ai, de como fazer um banner de propaganda igual tem no uol, aquele banner que aparece sobre os elementos da pagina com um botão para fechar ou fechar automaticamente depois de x segundos??

Leave a Reply

This site uses Akismet to reduce spam. Learn how your comment data is processed.