Bordas arredondadas parecem nunca sair de moda. Para a infelicidade dos webdesigners, adicionar mais de uma imagem de fundo a um elemento e a propriedade “border-radius” são exclusividades da versão 3 do CSS, que ainda não é suportada pelo navegador da Microsoft e por isso seu uso está fora de cogitação.
Mas nem tudo está perdido: uma ótima técnica que utiliza CSS2, descrita no artigo “Even More Rounded Corners”, permite mostrar bordas arredondadas utilizando apenas uma imagem PNG com a caixa inteira e uma porção de declarações “background-position” para fatiar virtualmente a imagem. Como todas as soluções compatíveis com o IE, ela necessita de marcação extra no HTML para funcionar. Na verdade, ela é bem compacta, vejam:
<div class="dialog">
<div class="content">
<div class="t"></div>
<!-- Seu contéudo vai aqui --></div>
<div class="b">
<div></div>
</div>
</div>
Mesmo compacta ela ainda causa, em menor intensidade, os mesmos já conhecidos problemas das marcações extras:
- Dificuldade de manutenção: é necessário reproduzir a estrutura cada vez que quisermos uma caixa arredondada.
- Perda de legibilidade: seu conteúdo ficará escondido num mar de DIVs inúteis.
- Quebra de encapsulamento: tags com propósito unicamente visual (DIVs vazias!) tornam o código menos semântico e intuitivo.
Não sendo possível diminuir mais a quantidade de porcaria marcação inútil servida para o usuário, podemos ao menos reduzir algumas linhas do nosso código fonte no servidor, utilizando o PHP.
A solução aqui apresentada permitirá escrever no fonte:
<div class="dialog">
<!-- Seu conteúdo vai aqui --></div>
E ter como resultado o código “sujo” da técnica do “Even More Rounded Corners” na saída. O truque é fazer com que o PHP injete as divs necessárias e sirva para o usuário a marcação extra sem sujar o fonte, melhorando legibilidade, facilitando a manutenção e evitando em certo nível a quebra de encapsulamento. Para executar a mágica vamos usar o controle de buffer de saída do PHP e a extensão DOM, para manipular o HTML.
Primeiro, vamos precisar adicionar o seguinte código no início da página, fazendo com que ele execute antes do script emitir qualquer saída:
<?
// Captura a saída em um buffer.
ob_start();
?>
Isso garantirá que toda a saída do PHP seja guardada em um buffer, ao invés de ser enviada diretamente ao user agent.
O próximo e último passo é pegar toda a saída e injetar a marcação extra. Isso deve ser feito, é claro, no fim do script, depois de qualquer saída ter sido gerada e, conseqüentemente, guardada no buffer:
<?
// Lê o buffer de saída para uma variável string.
$saida = ob_get_contents();
ob_end_clean();
// Defina aqui a classe a ser considerada
// para caixas arredondadas.
$classe = "dialog";
// Carrega o documento na classe DOM.
$dom = new DomDocument("1.0");
// Detecta a codificação da página.
if (
mb_detect_encoding(
$saida . 'a' , 'UTF-8, ISO-8859-1' )
==
"UTF-8"
)
{
$saida = utf8_decode($saida);
}
$dom->loadHTML($saida);
// Seleciona todas as DIVs
$divs = $dom->getElementsByTagName("div");
foreach ($divs as $div) {
// Filtra as DIVs da classe selecionada.
if (strstr($div->getAttribute("class"), $classe)) {
// Cria os nós adicionais
$content_div = $dom->createElement("div");
$content_div->setAttribute("class", "content");
$t_div = $dom->createElement("div");
$t_div->setAttribute("class", "t");
$b_div = $dom->createElement("div");
$b_div->setAttribute("class", "b");
$extra_div = $dom->createElement("div");
// Cria a árvore correta
$b_div->appendChild($extra_div);
$content_div->appendChild($t_div);
// Importa o conteúdo do div a ser arredondado
// para dentro de 'content'.
while ($div->hasChildNodes()) {
$content_div->appendChild(
$div->removeChild($div->firstChild)
);
}
// Adiciona tudo de volta à div.
$div->appendChild($content_div);
$div->appendChild($b_div);
}
}
$resultado = $dom->saveHTML();
echo $resultado;
?>
É claro que você não irá copiar e colar esse texto em todas as suas páginas. Você pode usar dois includes (um no começo do documento e outro ao final), e ainda, se você usa algum sistema de templates, fazer esses includes apenas no arquivo do template.
Podemos adaptar essa técnica para várias outras situações onde necessitamos de marcação extra. Podemos ainda adaptá-la facilmente para rodar no lado do cliente, uma vez que as funções DOM do PHP e do javascript são praticamente idênticas. O único porém deste último método é que não podemos garantir que o user agent suporte e esteja com o javascript habilitado e é então sujeitos a falhas, motivo pelo qual escolhi o método server-side.
Agora ninguém mais tem desculpa para fazer cara feia quando tiver que implementar aquele design todo arredondado!