Como redimensionar uma imagem para caber na janela do navegador?

114

Isso parece trivial, mas depois de toda a pesquisa e codificação, não consigo fazer funcionar. As condições são:

  1. O tamanho da janela do navegador é desconhecido. Portanto, não proponha uma solução envolvendo tamanhos absolutos de pixels.
  2. As dimensões originais da imagem são desconhecidas e podem ou não caber na janela do navegador.
  3. A imagem é centralizada verticalmente e horizontalmente.
  4. As proporções da imagem devem ser conservadas.
  5. A imagem deve ser exibida em sua totalidade na janela (sem cortes).
  6. Não desejo que as barras de rolagem apareçam (e não deveriam aparecer se a imagem couber).
  7. A imagem é redimensionada automaticamente quando as dimensões da janela mudam, para ocupar todo o espaço disponível sem ser maior que seu tamanho original.

Basicamente, o que eu quero é:

.fit {
  max-width: 99%;
  max-height: 99%;
}
<img class="fit" src="pic.png">

O problema com o código acima é que ele não funciona: a imagem ocupa todo o espaço vertical de que precisa, adicionando uma barra de rolagem vertical.

À minha disposição está PHP, Javascript, JQuery, mas mataria por uma solução somente CSS. Eu não me importo se não funcionar no IE.

sebnukem
fonte
perraultarchitecte.com/en/projects/… Este é o efeito que você deseja, certo? eu também!
1
Sim, ele é. A solução que postei acima funciona. Você pode ver o resultado em eseb.net/potos.php?f=best_of/fort_collins_winter.jpg
sebnukem
Obrigado, isso realmente me ajuda. Alguma sugestão de que eu poderia fazer para colocar duas imagens lado a lado, mantendo a funcionalidade de redimensionamento? Obrigado.
8
Gosto do seu "não requisito": "Não me importa se não funcionar no IE." :)
Bastian de

Respostas:

122

Atualização 11/04/2018

Aqui está uma solução sem Javascript e apenas com CSS . A imagem será centralizada e redimensionada dinamicamente para caber na janela.

<html>
<head>
    <style>
        * {
            margin: 0;
            padding: 0;
        }
        .imgbox {
            display: grid;
            height: 100%;
        }
        .center-fit {
            max-width: 100%;
            max-height: 100vh;
            margin: auto;
        }
    </style>
</head>
<body>
<div class="imgbox">
    <img class="center-fit" src='pic.png'>
</div>
</body>
</html>

A solução [outra, antiga], usando JQuery, define a altura do contêiner da imagem ( bodyno exemplo abaixo) para que a max-heightpropriedade na imagem funcione conforme o esperado. A imagem também será redimensionada automaticamente quando a janela do cliente for redimensionada.

<!DOCTYPE html>
<html>
<head>
    <style>
        * {
            padding: 0;
            margin: 0;
        }
        .fit { /* set relative picture size */
            max-width: 100%;
            max-height: 100%;
        }
        .center {
            display: block;
            margin: auto;
        }
    </style>
</head>
<body>

<img class="center fit" src="pic.jpg" >

<script src="http://code.jquery.com/jquery-latest.js"></script>
<script type="text/javascript" language="JavaScript">
    function set_body_height() { // set body height = window height
        $('body').height($(window).height());
    }
    $(document).ready(function() {
        $(window).bind('resize', set_body_height);
        set_body_height();
    });
</script>

</body>
</html>

Nota: O usuário gutierrezalex empacotou uma solução muito semelhante a um plugin JQuery nesta página.

sebnukem
fonte
6
Não há necessidade de JS, há uma solução apenas para CSS .
Neolisk de
Também sem JS, use alternativamente o flexbox
Jason Sturges
51

Aqui está uma solução simples de CSS apenas ( JSFiddle ), funciona em qualquer lugar, móvel e IE incluído:

CSS 2.0:

html, body {
    height: 100%;
    margin: 0;
    padding: 0;
}

img {
    padding: 0;
    display: block;
    margin: 0 auto;
    max-height: 100%;
    max-width: 100%;
}

HTML:

<body>
  <img src="images/your-image.png" />
