Imagem de fundo com largura de 100% e altura 'automática'

90

Atualmente estou trabalhando em uma página de destino móvel para uma empresa. É um layout bem básico, mas abaixo do cabeçalho há uma imagem de um produto que sempre terá 100% de largura (o design mostra sempre indo de ponta a ponta). Dependendo da largura da tela, a altura da imagem obviamente se ajustará de acordo. Eu fiz isso originalmente com um img (com largura de CSS de 100%) e funcionou muito bem, mas percebi que gostaria de usar consultas de mídia para servir imagens diferentes com base em resoluções diferentes - digamos um pequeno, médio e uma versão grande da mesma imagem, por exemplo. Eu sei que você não pode alterar o src img com CSS, então percebi que deveria usar um fundo CSS para a imagem, em vez de uma tag img no HTML.

Não consigo fazer isso funcionar corretamente, pois o div com a imagem de fundo precisa de largura e altura para mostrar o fundo. Obviamente, posso usar 'largura: 100%', mas o que devo usar para a altura? Posso colocar uma altura fixa aleatória como 150px e então posso ver os primeiros 150px da imagem, mas essa não é a solução, pois não há uma altura fixa. Eu joguei e descobri que uma vez que há uma altura (testado com 150px) eu posso usar 'background-size: 100%' para ajustar a imagem no div corretamente. Posso usar o CSS3 mais recente para este projeto, pois ele é voltado exclusivamente para dispositivos móveis.

Eu adicionei um exemplo aproximado abaixo. Desculpe os estilos embutidos, mas eu queria dar um exemplo básico para tentar tornar minha pergunta um pouco mais clara.

<div id="image-container">
    <div id="image" style="background: url(image.jpg) no-repeat; width: 100%; height: 150px; background-size: 100%;"></div>
</div>

Talvez eu precise dar ao div do contêiner uma altura percentual com base na página inteira ou estou olhando para isso completamente errado?

Além disso, você acha que os fundos CSS são a melhor maneira de fazer isso? Talvez haja uma técnica que veicula diferentes tags img com base na largura do dispositivo / tela. A ideia geral é que o modelo da página de destino seja usado várias vezes com imagens de produtos diferentes, então preciso ter certeza de que o desenvolvo da melhor maneira possível.

Peço desculpas se isso é um pouco prolixo, mas estou indo e voltando deste projeto para o próximo, então gostaria de terminar este pequeno detalhe. Agradecemos antecipadamente pelo seu tempo, é muito apreciado. Saudações

Darryl Young
fonte
Um navegador pode optar por não baixar um recurso de imagem se ele tiver display: none, então você sempre pode mostrar imagens diferentes com consultas de mídia sem JS
Ben Taliadoros

Respostas:

18

Em vez de usar, background-imagevocê pode usar imgdiretamente e para fazer com que a imagem se espalhe por toda a largura da janela de visualização, tente usar max-width:100%;e lembre-se de não aplicar qualquer preenchimento ou margem ao div do contêiner principal, pois isso aumentará a largura total do contêiner. Usando esta regra, você pode ter uma largura de imagem igual à largura do navegador e a altura também mudará de acordo com a proporção da imagem. Obrigado.

Editar: Alterar a imagem em diferentes tamanhos de janela

