Trabalhando com Estilos no DOM
Aprenda a estilizar elementos DOM em JavaScript: estilos inline, a propriedade style e cssText, leitura de valores com getComputedStyle e alternância de classes CSS com a API classList.
Ao trabalhar com o Document Object Model (DOM) em JavaScript, alterar a aparência de um elemento em tempo de execução é uma das tarefas mais comuns. Este guia cobre as maneiras práticas de aplicar estilos a elementos DOM: escrever estilos inline, ler e definir propriedades CSS individuais por meio da propriedade style, substituir várias propriedades de uma vez com cssText, ler os estilos resolvidos com getComputedStyle() e — a abordagem recomendada para a maioria dos casos — alternar classes CSS com a API classList.
A versão resumida: prefira classes em vez de estilos inline. A manipulação direta de estilos é adequada para valores computados em tempo de execução (uma posição, uma cor escolhida dinamicamente), mas para qualquer coisa que represente um estado — "ativo", "concluído", "erro" — defina uma classe em CSS e alterne-a pelo JavaScript. Este guia mostra os dois, e explica quando cada um é a ferramenta certa. Para uma visão mais ampla sobre estilização de elementos, veja Estilos e Classes.
Estilos Inline
Os estilos inline aplicam CSS diretamente a um elemento HTML por meio do atributo style. São úteis para alterações rápidas e pontuais, mas não escalam: misturam apresentação à marcação, não podem ser reutilizados e vencem toda batalha de especificidade exceto !important, o que os torna difíceis de sobrescrever mais tarde.
Exemplo
<div id="inlineStyleExample">This text will be styled using inline styles.</div>
<button onclick="applyInlineStyle()">Apply Inline Style</button>
<script>
function applyInlineStyle() {
const element = document.getElementById('inlineStyleExample');
element.style.color = 'red';
element.style.fontSize = '20px';
}
</script>Neste exemplo, clicar no botão aplicará estilos inline ao elemento div, alterando a cor do texto para vermelho e o tamanho da fonte para 20 pixels.
Definindo Estilos com a Propriedade style
A propriedade style fornece um objeto CSSStyleDeclaration que mapeia o estilo inline do elemento. Ler e escrever nela é o equivalente em JavaScript de editar o atributo style — portanto, compartilha as mesmas vantagens e desvantagens dos estilos inline, mas permite computar valores dinamicamente.
Duas regras costumam confundir as pessoas:
- Os nomes das propriedades CSS se tornam camelCase. Propriedades com hífen como
font-sizeebackground-colorse tornamstyle.fontSizeestyle.backgroundColor. A exceção éfloat, que virastyle.cssFloatporquefloaté uma palavra reservada. - Os valores são strings, com unidades.
element.style.width = 200não faz nada; é preciso escreverelement.style.width = '200px'. Da mesma forma, lerelement.style.colorapós defini-lo retorna uma string como'rgb(0, 0, 255)'.
Exemplo
<div id="stylePropertyExample">This text will be styled using JavaScript.</div>
<button onclick="applyStyleProperty()">Apply Style Property</button>
<script>
function applyStyleProperty() {
const element = document.getElementById('stylePropertyExample');
element.style.color = 'blue';
element.style.fontSize = '18px';
element.style.margin = '10px';
}
</script>Neste exemplo, clicar no botão aplicará vários estilos ao elemento div usando a propriedade style. A cor do texto é definida como azul, o tamanho da fonte como 18 pixels, e uma margem de 10 pixels é adicionada.
Definindo várias propriedades de uma vez com cssText
Atribuir uma propriedade por vez aciona uma escrita separada a cada vez. Quando você precisa definir várias propriedades juntas, style.cssText permite atribuí-las em uma única instrução usando a sintaxe CSS comum:
element.style.cssText = 'color: white; background-color: navy; padding: 8px;';Esteja ciente de que atribuir cssText substitui todos os estilos inline existentes, portanto, use-o para definir um bloco completo, em vez de ajustar um único valor. Para remover uma propriedade individual, defina-a como string vazia (element.style.color = '') ou chame element.style.removeProperty('color').
Lendo o estilo real com getComputedStyle()
A propriedade style reflete apenas estilos inline. Se uma cor vem de uma folha de estilos ou de uma classe, element.style.color será uma string vazia. Para ler o valor que o navegador realmente aplicou — após a resolução de folhas de estilos, classes e herança — use window.getComputedStyle():
<p id="styledByCss">I am styled by a stylesheet.</p>
<button onclick="readStyle()">Read computed color</button>
<script>
function readStyle() {
const element = document.getElementById('styledByCss');
// element.style.color would be '' — the color comes from CSS, not inline.
const computed = window.getComputedStyle(element);
alert('Computed color: ' + computed.color);
}
</script>
<style>
#styledByCss {
color: green;
}
</style>Os valores computados são retornados em uma forma normalizada e somente leitura — cores como rgb(...), comprimentos em px — portanto, getComputedStyle(element).color retorna 'rgb(0, 128, 0)' em vez de 'green'.
Manipulação de Classes
Gerenciar classes é a maneira recomendada de estilizar elementos: a estilização fica no seu CSS, e o JavaScript apenas ativa e desativa classes. A propriedade classList expõe uma API pequena e bem nomeada — add(), remove(), toggle(), contains(), replace() e item() — que é mais clara e segura do que construir strings com className.
Por que preferir classList em vez de className? Escrever element.className = 'highlight' sobrescreve todas as classes existentes, então você pode acidentalmente remover classes das quais outra parte do seu código depende. classList.add('highlight') adiciona apenas aquela classe e deixa o restante intacto.
Adicionando Classes
O método add() adiciona uma ou mais classes a um elemento. Adicionar uma classe que já está presente não faz nada, portanto, é seguro chamá-lo repetidamente.
Exemplo
<div id="addClassExample">This element will have classes added.</div>
<button onclick="addClass()">Add Class</button>
<script>
function addClass() {
const element = document.getElementById('addClassExample');
element.classList.add('highlight', 'text-large');
}
</script>
<style>
.highlight {
background-color: yellow;
}
.text-large {
font-size: 24px;
}
</style>Neste exemplo, clicar no botão adicionará as classes highlight e text-large ao elemento div, aplicando os estilos correspondentes.
Removendo Classes
O método remove() remove uma ou mais classes de um elemento. Remover uma classe que não está presente é uma operação nula, portanto, não é necessário verificar antes.
Exemplo
<div id="removeClassExample" class="highlight text-large">
This element will have classes removed.
</div>
<button onclick="removeClass()">Remove Class</button>
<script>
function removeClass() {
const element = document.getElementById('removeClassExample');
element.classList.remove('highlight', 'text-large');
}
</script>
<style>
.highlight {
background-color: yellow;
}
.text-large {
font-size: 24px;
}
</style>Aqui, clicar no botão removerá as classes highlight e text-large do elemento div.
Alternando Classes
O método toggle() adiciona uma classe se ela não estiver presente e a remove se estiver — perfeito para estados de ativar/desativar, como um menu aberto ou uma tarefa concluída. Retorna true se a classe estiver presente após a chamada e false caso contrário.
Você também pode forçar o resultado com um segundo argumento boolean: toggle('active', true) sempre adiciona a classe, e toggle('active', false) sempre a remove. Isso é útil quando o estado desejado vem de uma variável: element.classList.toggle('active', isActive).
Exemplo
<div id="toggleClassExample">Click me to toggle the highlight class.</div>
<button onclick="toggleClass()">Toggle Class</button>
<script>
function toggleClass() {
const element = document.getElementById('toggleClassExample');
element.classList.toggle('highlight');
}
</script>
<style>
.highlight {
background-color: yellow;
}
.text-large {
font-size: 24px;
}
</style>Neste exemplo, clicar no botão alternará a classe highlight no elemento div, ativando e desativando-a.
Verificando Classes
O método contains() retorna true se um elemento possui uma classe específica e false caso contrário. Use-o para ramificar com base no estado atual, por exemplo, para atualizar o rótulo de um botão.
Exemplo
<div id="containsClassExample" class="highlight">
This element's classes will be checked.
</div>
<button onclick="checkClass()">Check Class</button>
<script>
function checkClass() {
const element = document.getElementById('containsClassExample');
if (element.classList.contains('highlight')) {
alert('The element has the highlight class.');
} else {
alert('The element does not have the highlight class.');
}
}
</script>
<style>
.highlight {
background-color: yellow;
}
.text-large {
font-size: 24px;
}
</style>Aqui, clicar no botão verificará se o elemento containsClassExample possui a classe highlight e exibirá um alerta de acordo.
Substituindo uma Classe
O método replace() troca uma classe por outra em uma única chamada e retorna true se a classe antiga existia e foi substituída. É mais limpo do que chamar remove() e depois add():
<div id="replaceClassExample" class="theme-light">Switch my theme.</div>
<button onclick="swapTheme()">Toggle theme</button>
<script>
function swapTheme() {
const element = document.getElementById('replaceClassExample');
if (!element.classList.replace('theme-light', 'theme-dark')) {
// It wasn't 'theme-light', so swap the other way.
element.classList.replace('theme-dark', 'theme-light');
}
}
</script>
<style>
.theme-light { background: #fff; color: #111; padding: 8px; }
.theme-dark { background: #111; color: #fff; padding: 8px; }
</style>classList também é iterável, e classList.item(index) retorna a classe em uma determinada posição (ou null se o índice estiver fora do intervalo), o que é ocasionalmente útil quando você precisa ler as classes uma a uma.
Exemplo do Mundo Real: Lista de Tarefas Interativa
Para demonstrar esses conceitos em um cenário do mundo real, vamos construir uma pequena lista de tarefas interativa. Novas tarefas são adicionadas à lista, e clicar em uma tarefa alterna uma classe completed que a risca — um caso típico para classList.toggle().
<div>
<h2>To-Do List</h2>
<p>Here, you can add new items, and mark it as completed by clicking on them.</p>
<input type="text" id="newTask" placeholder="Add a new task" />
<button id="addTaskButton">Add Task</button>
<ul id="taskList"></ul>
</div>
<script>
const newTaskInput = document.getElementById('newTask');
const addTaskButton = document.getElementById('addTaskButton');
const taskList = document.getElementById('taskList');
addTaskButton.addEventListener('click', () => {
const taskText = newTaskInput.value;
if (taskText) {
const taskItem = document.createElement('li');
taskItem.textContent = taskText;
taskItem.classList.add('task');
taskItem.addEventListener('click', () => {
taskItem.classList.toggle('completed');
});
taskList.appendChild(taskItem);
newTaskInput.value = '';
}
});
</script>
<style>
.task {
cursor: pointer;
padding: 5px;
border-bottom: 1px solid #ccc;
}
.task.completed {
text-decoration: line-through;
color: gray;
}
</style>Neste exemplo, criamos uma aplicação de lista de tarefas onde as tarefas podem ser adicionadas e marcadas como concluídas ao clicar nelas. A classe task estiliza as tarefas, enquanto a classe completed, aplicada com o método toggle(), indica as tarefas concluídas.
Boas Práticas
Para garantir um código eficiente e de fácil manutenção ao trabalhar com estilos no DOM, considere as seguintes boas práticas:
- Separação de Responsabilidades: Mantenha seu HTML, CSS e JavaScript separados. Use JavaScript para manipular classes em vez de definir estilos diretamente sempre que possível. Essa abordagem mantém a separação de responsabilidades e torna seu código mais fácil de gerenciar.
- Evite Estilos Inline: Use estilos inline com moderação. Os estilos inline podem deixar seu HTML confuso e mais difícil de manter. Prefira adicionar e remover classes definidas no seu CSS.
- Use Classes para Reusabilidade: Defina classes reutilizáveis no seu CSS e use JavaScript para alterná-las. Essa abordagem permite uma estilização mais consistente em toda a aplicação e facilita a atualização de estilos.
- Aproveite os Métodos de
classList: Use os métodos declassList(add,remove,toggle,contains) para gerenciar classes com eficiência. Esses métodos são diretos e têm bom desempenho em comparação com a manipulação direta da propriedadeclassName. - Considerações de Performance: Fique atento ao desempenho ao manipular o DOM. Alternar uma única classe aciona um conjunto de recálculos de estilo, enquanto definir várias propriedades uma a uma em
element.stylepode causar reflows repetidos. Para orientações mais detalhadas, veja Otimização de Performance do DOM.
Prefira transições e animações CSS em vez de loops de animação controlados por JavaScript. Alterne uma classe e deixe o navegador animar a mudança — ele roda no compositor e geralmente é mais suave. Veja Animações CSS para mais detalhes.
Conclusão
Manipular estilos no DOM é essencial para interfaces dinâmicas e interativas. Use a propriedade style (e cssText) para valores computados em tempo de execução, getComputedStyle() para ler os estilos que o navegador realmente aplicou, e a API classList — add, remove, toggle, contains, replace — para tudo que representa um estado reutilizável. Como regra geral, recorra primeiro às classes e use estilos inline apenas quando necessário.
Para continuar explorando o DOM, veja Manipulação do DOM, Selecionando Elementos do DOM e Atributos e Propriedades.