Voltando à ativa depois de tanto tempo de inatividade, quero mostrar a vocês um exemplo comum de uso das camadas de conteúdo e apresentação. Um menu com imagens e rollover, mais acessível do que o normal e não muito complicado de se fazer.
O conceito é bastante simples: um DIV contendo uma lista não ordenada (UL), cujos itens são posicionados de maneira absoluta, funcionando mais ou menos como um mapa de imagens (MAP). O rollover é obtido mudando o posicionamento da imagem de fundo. No final, vou mostrar algumas modificações que podem ser usadas para tornar o menu mais acessível.
Vamos começar do começo, como sempre:
Código HTML básico
<div id="menu">
<ul>
<li><a href=”#”>Início</a></li>
<li><a href=”#”>Artigos</a></li>
<li><a href=”#”>Contato</a></li>
</ul>
</div>
O código acima é praticamente tudo que vamos precisar ter na camada de conteúdo. Bem simples, como deve ser. Veja o exemplo 1.
Posicionando o que tem que ser posicionado
<style type="text/css">
#menu{ position:relative; width:186px; height:35px; }
#menu ul{ list-style:none; }
#menu li{
position:absolute;
top:0;
height:35px;
border:1px solid;
}
#menu li a{
display:block;
width:100%;
height:100%;
top:0;
}
#um{ width:53px; left:0; }
#dois{ width:61px; left:53px; }
#tres{ width:72px; left:114px; }
</style>
<div id=”menu”>
<ul>
<li id=”um”><a href=”#”>Início</a></li>
<li id=”dois”><a href=”#”>Artigos</a></li>
<li id=”tres”><a href=”#”>Contato</a></li>
</ul>
</div>
Adicionamos um ID para cada item da lista, para que suas posições e larguras possam ser definidos separadamente.
O DIV menu precisa ter posicionamento relativo, para “conter” seus filhos, que serão posicionados de maneira absoluta. (leia meu artigo sobre posicionamento com CSS)
Note que cada LI tem uma largura (width) e uma posição horizontal (left) diferentes. O cálculo é simples: o valor de left é sempre a largura do LI anterior somado ao valor de left deste.
Usamos uma borda apenas para ilustrar. Veja o resultado no exemplo 2.
Adicionando uma imagem de fundo
A imagem de fundo deve ser o menu inteiro. Algo mais ou menos como a imagem abaixo:

Esta imagem vai ser aplicada como fundo do DIV menu. E esta é a única mudança com relação ao exemplo anterior:
#menu{
position:relative;
width:186px;
height:35px;
background:url(img1.gif) no-repeat 0 0;
}
Veja o resultado no exemplo 3. Note que o texto está por cima da imagem. Vamos resolver isso.
Escondendo o texto
A forma mais simples de esconder o texto é usando a propriedade CSS text-indent com um valor negativo muito alto. Vamos usar -9999em. Isso faz com que o texto seja levado para a esquerda e fique fora do espaço visível.
Esta técnica tem sido muito usada para efeitos de image replacement, que é como chamamos os métodos usados para substituir texto por imagens, usando CSS.
Este método, usando text-indent negativo, é efetivo, porém tem o problema de não exibir conteúdo algum caso o browser tenha suporte a CSS ligado e suporte a imagens desligado. Esta é uma situação bem difícil de acontecer, mas nem por isso devemos deixar de nos preocupar. Vamos achar uma maneira de resolver este problema no último passo do tutorial.
O que muda no código:
#menu ul{
list-style:none;
text-indent:-9999em;
}
#menu li a{
display:block;
text-decoration:none;
width:100%;
height:100%;
top:0;
}
O text-indent negativo foi aplicado ao UL e colocamos um text-decoration:none no A, para evitar que apareça uma linha azul estranhíssima em algumas versões do IE.
Veja o resultado no exemplo 4.
Adicionando o efeito de rollover
Para obter o efeito de rollover (ou seja, alguma mudança ao se passar o mouse sobre o elemento), vamos mudar a imagem usada como fundo. Apenas duplicamos a imagem e mudamos alguma coisa em cada um do itens. Neste caso, mudei a cor do texto. Veja:

