Como Fazer uma Imagem de Fundo Preencher a Tela Inteira
Recentemente em um projeto, houve a necessidade de fazer com que o plano de fundo do site (uma foto ou série de fotos, nesse caso) ocupasse toda a tela, não importando a resolução.
Faça o download dos arquivos de exemplo clicando aqui.
Sempre fui fã to site da agência August, um dos sites pioneiros a utilizarem fotos grandes como fundo. Porém, neste site foi utilizado Flash para o efeito de preenchimento de tela (originalmente; agora percebi que já trocaram para HTML/CSS). Hoje, com o avanço das bibliotecas javascript, procurei encontrar uma forma de fazer isso apenas com jQuery e um pouco de CSS (é claro que isso também pode ser feito com javascript “puro”). Neste tutorial mostrarei a solução que desenvolvi (veja o site do cliente).
HTML e CSS Básico
Antes de mais nada, temos que pensar como esta técnica funciona (mesmo que de forma mais simples) sem javascript. Não há uma forma confiável de fazer o efeito desejado apenas com HTML e CSS2, mas conseguimos uma funcionalidade básica. Não há muita flexibilidade com a utilização da propriedade CSS background, a não ser que seja utilizado CSS3 (cada vez mais uma alternativa viável, ver o Postscript), portanto iremos utilizar uma tag <img> e manipular seus atributos com CSS e Javascript.
Primeiramente, vamos analisar o HTML deste exemplo:
<!doctype html> <html lang="pt-br"> <head> <meta charset="UTF-8" /> <title>Imagem de Fundo Preenchendo Toda a Tela</title> <style> /* Estilos (em um site real colocar em arquivo externo) */ </style> <script src="https://ajax.googleapis.com/ajax/libs/jquery/1.6.1/jquery.min.js"></script> <script> //Javascript (em um site real colocar em arquivo externo) </script> </head> <body> <div id="fundo"> <img src="http://flickholdr.com/1600/1200/sunset" alt="" /> </div> <div id="site"> <h1>Site Exemplo</h1> <p> Lorem ipsum... </p> </div> </body> </html>
Estou colocando os estilos e o javascript dentro do documento, mas é recomendável em um projeto real utilizar arquivos externos. Quanto ao HTML, nada muito diferente do normal, apenas a questão de haver duas divs, uma chamada #fundo-externo, para criar um contexto de posicionamento e outra chamada #fundo que será o nosso container para as imagens que irão preencher a tela. A razão de utilizar uma div é que podemos colocar várias imagens dentro dela e até criar um slideshow (como foi o caso no projeto do meu cliente).
A ideia de ter uma div com a imagem antes do site é poder posicionar o fundo e o site de forma absoluta, para que possamos sobrepor os dois. Vejamos o CSS:
/* reset de margens */
* {
margin: 0;
padding:0;
}
/* para garantir que estes elementos ocuparão toda a tela */
body, html {
width: 100%;
height: 100%;
font-family: Arial, Tahoma, sans-serif;
}
#fundo-externo {
overflow: hidden; /* para que não tenha rolagem se a imagem de fundo for maior que a tela */
width: 100%;
height: 100%;
position: relative; /* criamos um contexto para posicionamento */
}
#fundo {
position: fixed; /* posição fixa para que a possível rolagem da tela não revele espaços em branco */
width: 100%;
height: 100%;
}
#fundo img {
width: 100%; /* com isso imagem ocupará toda a largura da tela. Se colocarmos height: 100% também, a imagem irá distorcer */
position: absolute;
}
#site {
position: absolute;
top: 40px;
left: 50%;
width: 560px;
padding: 20px;
margin-left: -300px; /* por causa do posicionamento absoluto temos que usar margem negativa para centralizar o site */
background: #FFF; /* fundo branco para navegadores que não suportam rgba */
background: rgba(255,255,255,0.8); /* fundo branco com um pouco de transparência */
}
p {
margin-bottom: 1.5em;
}
Com isso, você verá que a imagem de fundo ocupará toda a largura da tela. Uma das desvantagens desta técnica já fica aparente logo de cara: por causa do posicionamento absoluto do site, temos algumas limitações quanto ao posicionamento da div#site. Neste caso, utilizei margens negativas para centralizar o container no layout. Porém, se a tela for muito estreita, haverá corte do conteúdo do site. Também podemos trabalhar com o site alinhado à esquerda ou à direita.
Você também perceberá que, apesar da imagem de fundo ocupar toda a tela, dependendo da forma como a janela do navegador é redimensionada, fica um espaço branco na parte de baixo do site. Isso acontece porque o redimensionamento automático está apenas acontecendo de acordo com a largura da janela. Quanto menor a largura da janela, menor a largura da imagem. Dependendo das proporções da janela ou tela, a imagem ficará menor do o espaço a ser ocupado, o que não é o que queremos aqui. Queremos que a imagem ocupe toda a tela, não importando o seu tamanho ou proporção.
Para isso, iremos utilizar um pouco de javascript:
// Função adaptImage()
// Parâmetros: targetimg (objeto jquery com elementos selecionados)
function adaptImage(targetimg) {
var wheight = $(window).height(); // altura da janela do navegador
var wwidth = $(window).width(); // largura da janela do navegador
// removemos os atributos de largura e altura da imagem
targetimg.removeAttr("width")
.removeAttr("height")
.css({ width: "", height: "" }); // removemos possíveis regras css também
var imgwidth = targetimg.width(); // largura da imagem
var imgheight = targetimg.height(); // altura da imagem
var destwidth = wwidth; // largura que a imagem deve ter
var destheight = wheight; // altura que a imagem deve ter
// aqui vamos determinar o tamanho final da imagem
if(imgheight < wheight) {
// se a altura da imagem for menor que a altura da tela, fazemos um cálculo
// para redefinir a largura da imagem para bater com a altura que queremos
destwidth = (imgwidth * wheight)/imgheight;
$('#fundo img').height(destheight);
$('#fundo img').width(destwidth);
}
// aqui utilizamos um cálculo simples para determinar o posicionamento da imagem
// para que a mesma fique no meio da tela
// posição = dimensão da imagem/2 - dimensão da tela/2
destheight = $('#fundo img').height();
var posy = (destheight/2 - wheight/2);
var posx = (destwidth/2 - wwidth/2);
//se o cálculo das posições der resultado positivo, trocamos para negativo
if(posy > 0) {
posy *= -1;
}
if(posx > 0) {
posx *= -1;
}
// colocamos através da função css() do jquery o posicionamento da imagem
$('#fundo').css({'top': posy + 'px', 'left': posx + 'px'});
}
//quando a janela for redimensionada, adaptamos a imagem
$(window).resize(function() {
adaptImage($('#fundo img'));
});
//quando a página carregar, fazemos o mesmo
$(window).load(function() {
$(window).resize();
});
No código acima utilizei um pouco de jQuery (apenas para os seletores e eventos), mas não é algo necessário. Isso pode ser feito com javascript puro sem problemas. Também não sou especialista em javascript, então acredito que podem haver melhorias na função (sugestões serão bem-vindas!), mas esta foi a solução que funcionou para mim.
Com esta técnica deixamos o CSS cuidar do redimensionamento da largura da imagem. Caso a largura fique muito pequena e a altura da imagem acabe ficando menor do que a altura da janela do navegador, a script atua para redimensionar a imagem de acordo com sua altura. Assim a imagem sempre ocupa toda a tela do navegador, não importando o tamanho ou proporção da mesma.
Esta técnica foi útil para você? Opine nos comentários!
Postscript: Uma Técnica com CSS3
Para conseguir um efeito semelhante com CSS3, sem utilizar javascript e utilizando menos HTML, podemos nos utilizar da nova propriedade background-size. Veja o exemplo CSS3 aqui. O código CSS é bem simples:
body {
background: url(http://flickholdr.com/1600/1200/sunset);
-webkit-background-size: cover;
-moz-background-size: cover;
-o-background-size: cover;
background-size: cover;
}
Redimensione a janela do seu navegador para ver o efeito em ação. Neste caso, podemos apagar as divs #fundo-externo e #fundo, pois não são mais necessárias.
Para mais informações sobre background-size e outras novas propriedades CSS3, visite este artigo do Sitepoint.

45 Comentários
Caramba Parabéns, achei seu site pesquisando na web e tive que comentar, PQP que artigo animal velho vc está de parabéns vou acompanhar seu site, já adicionei nos favoritos rsrs!!! Posso manter contato e dar dicas para posts?
Valeu e parabéns novamente
Valeu Thiago! Infelizmente tenho pouco tempo para atualizar o blog atualmente, mas estarei atualizando-o pouco a pouco. Obrigado pelo apoio e se tiver alguma dica envie um e-mail.
muito útil, obrigado.
Cara vc tá de parabens, tou começando agora na area de web e tava precisando justamente fazer esse esquema no site do criente, valeu pelo post, muito bom mesmo…
cara, fantástico
manja muito
parabéns
Obrigado! Estou preparando mais alguns posts com técnicas úteis.
Cara parabens me deu um help aqui do tamanho de um trem valeu mesmo.
Olá amigo tem como fazer isso com um backgroud-color, por exemplo no css defino pra ele ter 100% da tela, mais quando fecho o navegador ao ponto de surgi uma barra de rolagem horizontal, o mesmo rodapé não preenche de cor o 100%.
Olá Hugo,
Teria que ver o caso com calma, mas se você utilizar a background-color no tag body, você não terá esse problema.
olá eu utilizei exatamente como esta ai, porem quando altero o tamanho de width: alinha tudo para a direita. estou usando width:900px;
Se puder me ajudar eu agradeço e agradeceria mais ainda se pudesse me enviar um E-mail.
Obrigado.
Olá Gunner,
Esta técnica foi desenvolvida para ser utilizada na área da tela inteira. Caso você queira trabalhar com uma largura fixa, talvez nem precise de tudo isso. Depende de cada caso, pode até ser mais fácil de fazer.
Qualquer coisa me mande um e-mail que eu posso dar uma olhada. Apenas peço desculpas se eu demorar para responder pois estou com bastante projetos no momento.
cara nao entendi to fazendu um blog dai eu peguei uma imagem mais eu boto ela e sempre fica pequena
ajuda
Olá pepe,
Você precisaria especificar melhor o que está tentando fazer, não entendi.
Cara, que dica excelente!! E parabéns pelo seu trabalho, muito bom gosto!
Com certeza estarei visitando mais vezes aqui, obrigado!
Obrigado! Que bom que foi útil. O blog está meio parado agora mas até o final do ano sai o redesign do site, fique ligado!
Cara, Parabéns pelo script foi muito util, continue assim vlw!!!
Valeu Felipe! Em 2012 terei novos artigos!
Olá Guilherme,
Ficou muito legal! Parabéns!
Você encontrou algum problema com o IE 8 no comando abaixo?
$(window).resize(function() {
adaptImage($(‘#fundo img’));
});
Abraços,
Isaias
Obrigado pelo comentário!
Então, não lembro de ter problemas com o IE8, mas vou verificar. O que exatamente aconteceu?
Olá, Guilherme
Qual foi recurso q vc usou para fazer o slideshow do bg?
Teria mostrar a aplicação dele no código?
Estou com um projeto q precisa ter algo parecido.
Muito grato,
Ed
Olá Ed,
Para fazer um slideshow, basta adaptar um pouco a técnica. No site da Berlim Ambientes (veja no meu portfolio) utilizei várias imagens dentro da mesma div e o plugin cycle para jquery. Pode ver o código do site do cliente para ter uma ideia.
Muuuuuuuuuuuuuuuuito Obrigado amigo .!
estava com essa duvida, pra fazer um serviço pra um cliente.
Mt obg msm salvou minha vida
SUCESSO !
Olá Guilherme,
Adorei o artigo, mas estou tendo problemas no IE 9. No final do site ele está aparecendo uma barra branca, como se o fundo da imagem terminasse ali e ele complementasse sem a imagem, fica sem fundo.
A imagem não está sendo aplicada no browser todo, vc sabe o porque disso, estou tentando catar aqui no código, mas não consigo achar nada.
Fico no aguardo.
Obrigada.
Olá Amanda,
Que bom que gostou do artigo.
Problemas como esse precisam de bastante análise, pois inconsistências de HTML ou CSS são parte do nosso trabalho. Eu teria que ver um exemplo para tentar diagnosticar o que está acontecendo. Tente fazer modificações no código (salve uma cópia antes) pois esta é a única maneira para se chegar a uma solução.
Cara, independente de ter mais alternativas que funcione ou não, você esta de parabéns, realmente funciona, mas o que eu gostaria muito de comentar, é que muita gente acha que sabe tudo e fica escondendo o peixe (informação), mas você é dos meus, informação gratuita para todos, muito bom mesmo!
Obrigado Cleber,
O que eu puder colocar de informação útil aqui certamente o farei. Fique atento também para o curso básico de HTML e CSS que estarei lançando em breve!
Quer uma forma muuuiito mais facil?
aqui vai:
mude essa linha:
#fundoFoto img {min-width: 100%;min-height: 100%;position: absolute;}
e remova todo javascript que voce fez pois com isso o navegador ja faz tudo sozinho e nem precisa de css3 !
testado no IE 7,8,9 FF e Chrome, só não testei no IE6
só corrigindo não é #fundoFoto é só #fundo
#fundo img {min-width: 100%;min-height: 100%;position: absolute;}
Obrigado pela dica Azziz! Não tinha pensado nisso.
O funcionamento deste código pode ser satisfatório para alguns casos, mas não é igual à técnica que estou passando. Com a técnica javascript (ou CSS3), perceba que o redimensionamento da imagem funciona de forma diferente. Mesmo assim, obirgado pelo ponto de vista alternativo.
Opa, obrigado pelo belo post.
Estava procurando algo assim pra um site meu mesmo que quero implantar aqui.
Nao manjo nada de html nem javascript nem css, mas comecei estudar tudo isso e espero logo estar sabendo algo sobre.
Uma duvida no dreamwaver quando clico em ver a compatibilidade do browser ele diz que nao é compativel com alguns browsers, posso ter problemas com isso ?
Sendo que só testei no I.E 8, Chrome, e Firefox 9.
Abraços e obrigado novamente.
Que bom que o post foi útil para você.
Quanto a compatibilidade, não sei sobre a confiabilidade do Dreamweaver em relação a isso. Portanto é mais importante testar nos próprios navegadores e, se possível, em outros computadores também e com outros usuários.
Não estou conseguindo deixar a div em 100% da tela alguem pode me ajudar
HTML
conteudo
CSS
html, body, #wrap {height: 100%;}
body > #wrap {height: auto; min-height: 100%; background:#966;}
#main {padding-bottom: 40px; background:#F00;} /* deve ser a mesma altura do rodapé */
#footer {
width:100%;
background:#333;
position: relative;
margin-top: -40px; /* A mesma altura do rodapé, o valor deve ser negativo */
height: 40px;
clear:both
}
Guilherme, descuido meu, se eu tivesse lido o codigo teria visto que nele proprio diz:
background: #FFF; /* fundo branco para navegadores que não suportam rgba */
Testei em mais aguns navegadores e tudo tranquilho.
Obrigado novamente.
Parabéns pela iniciativa Guilherme. Todos pela democratização do conhecimento. Perfeito.
Me tira só uma dúvida. Qual o tamanho padrão das imagens que você usou, pois acho que se a imagem for muito pequena irá distorcer quando visualizada em um monitor com resolução muito alta. E vice-versa.
Ou estou errado?
Mais uma vez. Parabéns.
Obrigado Bruno!
Neste exemplo não lembro que tamanho de imagem que utilizei, pois usei um serviço para servir a imagem.
Mas o que eu sugiro é utilizar um tamanho que ofereça suficiente qualidade, pois os navegadores hoje lidam bem com a redução e espansão de imagens.
Sim, se for muito pequena, vai distorcer em telas maiores. Se a imagem for muito grande, não acho que vai distorcer tanto em telas menores, mas estas pessoas terão que baixar uma imagem enorme para vê-la “pequena”. Ainda não existe solução definitiva para isso, mas existem serviços que servem a imagem de acordo com o tamanho da tela, para economizar largura de banda. Se você pesquisar encontra (não lembro agora o nome dos sites).
Olá Guilherme. Cara não estou conseguindo rotacionar as imagens. Acredito que esteja faltando algum plugin para a jQuery. Quando direciono para o endereço do plugin do site da Berlim que você fez por exemplo, dá certo. Onde encontro esse plugin para salvar na pasta local?
Fico no aguardo, até mais.
Se não me engano usei o jQuery Cycle:
http://jquery.malsup.com/cycle/
Qualquer coisa basta ver o código fonte do site da Berlim.
Blz. Guilherme consegui fazer aqui ficou lindo hehe. Percebi que a barra de rolagem não aparece mesmo redimencionando a janela do navegador, neste caso, tenho que fazer com que meu conteúdo sempre caiba na janela. Ou seja, não poderei utilizar textos grandes que necessitem de rolagem.
É mais ou menos isso?
Fazer um site que sempre fique inteiro na tela apresenta vários desafios. Você pode navegar no site da Berlim para ver como que eu resolvi o problema de texto. O site acessa bem até em telas bem menores, apenas para celulares que teria que fazer alguns ajustes. Você consegue trabalhar com uma quantidade de conteúdo maior desde que saiba como resolver os problemas das resoluções menores e maiores (os extremos).
Boa tarde guilherme, eu nao tenho conhecimento em css, mas estou tentando. Meu problema e o seguinte:
Nao estou conseguindo fixar um arquivo flash para que ele fique no meio da tela na raiz site da div, a resolucao do mesmo e de 1000 x 600, mas quando adiciono o mesmo fica para o lado direito da tela. Sera que pode me ajudar passando o codigo do mesmo.
Obrigado e parabens pelo tutorial.
Olá Diego,
Teria que realmente ver o código do site que você está fazendo e também como você está inserindo o arquivo flash na página. De qualquer forma, há vários tutoriais na internet (nenhum aqui no blog por enquanto) que explicam como se centraliza um elemento no documento. Eu, pessoalmente, uso position: absolute; quando isso realmente é necessário, mas esta técnica também tem seus problemas.
Mas continue estudando CSS, pois é uma linguagem muito interessante e essencial para construir websites!
Olá Diego.
Tente fazer da seguinte forma:
– No html
ARQUIVO EM FLASH
– Na CSS
.flash{
width: 1000px /* Neste caso coloquei o tamanho do seu flash*/
margin: 0 auto;
}
Acho que desta forma pode funcionar, qualquer coisa posta aqui de novo!
Abraços.
Muito boa a dica, parabéns! Era o que estava precisando para finalizar um projeto! Muito obrigado.
Postei um código em HTML para auxiliar o Diego na dúvida dele mas não apareceu no post…
era
div class=flash
ARQUIVO EM FLASH
/div
Coloquei sem os para ver se passa no blog.
Abs e desculpa o flood.
Olá Marcus,
Tudo bem. O blog ainda está na configuração inicial e ainda não tive muito tempo para ver isso. Acho que as tags realmente não sairão no comentário. Mas acho que dá para ter uma ideia (por enquanto usemos a imaginação).