Quer aprender a criar seu próprio no Layout Responsivo? Então você está no lugar certo. Aqui você vai ver todos os artigos relacionados a Layout Responsivo e muito mais sobre desenvolvimento.

O módulo CSS Flexible Box Layout, ou simplesmente Flexbox Layout, é uma Candidate Recommendation (CR) da W3C que visa proporcionar uma forma mais eficiente para alinhar e distribuir o espaço entre itens de uma página HTML, independente do tamanho desses itens. O nome Flexbox vem muito a calhar, pois, os elementos são flexíveis e relativos ao tamanho da tela, você pode vê-los aumentar ou diminuir de tamanho apenas redimensionando a tela do seu navegador.

A ideia por trás das caixas flexíveis do módulo Flexbox é dar a possibilidade de elementos "pai" redimensionarem o tamanho (width e height) dos seus elementos filhos, para que estes fiquem na ordem desejada e acomodem-se ao tamanho da tela em que o usuário deseja visualizar o conteúdo da página.

Outro fato interessante do Flexbox Layout é que você não está limitado quanto à posição dos elementos da sua página, ou seja, um elemento pode ser adicionado ao final do seu código HTML e ser apresentado como o primeiro elemento da página, apenas alterando a sua propriedade CSS order: <número>;.

Vamos ver como isso funciona na prática logo abaixo.

Flexbox precisa de "pai" e "filho(s)"

Se você trabalha como desenvolvedor, deve saber que existem alguns elementos que dependem de outros para que algumas propriedades CSS funcionem, como é o caso de elementos com posição absoluta dentro de elementos com posição relativa, além de outros.

Com Flexbox isso não é diferente, você pode ter um (ou vários) elemento(s) "pai" e seus elementos "filhos" receberão as propriedades que você indicar, como por exemplo, se eles serão alinhados como "linha" (row) ou  coluna (column).

Veja um exemplo:

Modelo layout - Pai Filho

Nesse caso, o HTML seria algo parecido com:

<div class="pai">
	<div class="filho">1</div>
	<div class="filho">2</div>
	<div class="filho">3</div>
</div>

Com essa estrutura em mente, vamos ver um pouco mais de perto as propriedades do módulo Flexbox.

display: flex;

Propriedade do elemento pai.

Para começar, você pode definir um container flexível (flex) com as propriedades flex ou inline-flex, que correspondem, respectivamente, à propriedades block e inline.

.pai{
	display: flex ou inline-flex;
}

Isso ainda não fará nada ao seu elemento, pois, você precisa das outras propriedades. Você verá exemplos mais adiante.

order

Propriedade do elemento filho.

Como eu disse no início do artigo, "filhos" de um elemento flexbox não precisam de uma ordem no seu documento HTML, você pode escolher essa ordem utilizando a propriedade order.

.pai > .filho:nth-child(1){
	order:3;
}

Neste casso, o elemento com classe filho que está na posição 1, apareceria na terceira posição.

Codepen 1

flex-direction

Propriedade do elemento pai.

Elementos filhos de uma elemento flexbox, são baseados em eixos (main e cross), sendo o eixo main tratando da parte horizontal da página e o cross da parte vertical. Sendo assim, flex-direction representa a direção em que os filhos do elemento flexbox serão posicionados, em modo linha (row) ou coluna (column).

As propriedades aceitas são:

  • row – Linha
  • row-reverse – Linha de maneira invertida
  • column – Coluna
  • column-reverse – Coluna de maneira invertida

Codepen 2.

flex-grow

Propriedade do elemento filho.

Essa é uma propriedade extremamente interessante, ela descreve que qualquer um dos elementos filhos podem "crescer" para se adaptar ao conteúdo. O padrão é 0, para não crescer, se você modificar este valor para 1, o elemento filho que recebeu essa propriedade sempre vai se adequar ao tamanho da tela utilizando os espaços que sobraram.

