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

Posts relacionados

Avalie

1 estrela2 estrelas3 estrelas4 estrelas5 estrelas (No Ratings Yet)

7 Responses to “O POG nosso de cada dia #16”

  1. Guilherme Serrano says with Firefox on Windows XP

    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.

  2. Chris says with Firefox on Ubuntu

    Inclusive eu nem sei se esse cálculo está efetivamente correto, em pixels e tal.
    Mas peguei pronto, sempre funcionou, e vai continuar funcionando! :D

  3. Tweets that mention Chris B. – idéias e pensamentos » O POG nosso de cada dia #16 -- Topsy.com says with

    [...] This post was mentioned on Twitter by Chris Benseler. Chris Benseler said: o pog nosso de cada dia http://bit.ly/GMbAZ #pog [...]

  4. Cleiver says with Firefox on Windows XP

    Véi… nem sei o que comentar… hahaha xD

  5. Julio Anderson says with Chrome on Windows Vista

    Véi… nem sei o que comentar… hahaha xD [2]

    Essa foi uma solução realmente… criativa.

  6. Hard says with Firefox on Linux

    Isso q eu chamo de fazer o codigo na Unha.. huahuahuaahu

  7. Chris says with Firefox on Ubuntu

    @Cleiver é melhor não comentar

    @Julio e que nos salvou algumas vezes, não? haha

    @Hard minimalista!

Leave a Reply