</body>
Neolisk
fonte
2
Agradável. Mas não está centrado verticalmente.
sebnukem de
1
@sebnukem: Era para ser? De alguma forma, eu perdi isso nos requisitos. É por isso que as pessoas usam screenshots / mockups. :) PS: Não acho que nenhuma das respostas fornecidas o torne centralizado verticalmente, mesmo com a ajuda de JS.
Neolisk de
3
Eu tentei muitas soluções por aí, até mesmo soluções de truques de CSS. O seu funciona perfeitamente como um encanto!
Stephan
2
Melhor solução de todas!
iVela
24

CSS3 introduz novas unidades que são medidas em relação à janela de visualização, que é a janela neste caso. São vhe vw, que medem a altura e a largura da janela de visualização, respectivamente. Aqui está uma solução simples de CSS apenas:

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

A única ressalva para isso é que só funciona se não houver outros elementos contribuindo com a altura da página.

Max
fonte
Obrigado, isso é ótimo. Existe algum motivo para 100vhque a imagem não se encaixe, mas 97vhfuncione bem?
Pavel
Talvez você tenha outras imagens que contribuem para a altura, como margem e preenchimento no corpo? vhliteralmente significa a altura da visualização, então se qualquer outro elemento adicionar altura à sua página, a página inteira será> 100vh. Isso faz sentido?
Máx.
Obrigado, resolvido agora. Se alguém tiver o mesmo problema (o .svgarquivo renderiza bem, mas renomeá-lo .htmlcausa imprecisão): o navegador adiciona automaticamente a <body>tag com o padrão, margin:8mesmo se o arquivo não tiver <body>tag. Então a solução é adicionar<style>body{margin:0}</style>
Pavel
15

Se você deseja colocar um elemento de contêiner em torno de sua imagem, uma solução CSS pura é simples. Veja, 99% de altura não tem significado quando o elemento pai se estende verticalmente para conter seus filhos. O pai precisa ter uma altura fixa, digamos ... a altura da janela de visualização.

HTML

<!-- use a tall image to illustrate the problem -->
<div class='fill-screen'>
    <img class='make-it-fit' 
         src='https://upload.wikimedia.org/wikipedia/commons/f/f2/Leaning_Tower_of_Pisa.jpg'>
</div>

CSS

div.fill-screen {
    position: fixed;
    left: 0;
    right: 0;
    top: 0;
    bottom: 0;
    text-align: center;
}

img.make-it-fit {
    max-width: 99%;
    max-height: 99%;
}

Brinque com o violino .

Mark E. Haase
fonte
Você pode fazer isso com um em <div>vez de um <img>?
StevoHN,
@sebnukem Eu não percebi esse requisito antes. Eu atualizei minha resposta.
Mark E. Haase de
Isso não maximiza a altura da minha imagem ampla.
Sridhar Sarnobat
4

Redimensione a imagem para caber na tela pelo lado mais longo, mantendo sua proporção da imagem

img[src$="#fit"] {
    width: 100vw;
    height: auto;
    max-width: none;
    max-height: 100vh;
    object-fit: contain;
}
  • width: 100vw - a largura da imagem será 100% da porta de visualização

  • height: auto - a altura da imagem será dimensionada proporcionalmente

  • max-height: 100vw - se a altura da imagem for maior do que a porta de visualização, ela será reduzida para caber na tela, conseqüentemente a largura da imagem será reduzida devido à seguinte propriedade

  • object-fit: contain - o conteúdo substituído é dimensionado para manter sua proporção enquanto se ajusta à caixa de conteúdo do elemento

    Nota: object-fité totalmente compatível apenas a partir do IE 16.0

am0wa
fonte
1
Como essa solução, no entanto, você deve mencionar que o ajuste de objeto não é compatível com o IE11, que ainda é amplamente usado, infelizmente.
Blackbam,
@DivijSehgal então você não precisa object-fitou pode usar explicitamente object-fit: fill;qual é o padrão .
am0wa
E se quisermos centralizar verticalmente?
Fmstrat
E se quisermos centralizar verticalmente? Basta adicionar: margin: auto;
gato
A solução funciona em conjunto com html e body style de outra resposta: html, body {width: 100%; altura: 100%; margem: 0; preenchimento: 0; }
Ivan Kovtun
3

Minha regra geral de CSS preguiçoso:

.background{
width:100%;
height:auto;
background: url('yoururl.jpg') no-repeat center;
background-position: 50% 50%;
background-size: 100% cover!important;
overflow:hidden;
}