.pai{
    display: flex;
    flex-direction: row;
    flex-wrap: wrap;
    max-width:1200px;
    margin:0 auto;
    background:#ccc;
}
.pai > .filho{
    width:50%;
    height:100px;
    background:purple;
    color:#fff;
}
.pai > .filho:nth-child(1){
    background:yellow;
    color:#000;
    flex-grow:1;
}
.pai > .filho:nth-child(2){
    background:pink;
    color:#000;
}
.pai > .filho:nth-child(3){
    flex-grow:1;
}

Codepen 3.

flex-wrap

Propriedade do elemento pai.

Por padrão, os filhos do elemento tentarão se adaptar em uma única linha, porém, você pode modificar isso com flex-wrap.

.pai{
    flex-wrap: nowrap | wrap | wrap-reverse;
}

A primeira opção acima, é padrão, a segunda, faz com que os filhos "quebrem" a linha se for necessário, a terceira faz o mesmo, porém de maneira inversa:

.pai{
    display: flex;
    flex-direction: row;
    /* WRAP-REVERSE */
    flex-wrap: wrap-reverse;
    max-width:1200px;
    margin:0 auto;
    background:#ccc;
}
.pai > .filho{
    width:50%;
    height:100px;
    background:purple;
    color:#fff;
}
.pai > .filho:nth-child(1){
    background:yellow;
    color:#000;
    flex-grow:1;
}
.pai > .filho:nth-child(2){
    background:pink;
    color:#000;
}
.pai > .filho:nth-child(3){
    flex-grow:1;
}

Codepen 4.

justify-content

Propriedade do elemento pai.

Esqueça suas margens, essa propriedade calcula tudo para você. Veja seus valores:

  • flex-start (padrão): filhos começam a ser exibidos do começo
  • flex-end: filhos começam a ser exibidos do fim
  • center: filhos centralizados
  • space-between: primeiro filho encostado no começo do elemento pai, último filho encostado na linha final do pai, os outros filhos (do meio) terão espaços iguais entre eles.
  • space-around: espaço do elemento pai dividido igualmente entre os elementos filhos.

Veja um "Codepen" de exemplo:

Codepen 5.

Muito bom!

align-items

Propriedade do elemento pai.

Essa propriedade faz quase a mesma coisa do exemplo anterior, porém, ela alinha os elementos baseando-se do eixo cross (vertical). Veja seus valores:

  • flex-start: filhos começam a ser exibidos do começo
  • flex-end: filhos começam a ser exibidos do fim
  • center: centralizados
  • baseline: filhos são alinhados como suas baselines
  • stretch (padrão): Esticam para ocupar todo o espaço do pai

Veja um exemplo de código:

.pai{
  display: flex;
  flex-direction: row;
  flex-wrap: wrap;
  justify-content: space-around;
  align-items: stretch;
  max-width:1200px;
  height:540px;
  margin:0 auto;
  background:#eee;
}

Agora um exemplo rodando no navegador (Codepen):

Codepen 6.

align-self

Propriedade do elemento filho.

Essa opção da a possibilidade de alinhar um único filho em posições diferentes do que a escolhida nas opções do elemento pai.

Suas opções são as mesmas da propriedade anterior:

  • flex-start: filhos começam a ser exibidos do começo
  • flex-end: filhos começam a ser exibidos do fim
  • center: centralizados
  • baseline: filhos são alinhados como suas baselines
  • stretch (padrão): Esticam para ocupar todo o espaço do pai

Veja um exemplo de código:

.pai > .filho:nth-child(3){
  align-self: flex-end;
}

Agora um "Codepen" (Não pode faltar, né!).

CodePen 7.

Mais propriedades

Além de tudo o que eu disse anteriormente, ainda existem mais propriedades. Aconselho que você leia os artigos abaixo, de onde tirei maioria dos exemplos do que você leu acima:

Caso tenha alguma dúvida, critica ou correção, mande nos comentários.

Criar um layout responsivo não é tão complicado quando você tem em mente o que deseja. Por exemplo, no vídeo que você vai assistir nesse artigo, queria criar um layout com menu superior, conteúdo na esquerda, barra lateral na direita e um rodapé simples. Também gostaria que o conteúdo tivesse largura máxima de 1200px e que a barra lateral seguisse o fluxo do layout quando o usuário visualizasse o site utilizando um smartphone.

