Em projetos de interfaces móveis, um dos problemas mais recorrentes envolve o cálculo incorreto das dimensões dos elementos. Quando aplicamos padding e border, o modelo de caixa padrão do CSS frequentemente faz com que os componentes ultrapassem os limites do contêiner pai. Este artigo explora a propriedade box-sizing, seu funcionamento, cenários comuns de uso e as melhores abordagens para resolver esses desafios.
Modelo de Caixa Padrão vs. Modelo Alternativo
Modelo Padrão (content-box)
No modelo de caixa convencional, a largura total de um elemento é calculada somando a largura declarada com os espaçamentos internos e bordas:
largura_total = width + padding-left + padding-right + border-left + border-right
Exemplo prático:
.bloco-principal {
width: 100%;
padding: 18px;
border: 3px solid #aaa;
}
/* Largura real = 100% + 36px + 6px = 100% + 42px */
Modelo Alternativo (border-box)
Ao aplicar box-sizing: border-box, o cálculo muda e o valor de width já inclui padding e border:
.bloco-principal {
width: 100%;
padding: 18px;
border: 3px solid #aaa;
box-sizing: border-box;
}
/* Largura real = 100% (padding e border inclusos) */
Problemas Frequentes em Interfaces Móveis
Campos de Texto Ultrapassando o Contêiner
Em formulários para dispositivos móveis, campos de entrada frequentemente transbordam horizontalmente.
<div class="wrapper-formulario">
<input class="campo-texto" type="email" placeholder="Seu e-mail" />
</div>
<style>
.wrapper-formulario {
width: 100%;
padding: 15px;
}
.campo-texto {
width: 100%;
padding: 10px 14px;
border: 1.5px solid #bbb;
}
</style>
Análise do problema:
- Largura declarada: 100%
- Espaçamento horizontal total: 28px (14px × 2)
- Borda horizotnal total: 3px (1.5px × 2)
- Largura real: 100% + 31px → estouro do contêiner
Layout de Grade com Largura Fixa
Componentes com larguras fixas podem causar problemas ao adaptar para telas menores:
.painel {
width: 280px;
padding: 18px;
border: 1px solid #ddd;
margin: 8px;
}
@media (max-width: 600px) {
.painel {
width: 100%;
/* Largura real = 100% + 38px → possível estouro */
}
}
Estratégias de Solução
Abordagem 1: Aplicar box-sizing: border-box
Esta é a solução mais recomendada e pode ser aplicada globalmente:
/* Reset global recomendado */
*,
*::before,
*::after {
box-sizing: border-box;
}
/* Ou para componentes específicos */
.campo-texto {
width: 100%;
padding: 10px 14px;
border: 1.5px solid #bbb;
box-sizing: border-box;
}
Abordagem 2: Função calc()
Uma alternativa que exige cálculo manual:
.campo-texto {
width: calc(100% - 31px);
padding: 10px 14px;
border: 1.5px solid #bbb;
}
Esta abordagem é menos prática porque obriga o desenvolvedor a recalcular sempre que os valores de padding ou border mudarem.
Abordagem 3: Flexbox
O Flexbox gerencia automaticamente o espaço disponível:
.wrapper-formulario {
display: flex;
}
.campo-texto {
flex: 1;
padding: 10px 14px;
border: 1.5px solid #bbb;
}
Implementação em Projetos Reais
Componente de Busca Móvel
Código com o problema de estouro:
<div class="barra-pesquisa">
<input
class="entrada-pesquisa"
type="search"
placeholder="Buscar produtos..."
/>
</div>
<style lang="scss">
.barra-pesquisa {
padding: 12px;
}
.entrada-pesquisa {
width: 100%;
height: 44px;
padding: 0 12px;
border: 2px solid $cor-borda;
border-radius: 6px;
}
</style>
Versão corrigida com wrapper adicional:
<div class="barra-pesquisa">
<div class="envelope-entrada">
<input
class="entrada-pesquisa"
type="search"
placeholder="Buscar produtos..."
/>
</div>
</div>
<style lang="scss">
.envelope-entrada {
position: relative;
width: 100%;
}
.entrada-pesquisa {
width: 100%;
height: 44px;
padding: 0 12px;
border: 2px solid $cor-borda;
border-radius: 6px;
box-sizing: border-box;
}
</style>
Grade de Cartões Responsiva
*,
*::before,
*::after {
box-sizing: border-box;
}
.cartao {
width: 100%;
max-width: 280px;
padding: 18px;
border: 1px solid #eee;
border-radius: 6px;
margin: 8px;
}
.grade-cartoes {
display: flex;
flex-wrap: wrap;
gap: 16px;
}
@media (max-width: 600px) {
.cartao {
max-width: none;
}
}
Compatibilidade e Recomendações
Suporte dos Navegadores
A propriedade box-sizing possui amplo suporte:
- IE8+
- Chrome 4+
- Firefox 2+
- Safari 3.1+
- Todos os navegadores móveis modernos
Boas Práticas
Reset global no início do projeto:
*,
*::before,
*::after {
box-sizing: border-box;
}
Mixin com pré-processadores:
@mixin modelo-caixa($tipo: border-box) {
box-sizing: $tipo;
}
.entrada-dados {
@include modelo-caixa;
width: 100%;
padding: 14px;
border: 2px solid #ccc;
}
Armadilhas Comuns
Conflito com Bibliotecas de Terceiros
Algumas bibliotecas mantêm o modelo padrão, o que pode gerar conflitos visuais:
.componente-externo {
box-sizing: content-box !important;
}
Elementos de Mídia
Imagens e vídeos geralmente devem manter o comportamento padrão, pois suas dimensões são intrínsecas:
img,
video,
iframe {
box-sizing: content-box;
}
Considerações de Desempenho
Embora o impacto no desempenho seja mínimo, é perferível usar o reset global do que aplicar box-sizing individualmente em cada elemento do DOM.