Isso pode aumentar o zoom em sua imagem se ela for de baixa resolução para começar (isso tem a ver com a qualidade da imagem e o tamanho em dimensões. Para centralizar sua imagem, você também pode tentar (no CSS)

display:block;    
margin: auto 0; 

centrar sua imagem

em seu HTML:

<div class="background"></div>
usrrname
fonte
3

Eu sei que já existem algumas respostas aqui, mas aqui está o que usei:

max-width: 100%;
max-height: 100vh;
width: auto;
margin: auto;
TomC
fonte
Não tenho ideia do porquê, mas funciona como um encanto. Adoraria uma explicação!
SeedyROM
Nem eu, mas foi o que encontrei depois de muita procura.
TomC
2

Eu tinha um requisito semelhante e precisava fazer isso em CSS e JavaScript básicos. Nenhum JQuery disponível.

Isso é o que estou trabalhando.

<html>
      <head>
            <style>
                   img {
                          max-width: 95% !important;
                          max-height: 95% !important;
                       }
            </style>
            <script>
                   function FitImagesToScreen() {
                      var images = document.getElementsByTagName('img');
                      if(images.length > 0){
                         for(var i=0; i < images.length; i++){
                             if(images[i].width >= (window.innerWidth - 10)){
                                 images[i].style.width = 'auto';
                               }
                            }
                         }
                   }
             </script>
      </head>
      <body onload='FitImagesToScreen()'>
      ----    
      </body>
</html>

Observação: não usei 100% para a largura da imagem, pois sempre houve um pouco de preenchimento a ser considerado.

Rohit Vipin Mathews
fonte
2
Com CSS 3, obtemos as unidades "vh" e "vw" que são a porcentagem da altura da janela de visualização e a porcentagem da largura da janela de visualização, respectivamente. simplesmente img {largura máxima: 95vw; altura máxima: 95vh;} pode ser suficiente.
bobpaul
Se você puder somar como uma resposta, pode ser útil para qualquer um que vier a isso mais tarde.
Rohit Vipin Mathews
Você também pode empilhar várias imagens na área visível. Para duas imagens, coloque duas imgtags no bodyda página e defina max-heightcomo 49vh. Exibir mais de duas imagens na área visível é deixado como um exercício para o leitor.
Andrew Beals de
2

Simplifique. obrigado

.bg {
  background-image: url('https://images.unsplash.com/photo-1476820865390-c52aeebb9891?ixlib=rb-1.2.1&ixid=eyJhcHBfaWQiOjEyMDd9&w=1000&q=80');
  background-repeat: no-repeat;
  background-size: cover;
  background-position: center;
  height: 100vh;
  width: 100vw;
}
<div class="bg"></div>

Hassan Siddiqui
fonte
obrigado! apenas adicionando style = "height: 80vh;" na tag de imagem funcionou para mim.
Tobias J.
1
width: 100%;
overflow: hidden;

Eu acredito que deve resolver o problema.

RobinJ
fonte
Olá, obrigado pela sua resposta, mas não funciona e não pode funcionar logicamente quando a altura da imagem é maior do que a janela.
sebnukem
1
Bem ... O que é que pretende fazer? Você quer esticar? Ou as proporções originais devem ser mantidas intactas (presumo que seja isso que você deseja)?
RobinJ
1

Com base na resposta de @Rohit, isso corrige problemas sinalizados pelo Chrome, redimensiona as imagens de maneira confiável e também funciona para várias imagens empilhadas verticalmente, por exemplo, <img src="foo.jpg"><br><img src="bar.jpg"><br><img src="baz.jpg"> provavelmente há uma maneira mais elegante de fazer isso.

<style>
    img {
        max-width: 99vw !important;
        max-height: 99vh !important;
    }
</style>
<script>
    function FitImagesToScreen() {
        var images = document.getElementsByTagName('img');
        if(images.length > 0){
            document.styleSheets[1].rules[0].style["max-height"]=((100/images.length)-1)+"vh";
            for(var i=0; i < images.length; i++){
                if(images[i].width >= (window.innerWidth - 10)){
                    images[i].style.width = 'auto';
                }
            }
        }
    }
</script>
</HEAD>
<BODY onload='FitImagesToScreen()' onresize='FitImagesToScreen()'>
<img src="foo.png">
</BODY>

Andrew Beals
fonte
0

Use este código em sua tag de estilo

<style>
html {
  background: url(imagename) no-repeat center center fixed;
  background-size: cover;
  height: 100%;
  overflow: hidden;
}
</style>
vaibhav khunt
fonte