Então decidi tentar montar o layout correndo aqui, sem testar em nenhum navegador mais antigo nem me preocupar com cores, fundos, nem nada disso, somente a estrutura. Fiz isso para que você possa entender o processo da criação e o estilo que costumo começar um desenvolvimento. Normalmente eu crio a estrutura primeiro e depois trabalho o restante do layout.

Como resultado? Como você vai ver, ficou horrível, porém atingimos o objetivo de criar a estrutura de um layout responsivo. Agora só precisamos ajustar as cores (é óbvio), fontes e coisas do tipo. Não esquecendo de testar em outros navegadores para corrigir os bugs, por exemplo, o menu precisa de um "fix" para o IE6 e IE7 no menu. Também aconselharia verificar a largura mínima para o IE8, já que media queries não funcionam nele (ou utilizar algo que faça funcionar, como respond.js).

Assista ao vídeo abaixo.

Layout responsivo em 8 minutos

Obs.: Não é um problema no áudio, eu gravei sem microfone propositalmente para não demorar muito e focar completamente no código.

Só isso!

O código do vídeo

Se quiser copiar o código do vídeo, segue abaixo:

<!DOCTYPE html>
<html>
	<head>
		<meta charset="UTF-8">
		
		<title>TutsUP - Layout Responsivo</title>
		
		<style>
		body, html{
			margin:0;
			padding:0;
		}
		.main{
			max-width:1200px;
			margin:0 auto;
			overflow:hidden;
			background:lightgray;
		}
		.content{
			float:left;
			width:100%;
			margin-right:-210px;
		}
		.content-inner{
			margin-right:210px;
		}
		.sidebar{
			background:red;
			float:right;
			width:200px;
		}
		.menu{
			width:100%;
			background:blue;
		}
		.menu ul{
			margin:0; 
			padding:0;
		}
		.menu ul li{
			display:inline-block;
			*display:inline;
			zoom:1;
			margin:0; 
			padding:0;
		}
		.menu ul li a{
			display:block;
			padding:20px;
			color:#fff;
		}
		.footer{
			width:100%;
			background:yellow;
			text-align:center;
		}
		
		@media screen and (max-width: 700px) {
			.sidebar, .content-inner, .content{
				float: none;
				width: 100%;
				margin-right:0;
			}
		}
		</style>
		</head>
	<body>
		<div class="main">
			<div class="menu">
				<ul>
					<li> <a href="#"> menu </a> </li>
					<li> <a href="#"> menu </a> </li>
				</ul>
			</div>
			<div class="content">
				<div class="content-inner">
					Conteúdo
				</div>
				
			</div>
			<div class="sidebar">
				Barra lateral
			</div>
			
			<br style="clear:both">
			
			<div class="footer">
				Rodapé
			</div>
		</div>
	</body>
</html>

Provavelmente isso vai funcionar perfeitamente em todos os navegadores. Apenas media queries (como eu disse), precisam ser analisadas no IE6, 7 e 8.

Ajustar imagens para layouts responsivos com CSS é uma das únicas medidas que temos atualmente para garantir que a imagem seja exibida no tamanho que queremos em qualquer tamanho de tela. Claro que temos milhares de soluções JS e server-side para garantir que o usuário final do seu site não tenha que baixar bytes desnecessários para cada imagem que você utilizar no seu layout. Além disso, também poderíamos esperar o futuro do elemento picture para modificarmos a maneira em que desenvolvemos nossos sites, mas, como ninguém vive de futuro, ainda temos que utilizar o que nos é dado para garantir a compatibilidade com todos os navegadores ainda disponíveis no mercado (Leia-se: os IEs da vida).

A solução que vou passar aqui não é nada amigável em termos de largura de banda, mas vai resolver o problema do seu layout responsivo em todos os navegadores (com exceção do IE6).

Se você já é do ramo, provavelmente já deve saber que estou falando da propriedade max-width do CSS, mas como este blog não tem foco só em pessoas com alto nível de conhecimento, vamos partilhar a informação.