$(window).resize(function(){
  var windowWidth = $(window).width();
  var imgSrc = $('#image');
  if(windowWidth <= 400){			
    imgSrc.attr('src','http://cdn.sstatic.net/Sites/stackoverflow/company/img/logos/so/so-icon.png?v=c78bd457575a');
  }
  else if(windowWidth > 400){
    imgSrc.attr('src','http://i.stack.imgur.com/oURrw.png');
  }
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div id="image-container">
  <img id="image" src="http://cdn.sstatic.net/Sites/stackoverflow/company/img/logos/so/so-icon.png?v=c78bd457575a" alt=""/>
</div>

Desta forma, você altera sua imagem em diferentes tamanhos do navegador.

maksbd19
fonte
Obrigado por dedicar seu tempo para fazer isso por mim, é muito apreciado. Eu apenas dei uma olhada rápida e parece estar funcionando.
Darryl Young de
2
Essa resposta antiga parecia atraente ... mas não é verdade que o navegador móvel ainda fará o download (apenas não exibirá) a imagem inicialmente definida no HTML como src? Se for assim, não é um bom começo, já que o objetivo é conservar os recursos do dispositivo móvel.
Tim Gallant
1
Eu acredito que Tim Gallant está certo sobre este - neste caso, o navegador irá carregar as duas imagens como um recurso e então apenas exibir a de resolução mais baixa. Portanto, embora pareça atraente, no celular é realmente mais lento do que carregar apenas o de alta resolução e com esse sacrifício você verá apenas a imagem de resolução mais baixa ... o pior dos dois mundos.
homenzinho de
1
Resposta ruim. Votos negados. Código simplesmente inchado e antigo.
TheBlackBenzKid
Insira consultas de mídia que adicionam exibição: nenhuma às imagens que você não deseja mostrar - a maioria dos navegadores não as baixa
Ben Taliadoros
215

Tim S. estava muito mais perto de uma resposta "correta" do que a atualmente aceita. Se você quiser ter uma imagem de fundo com 100% de largura e altura variável feita com CSS, em vez de usar cover(o que permitirá que a imagem se estenda para fora dos lados) ou contain(que não permite que a imagem se estenda), apenas defina o CSS assim:

body {
    background-image: url(img.jpg);
    background-position: center top;
    background-size: 100% auto;
}

Isso definirá sua imagem de plano de fundo para 100% de largura e permitirá que a altura transborde. Agora você pode usar consultas de mídia para trocar essa imagem em vez de depender de JavaScript.

EDIT: Acabei de perceber (3 meses depois) que você provavelmente não quer que a imagem transborde; você parece querer que o elemento contêiner seja redimensionado com base em sua imagem de fundo (para preservar sua proporção), o que não é possível com CSS, até onde eu sei.

Esperançosamente, em breve você poderá usar o novo atributo srcset no imgelemento. Se você quiser usar os imgelementos agora, a resposta atualmente aceita é provavelmente a melhor.

No entanto, você pode criar um elemento de imagem de plano de fundo responsivo com uma proporção de aspecto constante usando puramente CSS. Para fazer isso, você define o heightcomo 0 e define o padding-bottomcomo uma porcentagem da largura do próprio elemento, assim:

.foo {
    height: 0;
    padding: 0; /* remove any pre-existing padding, just in case */
    padding-bottom: 75%; /* for a 4:3 aspect ratio */
    background-image: url(foo.png);
    background-position: center center;
    background-size: 100%;
    background-repeat: no-repeat;
}

Para usar diferentes proporções, divida a altura da imagem original por sua própria largura e multiplique por 100 para obter o valor percentual. Isso funciona porque a porcentagem de preenchimento é sempre calculada com base na largura, mesmo que seja um preenchimento vertical.

cr0ybot
fonte
4
perfeita, a pesquisa rápida no google me trouxe aqui, problema resolvido!
J King de
6
Respostas como essa devem ser as aceitas, elas respondem à pergunta. Claro, dê a "melhor solução", mas também responda à pergunta, então, quando as pessoas a encontrarem, obterão a resposta que desejam!
tim.baker
Isso não funciona para mim, estou usando o Google Chrome 47.0. Pode ser porque a resposta está desatualizada?
MeV
Você poderia ser mais específico sobre qual parte não está funcionando? Dei várias respostas possíveis, portanto, se uma parte não estiver funcionando, posso elaborar mais para dar uma resposta melhor e mais atualizada.
cr0ybot
por algum motivo pouco claro, a configuração background-size: autoresolveu meu problema em todas as orientações de dispositivos.
n__o
17

Tente isto

html { 
  background: url(image.jpg) no-repeat center center fixed; 
  -webkit-background-size: cover;
     -moz-background-size: cover;
       -o-background-size: cover;
          background-size: cover;
}

Versão simplificada

html {
  background: url(image.jpg) center center / cover no-repeat fixed;
}
Mo.
fonte
16

Você pode usar a propriedade CSS background-sizee defini-la como coverou contain, dependendo de sua preferência. Cover irá cobrir a janela inteiramente, enquanto contain fará com que um lado se ajuste à janela, portanto, não cobrindo a página inteira (a menos que a proporção da tela seja igual à da imagem).

Observe que esta é uma propriedade CSS3. Em navegadores mais antigos, essa propriedade é ignorada. Alternativamente, você pode usar javascript para alterar as configurações CSS dependendo do tamanho da janela, mas isso não é preferido.

body {
    background-image: url(image.jpg); /* image */
    background-position: center;      /* center the image */
    background-size: cover;           /* cover the entire window */
}
Tim S.
fonte
4

Basta usar uma imagem de fundo de duas cores:

<div style="width:100%; background:url('images/bkgmid.png');
       background-size: cover;">
content
</div>
Alexey Kaverin
fonte
2

Estamos em 2017 e agora você pode usar o ajuste de objeto, que tem um suporte decente . Ele funciona da mesma maneira que um div, background-sizemas no próprio elemento e em qualquer elemento, incluindo imagens.

.your-img {
  max-width: 100%;
  max-height: 100%;
  object-fit: contain;
}
usuario
fonte
1
html{
    height:100%;
    }
.bg-img {
    background: url(image.jpg) no-repeat center top; 
    background-size: cover; 
    height:100vh;     
}
Mostafa Norzade
fonte