A propriedade CSS width no design responsivo

visualizações Publicado em: 08/04/2013

Introdução

Com a chegada do "Design Responsivo" tornou-se comum o uso da declaração width: 100%; para breakpoints contemplando larguras de viewport menores. Mas, você tem certeza que essa é a declaração certa a fazer?

Não é raro encontrarmos em fóruns, grupos e listas de discussão dedicadas ao design responsivo perguntas do tipo:

"Declarei width: 100%; para larguras abaixo de 480px, não tenho nenhum elemento com largura fixa na página, mas está aparecendo uma barra de rolagem horizontal. Alguém sabe como resolver esse bug?"

Criei uma página bem simples mostrando esse "bug" (vou mostrar adiante que não se trata de "bug"). Abra a página redimensione a largura da janela para um valor abaixo de 800px e observe a barra de rolagem. Para entender o que está acontecendo examine o código fonte da página e observe a regra media query para larguras menores que 800px. Ver a página exemplo (abre em outra janela).

Nessa matéria explico o porquê de em determinadas situações um elemento da marcação para o qual foi declarado width: 100%; acabar ficando com largura maior do que 100% causando aparecimento da barra de rolagem horizontal. Aliás vou um pouco além do que simplesmeste explicar o porquê e convido o leitor a um estudo detalhado da propriedade width das CSS.

A Especificação do W3C

A Especificação do W3C para as CSS2.1 na sua seção 10 item 10.2 prevê a propriedade width das CSS, como sendo aquela destinada a definir a largura da área do conteúdo de um box.
Lembro que o Box Model das CSS prevê uma área de margens ao redor do box (definida pela propriedade margin), uma área de bordas (definida pela propriedade border) e uma área de enchimento (definida pela propriedade padding). A área interna a essas áreas é a área do conteúdo do box (definida pela propriedade width).

Os valores possíveis para a propriedade width são:

  • lenght — o valor é expresso por uma unidade de medida de comprimento CSS;
  • percentage — o valor é expresso por uma porcentagem;
  • auto — esse é o valor inicial para todos os elementos;
  • inherit — o valor é herdado;

A propriedade width não se aplica a elementos inline do tipo "non-replaced" (elementos que não tenham dimensões intrínsecas), por exemplo elementos <strong>, <span>, <em>, <i>, etc. Elementos inline do tipo "replaced" são aqueles cujas dimensões e aparência são definidos por fatores externos, tais como os elementos <img>, <object> e elementos de formulário <button>, <input>, etc. Diz-se que tais elementos têm dimensões intrínsecas e a eles a propriedade width é aplicável
Ver a página exemplo (abre em outra janela);

Diferença entre width 100% e auto

A unidade de medida expressa em porcentagem é uma grandeza relativa. Relativa à uma referência. Assim, quando dizemos que a largura de um box é igual a 50% precisamos de um valor que sirva de referência para o cálculo daquela porcentagem. Podemos afirmar que o box terá a metade da largura da referência, mas se a largura da referência for indeterminada não teremos um valor determinado.

A Especificação para as CSS prevê que o valor de referência para cálculo da largura de um box, expressa em porcentagem, é igual à largura da área de conteúdo do box no qual ele está contido.

Em CSS o valor inicial da propriedade width de um box é sempre definido, e igual a auto. Assim, podemos concluir que o valor de referência sempre existirá, seja definido explicitamente seja o valor inicial.

Mas, qual o significado de auto? A Especificação diz que auto depende do valor de outras propriedades e explica como chegar a esse valor considerando inúmeras situações. Essas outras propriedades são: margin, border, padding e width do box e as situações dizem respeito ao tipo de box, se inline "replaced", inline "non-replaced", ou nível de bloco.

Para resumir todas as situações podemos simplificar dizendo que width: auto; refere-se à largura total do box.

Criei, conforme relacionadas a seguir, três páginas exemplo mostrando a definição desses valores de largura (100% e auto) para esclarecer na prática o que prevê a Especificação.

  • Esse exemplo (abre em outra janela) mostra um box container com largura de 600px e dentro dele foram criados dois boxes com largura igual a 100%. O primeiro possui borda e padding (a margem vertical não influi na largura e foi colocada somente para efeito de legibilidade) e o segundo não. Notar que o primeiro box apesar de ter sua largura declarada igual a 100% ultrapassou a borda direita do box container.

    A Especificação diz que o valor porcentagem para a propriedade width de um box é calculado em relação a largura da área de conteúdo do box no qual ele está contido. Então o primeiro box-filho terá largura total igual a 100% de 600px + paddings + borders e o segundo 100% de 600px + 0paddings + 0borders.

  • Esse exemplo (abre em outra janela), idêntico ao anterior mostra os dois boxes com largura igual a auto. Notar que os boxes não ultrapassaram a borda direita do box container.

    A Especificação diz que o valor auto para a propriedade width de um box é calculado levando em consideração margin, border, padding e width o que faz com que ambos os boxes-filho se ajustem dentro do box container.

  • Esse exemplo (abre em outra janela), idêntico ao anterior mostra dois boxes, um com largura igual a 100% e outro com largura igual a auto. Ambos possuem borda e padding (a margem vertical não influi na largura e foi colocada somente para efeito de legibilidade) e o segundo não. Notar que o primeiro box apesar de ter sua largura declarada igual a 100% ultrapassou a borda direita do box container e o segundo com largura declarada igual a auto não ultrapassou.

    Esse exemplo combina os dois anteriores e fornece a explicação para a questão proposta no início da matéria.

E agora eu pergunto:
Você tem mesmo certeza que no seu projeto de design responsivo deve declarar width: 100%; para pequenas larguras de viewport?

Mas, isso não é tudo!

A Especificação prevê que para boxes posicionados de forma absoluta o valor de referência para cálculo da porcentagem e igual à largura da área de conteúdo mais a área de padding do box container.

Esse exemplo (abre em outra janela) mostra um box container com width: 560px; e mais 20px de paddings laterais no qual foram inseridos dois boxes, o primeiro posicionado absolutamente e o segundo no fluxo normal, sem posicionamento. A ambos foi declarado width: 100%. Abra o exemplo, examine e analise o resultado. Experimente fazer uma cópia do arquivo e alterar para width: auto;

Convém lembrar que o Rascunho de Trabalho do W3C para o Módulo CSS3 UI prevê na seção 6 item 6.1 a propriedade box-sizing, que vem sendo largamente usada nos dias atuais. Essa propriedade altera o Box Model tradicional das CSS e elimina os efeitos indesejáveis da declaração width: 100% como mostrados nesse tutorial.