O básico do básico

Como eu descrevi anteriormente, se você já cria sites com layout responsivo, já deve conhecer o trecho de CSS abaixo:

img{
	max-width:100%;
	height:auto;
}

Isso faz com que todas as imagens do seu layout sejam redimensionadas para o tamanho máximo do elemento que as envolve, ou seja, se sua imagem estiver direto dentro da tag body do seu HTML, ela terá o tamanho alterado nos seguintes casos:

  1. Se a largura da tela do navegador for maior que a largura da imagem, ela será mostrada em seu tamanho real;
  2. Se a largura da tela do navegador for menor que a largura da imagem, ela terá sua largura reduzida para a largura da tela do navegador;

Exemplo no código:

<!DOCTYPE html>
<html>
<head>
<style>
img{
	max-width:100%;
	height:auto;
}
</style>
</head>

<body>
	<img src="cropped.jpg" />
</body>
</html>

Imagem redimensionada

Se você quiser colocar a imagem dentro de um elemento HTML e quer que apenas as imagens desse elemento tenham a largura adaptável, basta fazer da seguinte maneira:

.post-content{
	max-width:700px;
}
.post-content img{
	max-width:100%;
}

Se a imagem estiver dentro de qualquer elemento com a classe .post-content, tanto o elemento quanto a imagem terão largura máxima de 700px:

<div class="post-content">
	<img src="cropped.jpg" />
</div>

Neste caso, a DIV com classe .post-content é o foco, ela terá a largura máxima de 700px e todas as imagens dentro dela também.

Forçando a barra

Se por algum erro no seu desenvolvimento, alguma classe ou ID tiverem precedência sobre a classe ou ID que ajustam as imagens, você pode tentar forçar com a propriedade !important no seu CSS.

.post-content{
	max-width:700px;
}
.post-content img{
	max-width:100% !important;
}

Mas lembre-se, se você declarou seu CSS corretamente, não há motivos para utilizar !important (leia este artigo para entender melhor). É um erro no fluxo do seu código e deve ser corrigido.

Concluindo

Este foi um tutorial bem básico, mas espero que tenha entendido e agregado conhecimento aos seus estudos. Lembre-se de nunca parar de buscar novos conhecimentos, estamos sempre aprendendo algo novo, ou reaprendendo algo que já sabíamos.

Um layout responsivo com coluna fixa tem várias vantagens para a maioria dos tamanhos de tela em que ele será exibido. Se o cliente estiver vendo seu conteúdo em um smartphone, o layout irá se adaptar àquele tamanho de tela sem redirecionar a página para outro endereço.

O mesmo acontece quando o cliente estiver em seu desktop ou tablet, ou seja, um único layout que se adapta para qualquer tamanho de monitor ou tela.

Criar um layout responsivo não é nada complicado, porém, deve-se tomar bastante cuidado, principalmente se você já tem o costume de trabalhar com layouts de largura fixa.

No layout responsivo os elementos devem ser redimensionados automaticamente para a largura do elemento que os envolve caso o usuário modifique o tamanho da tela de seu navegador, ou acesse o site em um dispositivo com tela pequena, como um smartphone, por exemplo.

Por que barra fixa?

A barra fixa tem vantagens e desvantagens. Uma das vantagens é quando o site tem que exibir conteúdo fixo na barra lateral, como é o exemplo de anúncios do Adsense. Como o conteúdo é fixo, ficaria sem lógica a sua barra lateral ser redimensionada juntamente com o conteúdo do site.

Por outro lado, uma das desvantagens da barra lateral fixa é que ela terá que seguir o fluxo do layout quando a tela for pequena demais. Com isso, seus anúncios ou o conteúdo da barra lateral irão ficar abaixo do conteúdo principal para smartphones ou tablets com a tela muito pequena.

Veja exemplos nas imagens abaixo:

320px de largura:

Layout Responsivo

980px de largura:

Layout Responsivo

Demo