Mesmo a imagem tendo o dobro da altura da anterior, apenas a parte superior vai aparecer, já que nosso DIV tem uma altura fixa, em pixels.
Para o rollover, vamos usar a pseudo-classe :hover do A, e aplicar a imagem acima como fundo deste elemento, porém em posições diferentes para cada um deles. Veja:
#um a:hover{
background:url(img2.gif) no-repeat 0 -35px;
}
#dois a:hover{
background:url(img2.gif) no-repeat -53px -35px;
}
#tres a:hover{
background:url(img2.gif) no-repeat -114px -35px;
}
O primeiro valor é a posição da imagem na horizontal (left) e o segundo, na vertical (top). Percebam que o primeiro valor é sempre igual ao left do LI que contém o A. Veja o exemplo 5.
Um pouco mais de acessibilidade
Lembra do que falei, lá em cima, sobre nada ser exibido caso tenhamos CSS habilitado e imagens desabilitadas? Pois bem, há uma solução. Mas, claro, não é de graça. Vamos ter que adicionar alguma coisa ao nosso código HTML.
<div id="menu">
<ul>
<li id=”um”><a href=”#”><span></span>Início</a></li>
<li id=”dois”><a href=”#”><span></span>Artigos</a></li>
<li id=”tres”><a href=”#”><span></span>Contato</a></li>
</ul>
</div>
Colocamos um SPAN vazio dentro de cada A. Alguns podem achar isso um pouco “sujo” e, na verdade, não deixa de ser. Porém, não perdemos nada de substancial com o uso destes elementos vazios, e vamos, no entanto, ganhar um pouco em termos de acessibilidade. Na minha opinião, vale a pena. Você decide se vale ou não para você.
Os referidos SPANs vão ser declarados como elementos de bloco e posicionados de maneira absoluta, de modo que fiquem “por cima” de seus pais (A). Vamos colocar uma imagem de fundo para cada SPAN (o mesmo valor usado nos :hovers, mas com posição vertical 0 ao invés de -35px). Veja:
#menu li a span{
display:block;
position:absolute;
width:100%;
height:100%;
top:0;
cursor:pointer;
}
#um a span{
background:url(img2.gif) no-repeat 0 0;
}
#dois a span{
background:url(img2.gif) no-repeat -53px 0;
}
#tres a span{
background:url(img2.gif) no-repeat -114px 0;
}
Percebam que tive que usar cursor:pointer para que o cursor padrão de ponteiro (aquela “mãozinha” que aparece quando você passa o mouse sobre um link) apareça no Internet Explorer.
Vejam o exemplo 6.
Rollover de novo
Vamos adicionar o efeito de rollover a esse nosso novo código.
#um a:hover span{
background:url(img2.gif) no-repeat 0 -35px;
}
#dois a:hover span{
background:url(img2.gif) no-repeat -53px -35px;
}
#tres a:hover span{
background:url(img2.gif) no-repeat -114px -35px;
}
Se você acompanhou bem até aqui, acho que não preciso explicar, né? Vejam o exemplo 7.
Consertando o rollover no IE
Os mais atentos com certeza notaram que ocorre um problema com o exemplo acima no Internet Explorer. Quando você passa o mouse sobre um link, ele muda de cor, mas não volta à cor original quando o cursor é movido para fora do elemento. Não me perguntem por que isso acontece, não faço a mínima idéia.
Passei alguns minutos tentando achar uma solução, e achei!
Por algum motivo, se colocarmos o z-index (que é o posicionamento no eixo Z, ou seja, serve para colocar um elemento “por cima” de outro) do a:hover para um valor alto (vou usar 1000, que é o valor máximo), tudo passa a funcionar perfeitamente no IE, e continua funcionando normalmente nos outros browsers.
#menu ul li a:hover{
z-index:1000;
}
Simples assim. Porém, notem que o seletor desta regra deve ser mais específico que o do :hover. Vou falar sobre especificidade um dia desses. Por agora, tente adicionar apenas um ID a mais no seletor (no caso #menu) e especificar cada um dos elementos, na ordem (no caso ul li). Isso vai funcionar.
Confira o resultado final.
O código foi testado e aprovado nos seguintes browsers:
- Firefox 1.5
- Opera 9
- Internet Explorer 6
- Swift (um “safari para windows”, muito experimental ainda, portanto não posso garantir que o resultado seja o mesmo no safari do Mac OS X).
Se algum de vocês puder testar em outros browsers e me dizer se funciona, agradeço.
***
Espero que este exemplo seja de alguma utilidade para vocês. Dúvidas, sugestões e reclamações são muito bem vindas.
- Comprar: MP9, Jogos para PC, Monitor Cardiaco, Notebook HP, Celular LG, Celular
Vamos então aos posts com exemplos de códigos simples, mostrando o uso de uma ou mais das três camadas de desenvolvimento apresentadas nos dois posts anteriores.
Antes de começar, devo deixar claro que praticamente qualquer funcionalidade que você precise, seja em HTML, CSS ou JavaScript geralmente está a apenas uma “googlada” de distância. Se você tem um problema é muito provável que alguém já tenha tido o mesmo problema e a chance de que esse alguém já tenha resolvido e blogado sobre a solução também é muito grande.
O código feito aqui não se baseia em nenhum outro diretamente. Mas nada impede que eu use, inconscientemente (ou conscientemente, vai dizer) algo que eu já tenha visto por aí e tenha ficado registrado na caixola.
Vamos ao que interessa. Neste texto vamos fazer um título editável, ou seja, um título normal que, ao ser clicado se transforma em um campo de texto (INPUT) que ao perder o foco salva o novo valor e volta a ser um título novamente.
Começando pelo começo
A primeira coisa que precisamos é de uma página HTML com um título, no caso um H1, como pode ser visto no exemplo 1.
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd">
<meta http-equiv=”content-type” content=”text/html; charset=utf-8″>
<title>Título editável com JavaScript</title>
<style type=”text/css”>
h1 {
font:normal 2.4em/1.6 georgia, “times new roman”, “bitstream vera serif”, times, serif;
color:#900;
}
</style>
<script type=”text/javascript”>
</script>
</head>
<body>
<h1>Edite este título</h1>
</body>
</html>
Um Título simples, com um toquezinho de CSS só para definir a fonte e a cor, pra não ficar tosco demais.
Note que o CSS e o JavaScript vão ser colocados dentro do próprio arquivo HTML, apenas para facilitar o estudo. No “mundo real” o ideal é colocá-los em arquivos separados.
Fazendo o título parecer editável
Precisamos agora dar alguma dica ao usuário de que, se clicado, o título pode ser editado.
Uma mudança na cor de fundo em conjunto com um texto explicativo no atributo TITLE do H1 me parecem ser suficientes. Além disso, vamos colocar um SPAN dentro do H1. Isso porque como o H1 é um elemento de bloco, ocupa por padrão 100% do espaço horizontal disponível. Para mudar isso poderíamos usar a propriedade CSS float ou definir uma largura específica para o H1. No caso do float, seria necessário definir a propriedade clear para o elemento logo abaixo do H1. Usar uma largura fixa não seria muito inteligente, pois o texto digitado pode ser maior que esse espaço. Portanto, fico com o SPAN.
Nesse ponto temos algo parecido com o exemplo 2.
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd">
<meta http-equiv=”content-type” content=”text/html; charset=utf-8″>
<title>Título editável com JavaScript</title>
<style type=”text/css”>
h1 {
font:normal 2.4em/1.6 georgia, “times new roman”, “bitstream vera serif”, times, serif;
color:#900;
}
h1 span:hover{
background:#f5f5f5;
}
</style>
<script type=”text/javascript”>
</script>
</head>
<body>
<h1><span title=”Clique para editar o texto”>Edite este título</span></h1>
</body>
</html>
Você deve ter percebido que o exemplo 2 não funciona muito bem no Internet Explorer. Isso acontece porque o IE não tem suporte à pseudo-class :hover em elementos senão o A. Portanto, para obter esse efeito precisaremos de uma pitadinha de JavaScript.
Veja o exemplo 3. Perceba que coloquei o código todo dentro de uma função atribuída ao evento onload do objeto window, ou seja, o script será executado assim que o documento terminar de ser carregado pelo browser. Essa não é a melhor forma de fazer as coisas, mas por agora nos serve muito bem. Mais à frente veremos formas mais interessantes de “inicializar” nossos scripts.
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd">
<meta http-equiv=”content-type” content=”text/html; charset=utf-8″>
<title>Título editável com JavaScript</title>
<style type=”text/css”>
h1 {
font:normal 2.4em/1.6 georgia, “times new roman”, “bitstream vera serif”, times, serif;
color:#900;
}
</style>
<script type=”text/javascript”>
window.onload = function(){
var title = document.getElementsByTagName(’h1′)[0];
var span = title.firstChild;
span.onmouseover = function(){
this.title = ‘Clique para editar o texto’;
this.style.background = ‘#f5f5f5′;
}
span.onmouseout = function(){
this.title = ”;
this.style.background = ”;
}
}
</script>
</head>
<body>
<h1><span>Edite este título</span></h1>
</body>
</html>
Pense comigo. O título só será editável caso o browser tenha suporte a JavaScript, portanto é melhor que tanto a cor de fundo ao passar o mouse quanto o TITLE só existam quando o suporte estiver presente.
Explicando o script: na linha var title = document.getElementsByTagName('h1')[0]; colocamos na variável title uma referência para o primeiro elemento definido pela tag H1 no documento.
Na linha seguinte, var span = title.firstChild; pegamos o primeiro filho (firstChild) do H1 — que, no caso, é o SPAN, e jogamos para a variável span.
Nas linhas seguintes definimos, no evento onmouseover do SPAN, seu título e cor de fundo e no onmouseout limpamos esses valores. Simples, não? Pois bem, avancemos.
Criando um INPUT para edição do texto
Agora precisamos que, ao clicar no título, este se transforme em um INPUT para permitir a edição do texto.
Para isso vamos usar o evento onclick do nosso SPAN, como pode ser visto no exemplo 4.
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd">
<meta http-equiv=”content-type” content=”text/html; charset=utf-8″>
<title>Título editável com JavaScript</title>
<style type=”text/css”>
h1 {
font:normal 2.4em/1.6 georgia, “times new roman”, “bitstream vera serif”, times, serif;
color:#900;
}
</style>
<script type=”text/javascript”>
window.onload = function(){
function editTitle(){
var title = document.getElementsByTagName(’h1′)[0];
var span = title.firstChild;
span.onmouseover = function(){
this.title = ‘Clique para editar o texto’;
this.style.background = ‘#f5f5f5′;
}
span.onmouseout = function(){
this.title = ”;
this.style.background = ”;
}
span.onclick = function(){
var textoAtual = this.firstChild.nodeValue;
var input = ‘<input type=”text” value=”‘+textoAtual+’”>’;
this.innerHTML = input;
var field = this.firstChild;
this.onclick = null;
this.onmouseover = null;
field.focus();
field.select();
field.onblur = function(){
this.parentNode.innerHTML = this.value;
editTitle();
}
}
}
editTitle();
}
</script>
</head>
<body>
<h1><span>Edite este título</span></h1>
</body>
</html>
Note que o código dessa vez foi colocado dentro de uma função, editTitle() que é chamada logo após a sua definição. Já explico porque isso foi necessário. Primeiro vamos entender como o esquema funciona.
var textoAtual = this.firstChild.nodeValue; pega o texto contido no SPAN e joga para a variável textoAtual. Perceba o uso de firstChild. Abra o DOM Inspector e vá até o SPAN. Veja que dentro desse SPAN há um elemento, que é um textNode, representado por #text. Esse textNode é o primeiro filho (firstChild) do nosso SPAN e o seu valor (nodeValue) é o texto em si, no caso “Edite este texto”.
Logo abaixo criamos uma string, que é um código HTML representando um INPUT, já com o VALUE definido com o valor de textoAtual. Feito isso, colocamos essa string no innerHTML do SPAN. innerHTML é o conteúdo HTML presente dentro do elemento em questão.
Nesse momento, o input passa a ser o firstChild do SPAN. Guardamos uma referência para ele na variável field.
Agora limpamos os eventos onclick e onmouseover do SPAN, usando this.onclick = null; e this.onmouseover = null; (retire estas duas linhas do código e teste para entender o porquê disso) e depois jogamos o foco para o INPUT e selecionamos o texto nele contido.
O próximo passo é atualizar o valor do nosso SPAN (que é o pai [parentNode] do INPUT) no evento onblur (perda de foco) do INPUT e chamar a própria função editTitle() para garantir que o código continuará funcionando. Experimente retirar a chamada para a função editTitle() de field.onblur e teste para entender melhor.
[update]
Atualizando o valor do título ao pressionar ENTER
Sugeri que os leitores fizessem, como “dever de casa”, com que o valor do título fosse atualizado ao pressionarmos a tecla ENTER.
O’Marin fez e postou nos comentários, mas o código dele não funciona no Internet Explorer. Os outros browsers (pelo menos os gecko-based e o Opera) capturam o evento que acontece ao pressionarmos uma tecla e o joga na variável usada como parâmetro da função atribuida ao evento onkeypress. Já o IE captura esse evento e atribui a um objeto, o window.event.
Precisamos apenas checar se esse objeto existe e, em caso positivo, usá-lo para pegar o código da tecla pressionada. Caso não exista, usamos a variável do parâmetro (que, no meu exemplo, vai se chamar e).
Outra coisa que O’Marin faz e que poderia ser feito de uma forma mais adequada é repetir o código que já está sendo usado no evento onblur dentro do evento onkeypress. Podemos reutilizar o código já existente chamando o método blur() do objeto em questão, já que, ao pressionar enter, é interessante tirar o foco do INPUT. Veja no exemplo 5.
field.onblur = function(){
this.parentNode.innerHTML = this.value;
editTitle();
}
field.onkeypress = function(e){
var keynum;
if(window.event) // IE
keynum = window.event.keyCode;
else if(e.keyCode) // Netscape/Firefox/Opera
keynum = e.keyCode;
if (keynum == 13) this.blur();
}
Esse exemplo foi testado e funciona no IE, Firefox e Opera. Concordam comigo ou têm alguma solução melhor?
[/update]
Conclusão
É claro que para esse código se transformar em alguma coisa realmente útil é necessário guardar o valor do texto editado em algum lugar onde este persista (um banco de dados, por exemplo), mas isso fica para um outro post.
E, como dever de casa (hehe), tente fazer com que o texto seja atualizado quando o usuário pressionar ENTER. Quem conseguir, poste a solução nos comentários. Caso ninguém consiga, colocarei o código aqui, em um update do post.
Espero ter sido claro e que isto seja de utilidade para vocês pelo menos para ajudar a entender um pouquinho mais a camada de comportamento. Comentários são muito bem vindos.
- Comprar: Notebook Asus, MP4, Notebook, Notebook HP, Celular Motorola, Notebook Barato
No post anterior falei sobre desenvolvimento em camadas e apresentei a vocês as camadas de conteúdo e apresentação.
Ficou faltando a camada de comportamento. Vamos a ela então.
A camada de comportamento deve ser encarada como uma camada extra no desenvolvimento de uma página para a web. Nessa camada, usamos uma linguagem de script (JavaScript) junto com o DOM (Document Object Model) para modificar o comportamento dos elementos presentes na camada de conteúdo.
Digo que essa camada deve ser encarada como extra porque é importante que seu site ou aplicação funcione perfeitamente na ausência dessa camada (ou do suporte a ela).
O DOM
O DOM é um modelo de dados usado pelos user-agents para montar uma representação do código de uma página (seja ela escrita em HTML, XHTML ou XML) após sua renderização. É mais ou menos como uma árvore. Você pode usar o DOM Inspector do Firefox para dar uma olhada na estrutura dessa árvore. Já falei sobre o DOM Inspector e outras ferramentas legais para desenvolvedores no meu blog.
A partir da DOM API (que é algo como uma coleção de métodos para manipular os elementos no DOM) podemos selecionar elementos ou grupos de elementos e seus atributos e executar diversas funções com eles, inclusive criar ou remover elementos.
No caso do desenvolvimento da camada de comportamento de um site, usamos a DOM API presente no JavaScript, que é a linguagem de script existente em todos os browsers modernos.
Em geral, a maior parte do trabalho que se tem para desenvolver essa camada reside na manipulação do DOM.
São exemplos dos métodos existentes na DOM API:
- document.getElementById(id)
- Seleciona um elemento a partir do valor de seu atributo ID. É a maneira mais simples de se acessar um elemento no DOM.
Digamos que você tenha um DIV com ID “conteudo”.var conteudo = document.getElementById('conteudo')vai fazer com que a variável conteudo contenha uma referência para o referido DIV. Manipule a variável conteudo e as alterações serão feitas no DIV. - document.getElementsByTagName(tag)
- Seleciona um conjunto de elementos que são definidos pela tag “tag”.
Exemplo:var uls = document.getElementsByTagName('ul')cria em uls um array onde cada item é uma referência para um elemento UL dentro do documento.
uls[0]seria, nesse caso, uma referência para a primeira UL presente no documento.
Esses são, com certeza, os dois métodos que serão mais usados em qualquer script que você venha a desenvolver. Existem outros tantos que não vou listar aqui para não tornar o post extenso demais e até mesmo porque esse não é o intuito do texto. Uma ótima referência de métodos da DOM API pode ser encontrada na referência de DOM do Mozilla Developer Center. Apenas tenha em mente que essa referência é específica para os browsers baseados no engine Gecko (Mozilla, Firefox, Netscape), mas praticamente todos os métodos lá descritos funcionam também nos outros browsers igualmente modernos.
Existem milhões de coisas que podem ser feita usando a dupla DOM/JavaScript. Geralmente, usamos a camada de comportamento para melhorar de alguma forma a experiência do usuário ao utilizar uma página web.
Não vou me estender mais no assunto. Leiam o que o Élcio escreveu sobre o assunto. O texto dele é bem explicativo e cita diversas fontes que podem ser usadas como referência para o aprendizado das tecnologias envolvidas no desenvolvimento da camada de comportamento.
Nota: Relendo o texto percebo que está muito aquém do que eu pretendia escrever. É difícil passar o conceito de camada de comportamento sem exemplificar, sem tornar o texto técnico.
Acho que a melhor coisa a fazer é publicar posts menores, com exemplos de código explicados, sobre cada camada. O que vocês acham?
- Comprar: Celular LG, MP9, Monitor LCD 17, Notebook, Notebook Apple, Celular
Desenvolver sites e aplicações pra web usando os padrões web significa, basicamente, usar cada tecnologia para o propósito único para o qual ela foi desenvolvida. Com isso, acabamos por organizar nosso código em “camadas”. São elas conteúdo, apresentação e comportamento. Vamos ver, separadamente, o que significa, para que serve e como desenvolver cada camada separadamente.
Neste texto vamos dar uma rápida passada pelas duas primeiras camadas, a de conteúdo e a de apresentação. A de comportamento fica para um próximo post.
Conteúdo
A camada de conteúdo é, sem sombra de dúvida, a mais importante de todas. É onde colocamos a parte mais preciosa do nosso site, aquilo que realmente faz a diferença no fim das contas — o conteúdo (surpresa!).
Para desenvolver essa camada usamos as chamadas linguagens de marcação de hipertexto, no nosso caso HTML ou XHTML.
O desenvolvimento deve sempre começar por esta camada. Antes de se preocupar com a parte visual ou comportamental de um site ou aplicação, deve-se estruturar com o maior cuidado e critério possível o conteúdo.
Quando você for começar a realmente pôr a mão na massa e escrever código, mesmo que já tenha um layout definido, tente não pensar na parte visual. Se atenha ao conteúdo. Como esse conteúdo é dividido? Que partes compõem esse conteúdo? Qual a função de cada parte do conteúdo dentro do site?
Tendo isso em mente, ordene essas partes por ordem de importância e relevância para os usuários. Certifique-se de que o que é mais importante seja colocado antes no código.
Preocupe-se com a semântica. Use os elementos certos para marcar o conteúdo. O HTML te dá uma quantidade consideravelmente boa de elementos para estruturar o seu conteúdo.
Abra o seu HTML puro em um browser. O que você vê na tela faz algum sentido? Verifique se é possível navegar tranquilamente pelo conteúdo usando o teclado.
Lembre-se, todo o restante do processo de desenvolvimento do seu site vai depender de como o seu conteúdo está estruturado. Se as coisas não estiverem bem estruturadas nessa camada, você vai, certamente, ter problemas no futuro. Revise o seu código, mexa no que tiver de ser mexido agora. Mais tarde pode ser tarde demais e o tempo que você vai perder será muito maior, acredite.
Estando tudo certo com a estruturação do conteúdo, podemos passar para a próxima camada.
Apresentação
Agora é a hora de aplicar aquele belo layout que você (ou o seu designer) criou para tornar o seu conteúdo mais atraente.
Nessa camada, vamos usar o CSS para definir propriedades visuais para cada elemento do seu conteúdo.
O mais importante aqui é manter as coisas simples. Evite usar propriedades que possam causar problemas em diferentes browsers. Em geral é possível criar qualquer tipo de layout usando apenas aquilo que é largamente suportado.
Resista à tentação de mexer na camada de conteúdo para satisfazer uma necessidade especificamente de apresentação. Pense um pouco mais. A solução pode ser mais simples do que você pensa. Use esse artifício apenas em casos de desespero total, quando tudo o mais falhar.
Lembre-se, se você tem um problema, é grande a chance de que alguém já tenha tido o mesmo problema e o tenha resolvido. Também é grande a chance de que esse alguém tenha publicado, em algum lugar, a solução, quem sabe, com uma bela explicação. Uma busca no google é sempre uma boa pedida.
Teste freqüentemente o resultado, de preferência em diversos browsers. Principalmente nos mais usados (IE, Firefox, Opera e Safari).
Quer uma dica? Use como base de testes um browser que tenha um melhor suporte aos padrões web. Firefox é uma bela opção para os usuários de windows. Para quem usa Mac, o Safari é a melhor opção.
O Internet Explorer é, de longe, o browser mais usado, mas tem um suporte bastante precário aos padrões. Por isso, se você tomá-lo como base para o seu desenvolvimento, será muito mais complicado consertar as falhas que serão notadas nos outros browsers.
Se você fez tudo direitinho até aqui, você tem um site bem estruturado e visualmente agradável e consistente.
Update: Leia o post sobre a camada de comportamento.