13th out 2009
O POG nosso de cada dia #16
Faz tempo que não posto um POG por aqui, né? Bem, vamos tirar a poeira com uma coisa bonita.
O problema
Mais uma vez nosso querido IE6… imagine um menu em forma horizontal com listas nas verticais, uls aninhadas, uma dentro da outra, com uma certa hierarquia. Já tenho um código pronto há muito tempo, que funciona bem, que tem um javascript para simular o :hover em elementos que não são <a>. Não, não é nesse js que está o POG a ser apresentado (mas bem que poderia ser!), a questão é no CSS. Como os itens flutuam (float) não há width:auto que faça com que eles ocupem o espaço do texto – as lis acabam ficando com a largura total do pai.
Ah, sim, antes que comentem: existem várias soluções, muito boas, para menus com dropdown. Já pesquisei por todas, mas nenhuma atende 100% as necessidades que são impostas nos projetos que faço aqui na empresa, pois os menus são bem complexos.
O POG
Calcular a largura de cada item e deixar explícito por CSS inline. Como fazer isso? Uma função que retorna a largura de um texto, dependendo dos caracteres que o compõem, com isso a li vai ficar com a largura fixa no html, não correndo risco do width:auto não funcionar como previsto.
Abaixo segue o código de uma função, que usamos aqui, feita em Velocity – apesar da linguagem não ser de conhecimento popular, é fácil entender o que ela faz. Ah, sim, isso vale para fontes com tamanho 12 pixels!
#macro(largura $teste) #set($largura = 0) #if($teste.length() > 0) #set($total = $teste.length() - 1) #foreach($i in [0..$total]) #set($j = $i + 1) #set($letra = $teste.substring($i,$j)) #if($letra == " ") #set($largura = $largura + 2) #elseif($letra == "i" || $letra == "í" || $letra == "j" || $letra == "l") #set($largura = $largura + 3) #elseif($letra == "f" || $letra == "r" || $letra == "t" || $letra == "!") #set($largura = $largura + 4) #elseif($letra == "c" || $letra == "ç" || $letra == "y" || $letra == "I" || $letra == "Í" || $letra == "J" || $letra == "-" || $letra == "|") #set($largura = $largura + 5) #elseif($letra == "s" || $letra == "v" || $letra == "z" || $letra == "E" || $letra == "É" || $letra == "F" || $letra == "L") #set($largura = $largura + 6) #elseif($letra == "C" || $letra == "Ç" || $letra == "D" || $letra == "G" || $letra == "H" || $letra == "R" || $letra == "U" || $letra == "Ú" || $letra == "Ü") #set($largura = $largura + 7) #elseif($letra == "M" || $letra == "O" || $letra == "Ó" || $letra == "Q") #set($largura = $largura + 9) #elseif($letra == "m" || $letra == "W" || $letra == "%" || $letra == "@") #set($largura = $largura + 11) #else #set($largura = $largura + 7) #end #end #end #end

Esse código é muito, mas MUITO ninja!
É curioso como alguns caracteres utilizam tanto espaço a mais que outros (diferença de 2 para 11!), ó a tipografia acabando com a vida dos desenvolvedores… haha, ótima solução. POG na veia.
Inclusive eu nem sei se esse cálculo está efetivamente correto, em pixels e tal.
Mas peguei pronto, sempre funcionou, e vai continuar funcionando!
[...] This post was mentioned on Twitter by Chris Benseler. Chris Benseler said: o pog nosso de cada dia http://bit.ly/GMbAZ #pog [...]
Véi… nem sei o que comentar… hahaha xD
Véi… nem sei o que comentar… hahaha xD [2]
Essa foi uma solução realmente… criativa.
Isso q eu chamo de fazer o codigo na Unha.. huahuahuaahu
@Cleiver é melhor não comentar
@Julio e que nos salvou algumas vezes, não? haha
@Hard minimalista!