Não faz sentido você seguir um tutorial sem saber exatamente o que você vai fazer, por isso, temos um exemplo do layout que vamos criar neste tutorial, segue o link abaixo:

Vou explicar como criar este modelo.

Compatibilidade

O Layout responsivo que vamos criar é completamente compatível com todos os navegadores, com exceção do IE6, já que vamos utilizar uma propriedade CSS não suportada por ele – max-width.

Compatibilidade com o IE7 ou superior e todos os outros navegadores (Chrome, Opera, Firefox, Safari, etc…).

Criando o layout responsivo

Já falamos demais, então se você ainda estiver lendo, vamos começar a criar nosso layout pelo HTML.

Vou fazendo e explicando tudo.

O HTML

Vamos criar 3 DIVs para nosso layout, uma que vai ser o "container" e outras duas que serão a coluna da esquerda e direita respectivamente.

Dentro de ambas as colunas teremos uma outra DIV apenas para criar um espaçamento entre o conteúdo e a borda da mesma (padding).

<div class="site-cols-wrapper">
	<div class="site-left-col">
		<div class="site-left-col-inner">
			Esquerda
		</div>
	</div>
	<div class="site-right-col">
		<div class="site-right-col-inner">
			Direita
		</div>
	</div>
</div>
Classe Função
Detalhamento das DIVs
site-cols-wrapper Envolver todas as DIVs e para criar a largura máxima do site.
site-left-col Coluna da esquerda.
site-left-col-inner Espaçamento interno da coluna da esquerda.
site-right-col Coluna da direita.
site-right-col-inner Espaçamento interno da coluna da direita.

Agora vamos adicionar um pouco de estilo às nossas DIVs.

O CSS

Nossa DIV principal (site-cols-wrapper) terá no máximo 1200px de largura (max-width). Nossa DIV da direita (site-right-col), que será a barra lateral, terá 360px de largura fixa (width). Nossa DIV da esquerda, que terá o conteúdo (site-left-col), ficará livre, ou seja, a largura vai variar dependendo da largura da tela do navegador. Por fim, nossas DIVs que estão dentro de cada uma das colunas (site-left-col-inner e site-right-col-inner), terão apenas um espaçamento (padding).

.site-cols-wrapper{
    max-width:1200px;
    margin:0 auto;
    font-family: sans-serif;
    font-size:18px;
    color:#555;
}
/* Coluna da esquerda */
.site-left-col{
    width:100%;
    margin-right:-360px;
    float:left;
}
.site-left-col-inner{
    padding:20px;
    margin-right:360px;
}
/* Coluna da direita */
.site-right-col{
    width:360px;
    float:right;
}
.site-right-col-inner{
    padding:20px;
}

Os truques:

  • A DIV .site-left-col tem largura de 100%, no entanto, tem margin-right:-360px;, o valor negativo irá atrair o próximo elemento para próximo dela se este for menor que 360px;
  • Para que as DIVs não fiquem uma sobre a outra, a DIV interna .site-left-col-inner corrige o problema com margin-right:360px;

Pronto, o CSS e HTML estão feitos. Neste ponto você já deve ver suas duas colunas funcionando, no entanto, quando você diminuir muito a tela do seu navegador, a coluna lateral irá sobrepor a coluna do conteúdo. Por este motivo, iremos fazê-la seguir o fluxo quando a tela estiver menor que 800px.

Vou explicar como fazer isso com jQuery, no entanto, vamos precisar de mais classes CSS para quando a tela for pequena demais, veja abaixo:

.site-left-col-resized{
	width:100%;
	margin-right:0;
	float:none;
}
.site-left-col-inner-resized{
	padding:20px;
	margin-right:0;
}
.site-right-col-resized{
	width:100%;
	float:none;
}

Isso deverá ser colocado no final do seu CSS. Vamos incluir essas classes nas DIVs quando a tela for pequena demais e removê-las quando estiver em um tamanho razoável (leia-se: 800px ou mais).

O jQuery

Vamos utilizar a função .resize() no elemento window para saber o tamanho da janela e fazer a barra lateral sumir.

