Por vezes o primeiro bit de HTML que escrevemos num novo documento é um elemento que envolve tudo o resto na página. O termo wrapper é comum para isso. Nós lhe damos uma classe, e essa classe é responsável por encapsular todos os elementos visuais da página.
P>Tenho sempre lutado com a melhor maneira de implementá-lo. Encontrei um tópico relacionado no StackOverflow que tem mais de 250.000 visualizações, então obviamente não sou o único que se pergunta! Vou resumir meus últimos pensamentos neste artigo.
Antes de mergulharmos nele, vamos primeiro examinar a diferença entre o “wrapper” e o “container”.
“Wrapper” vs “Container”
Eu acredito que existe uma diferença entre os elementos wrapper e container.
Em linguagens de programação, a palavra container é geralmente usada para estruturas que podem conter mais de um elemento. Um wrapper, por outro lado, é algo que envolve um único objeto para fornecer mais funcionalidade e interface para ele.
Então, na minha opinião, faz sentido ter dois nomes diferentes porque eles pretendem funções diferentes.
Falando do wrapper, é comum pensar em um <div>
que contém todo o resto do HTML do documento. Tenho certeza que muitos de nós já vivemos um tempo em que definimos isso para 960px em largura e centro alinhou todo o nosso conteúdo principal. Wrappers também são usados para coisas como aplicar um rodapé pegajoso.
O container, por outro lado, normalmente pretende outro tipo de contenção. Um que às vezes é necessário para implementar um comportamento ou estilo de múltiplos componentes. Serve para o propósito de agrupar elementos tanto semanticamente como visualmente. Como exemplo, Bootstrap tem “classes de contêineres” que abrigam seu sistema de grid ou contêm vários outros componentes.
Os termos wrapper e container também podem significar a mesma coisa dependendo do desenvolvedor e do que eles pretendem. Pode haver outras convenções também, então o melhor conselho é normalmente implementar o que fizer mais sentido para você. Mas lembre-se, nomear é uma das partes mais fundamentais e importantes das atividades do desenvolvedor. As convenções de nomenclatura tornam o nosso código mais legível e previsível. Escolha cuidadosamente!
Aqui está um exemplo de um envoltório de página geral:
/** * 1. Centers the content. Yes, it's a bit opinionated. * 2. See the "width vs max-width" section * 3. See the "Additional Padding" section */.wrapper { margin-right: auto; /* 1 */ margin-left: auto; /* 1 */ max-width: 960px; /* 2 */ padding-right: 10px; /* 3 */ padding-left: 10px; /* 3 */}
largura vs largura máxima
Configurando o width
de um elemento de nível de bloco irá impedir que ele se estique até as bordas de seu container (bom para coisas como comprimentos de linha legíveis). Portanto, o elemento envolvente irá ocupar a largura especificada. O problema ocorre quando a janela do navegador é mais estreita do que a largura específica do invólucro. Isso irá acionar uma barra de rolagem horizontal, o que é quase sempre indesejável.
Using max-width
em vez disso, nesta situação, é melhor para janelas mais estreitas do navegador. Isto é importante quando se faz um site utilizável em dispositivos pequenos. Aqui está um bom exemplo mostrando o problema.
Veja o Pen CSS-Tricks: A melhor maneira de implementar um CSS Wrapper por Kaloyan Kosev (@superKalo) em CodePen.
Em termos de resposta, max-width
é a melhor escolha!
Acolchoamento Adicional
Eu já vi muitos desenvolvedores esquecerem um caso de borda em particular. Digamos que temos um invólucro com max-width
definido para 980px. O edge case aparece quando a largura da tela do dispositivo do usuário é exatamente 980px. O conteúdo então cola exatamente nas bordas da tela sem espaço para respirar.
Queremos normalmente um pouco de acolchoamento nas bordas. É por isso que se eu precisar de implementar um invólucro com uma largura total de 980px, eu o faria assim:
.wrapper { max-width: 960px; /* 20px smaller, to fit the paddings on the sides */ padding-right: 10px; padding-left: 10px; /* ... */}
Por isso, é por isso que adicionar padding-left
e padding-right
ao seu invólucro pode ser uma boa ideia, especialmente em telemóveis.
Or, considere usar box-sizing para que o acolchoamento não mude a largura total.
Que elemento HTML escolher
Um wrapper não tem significado semântico. Ele simplesmente contém todos os elementos visuais e conteúdo da página. É apenas um recipiente genérico. Em termos de semântica, <div>
é a melhor escolha. O <div>
também não tem nenhum significado semântico e é apenas um recipiente genérico.
Pode-se perguntar se talvez um elemento <section>
poderia se encaixar neste propósito. No entanto, aqui está o que diz a especificação do W3C:
O elemento
<section>
não é um elemento genérico de contentor. Quando um elemento é necessário apenas para fins de estilo ou como uma conveniência para o scripting, os autores são encorajados a usar o elemento div em seu lugar. Uma regra geral é que o elemento de seção é apropriado somente se o conteúdo do elemento for listado explicitamente no esboço do documento.
The <section>
element carries it’s own semantics. Ele representa um agrupamento temático de conteúdo. O tema de cada secção deve ser identificado, normalmente incluindo um cabeçalho (elemento h1-h6) como um filho do elemento da secção.
Exemplos de secções seriam os capítulos, as várias páginas tabeladas numa caixa de diálogo tabelada, ou as secções numeradas de uma tese. A página inicial de um site poderia ser dividida em seções para uma introdução, notícias e informações de contato.
Pode não parecer muito óbvio à primeira vista, mas sim! O simples ol’ <div>
cabe melhor para um invólucro!
Usando o <body> tag vs. Usando um adicional <div>
É importante mencionar que haverá alguns casos em que se poderá usar o elemento <body>
como um invólucro. A seguinte implementação funcionará perfeitamente bem:
body { margin-right: auto; margin-left: auto; max-width: 960px; padding-right: 10px; padding-left: 10px;}
E resultará em menos um elemento no seu markup porque você pode soltar aquele wrapper desnecessário <div>
desta forma.
No entanto, eu não recomendaria isto, devido à flexibilidade e resiliência às mudanças. Imagine se, numa fase posterior do projecto, algum destes cenários acontecer:
- Você precisa de forçar um rodapé para “colar” no final do documento (no fundo do viewport quando o documento é curto). Mesmo que você possa usar a maneira mais moderna de fazê-lo – com o flexbox, você precisa de um wrapper adicional
<div>
. - Você precisa definir o
background-color
da página inteira. Normalmente, qualquer que seja o fundo que você definir no<body>
comportar-se-á como se estivesse definido no elemento<html>
caso ainda não tenha um fundo. Apenas uma coisa estranha no CSS. Mas se o seu elemento<html>
já tiver um fundo, e você definir o corpo para outra coisa, e o corpo tiver qualquer tipo de restrição de espaçamento, os fundos vão ficar esquisitos. É uma coisa complicada.
Eu concluiria que ainda é melhor prática ter um <div>
adicional para implementar um envoltório CSS. Desta forma, se os requisitos de especificação mudarem mais tarde, você não terá que adicionar o wrapper mais tarde e lidar com a movimentação dos estilos. Afinal de contas, estamos falando apenas de um elemento DOM extra.