function resizeSidebar() {
	var window_width = $(window).width();
	
	if ( window_width < 800 ) {
		$('.site-right-col').addClass('site-right-col-resized');
		$('.site-left-col').addClass('site-left-col-resized');
		$('.site-left-col-inner').addClass('site-left-col-inner-resized');
	} else {
		$('.site-right-col').removeClass('site-right-col-resized');
		$('.site-left-col').removeClass('site-left-col-resized');
		$('.site-left-col-inner').removeClass('site-left-col-inner-resized');
	}
}

jQuery(function(){
	resizeSidebar();
	
	$(window).resize(function(){
		resizeSidebar();
	});
});

Simplesmente isso, apenas faz com que a barra lateral siga o fluxo quando a tela for menor que 800px.

Todo o código junto

Se quiser copiar e colar, o código abaixo já vem com tudo embutido:

<!DOCTYPE html>
<html>
<head>
<title>Layout responsivo com coluna fixa (CSS, HTML e jQuery) | Demo</title>
<style>
body, 
html{
	margin:0;
	padding:0;
	height:100%;
}
* img{
	max-width:100% !important;
	height:auto !important;
}
.site-cols-wrapper{
	max-width:1200px;
	margin:0 auto;

	font-family: sans-serif;
	font-size:18px;
	color:#555;
}
/* Coluna da esquerda */
.site-left-col{
	width:100%;
	margin-right:-360px;
	float:left;
}
.site-left-col-resized{
	width:100%;
	margin-right:0;
	float:none;
}
.site-left-col-inner{
	padding:20px;
	margin-right:360px;
}
.site-left-col-inner-resized{
	padding:20px;
	margin-right:0;
}
/* Coluna da direita */
.site-right-col{
	width:360px;
	float:right;
}
.site-right-col-resized{
	width:100%;
	float:none;
}
.site-right-col-inner{
	padding:20px;
}
/* "Menu" */
.menu{
	padding:20px 0;
	text-align:center;
	width:100%;
	displau:block;
	clear:both;
	font-size:20px;
	color:#fff;
	background:#000;
}
.menu a{
	color:#fff;
	text-decoration:none;
	font-weight:700;
}
</style>

<script src="http://code.jquery.com/jquery-latest.min.js"></script>
<script>
function resizeSidebar() {
	var window_width = $(window).width();
	
	if ( window_width < 800 ) {
		$('.site-right-col').addClass('site-right-col-resized');
		$('.site-left-col').addClass('site-left-col-resized');
		$('.site-left-col-inner').addClass('site-left-col-inner-resized');
	} else {
		$('.site-right-col').removeClass('site-right-col-resized');
		$('.site-left-col').removeClass('site-left-col-resized');
		$('.site-left-col-inner').removeClass('site-left-col-inner-resized');
	}
}

jQuery(function(){
	resizeSidebar();
	
	$(window).resize(function(){
		resizeSidebar();
	});
});
</script>

</head>

<body>
<div class="menu">
<a href="http://www.todoespacoonline.com/w/?p=129"> * voltar para o tutorial *</a> 
</div>
<div class="site-cols-wrapper">
	<div class="site-left-col">
		<div class="site-left-col-inner">
			Esquerda
		</div>
	</div>
	<div class="site-right-col">
		<div class="site-right-col-inner">
			Direita
		</div>
	</div>
</div>
<div class="menu">
<a href="http://www.todoespacoonline.com/w/?p=129"> * voltar para o tutorial *</a> 
</div>

</body>
</html>

Só colar em um arquivo HTML e estudar suas possibilidades.

Se for adicionar um menu e rodapé, faça isso fora da DIV principal que criamos neste tutorial, assim elas serão mantidas na mesma estrutura sempre.

Concluindo

Este layout irá funcionar em todos os navegadores, incluindo os que estão presentes em smartphones e tablets. Por fim, funciona no famoso IE (Internet Explorer 7 e posterior).

Caso tenha algum erro no código, queira aprimorar, ou tirar sua dúvida, comente, vamos partilhar nosso conhecimento com todos.