¿Cómo cambiar el tamaño de una imagen para que quepa en la ventana del navegador?

114

Esto parece trivial, pero después de toda la investigación y la codificación no puedo hacer que funcione. Las condiciones son:

  1. Se desconoce el tamaño de la ventana del navegador. Por lo tanto, no proponga una solución que implique tamaños de píxeles absolutos.
  2. Se desconocen las dimensiones originales de la imagen y es posible que ya se ajusten o no a la ventana del navegador.
  3. La imagen está centrada vertical y horizontalmente.
  4. Deben conservarse las proporciones de la imagen.
  5. La imagen debe mostrarse en su totalidad en la ventana (sin recortar).
  6. No deseo que aparezcan las barras de desplazamiento (y no deberían hacerlo si la imagen encaja).
  7. La imagen cambia de tamaño automáticamente cuando cambian las dimensiones de la ventana, para ocupar todo el espacio disponible sin ser más grande que su tamaño original.

Básicamente lo que quiero es esto:

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

El problema con el código anterior es que no funciona: la imagen ocupa todo el espacio vertical que necesita al agregar una barra de desplazamiento vertical.

A mi disposición está PHP, Javascript, JQuery, pero mataría por una solución solo de CSS. No me importa si no funciona en IE.

sebnukem
fuente
perraultarchitecte.com/en/projects/… Este es el efecto que desea, ¿verdad? ¡yo también!
1
sí lo es. La solución que he publicado anteriormente funciona. Puedes ver el resultado en eseb.net/potos.php?f=best_of/fort_collins_winter.jpg
sebnukem
Gracias, eso realmente me ayuda. ¿Alguna sugerencia de qué podría hacer para colocar dos imágenes una al lado de la otra, manteniendo la funcionalidad de cambio de tamaño? Gracias.
9
Me gusta su "no requisito": "No me importa si no funciona en IE". :)
Bastian

Respuestas:

122

Actualización 2018-04-11

Aquí hay una solución sin Javascript y solo CSS . La imagen se centrará y cambiará de tamaño dinámicamente para adaptarse a la ventana.

<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>

La solución [otra, antigua], que usa JQuery, establece la altura del contenedor de la imagen ( bodyen el ejemplo siguiente) para que la max-heightpropiedad de la imagen funcione como se esperaba. La imagen también cambiará de tamaño automáticamente cuando se cambie el tamaño de la ventana del cliente.

<!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: El usuario gutierrezalex empaquetó una solución muy similar a un complemento de JQuery en esta página.

sebnukem
fuente
6
No se necesita JS, hay una única solución de CSS .
Neolisk
También sin JS, alternativamente use flexbox
Jason Sturges
51

Aquí hay una solución simple de solo CSS ( JSFiddle ), funciona en todas partes, móviles e IE incluidos:

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
fuente
2
Agradable. Pero no está centrado verticalmente.
sebnukem
1
@sebnukem: ¿Se suponía que debía ser? De alguna manera me perdí esto en los requisitos. Es por eso que la gente usa capturas de pantalla / maquetas. :) PD: No creo que ninguna de las respuestas proporcionadas lo haga centrado verticalmente, incluso con la ayuda de JS.
Neolisk
3
He probado muchas soluciones, incluso soluciones de css-tricks. ¡El tuyo funciona perfectamente como un encanto!
Stephan
2
¡La mejor solución!
iVela
24

CSS3 introduce nuevas unidades que se miden en relación con la ventana gráfica, que es la ventana en este caso. Estos son vhy vw, que miden la altura y el ancho de la ventana, respectivamente. Aquí hay una solución simple de CSS:

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

La única advertencia a esto es que solo funciona si no hay otros elementos que contribuyan a la altura de la página.

Max
fuente
Gracias, eso es genial. ¿Hay alguna razón por la 100vhque no deja que la imagen encaje pero 97vhfunciona bien?
Pavel
¿Quizás tienes otras imágenes que aportan altura, como margen y relleno en el cuerpo? vhliteralmente significa la altura de la vista, por lo que si cualquier otro elemento agrega altura a su página, la página completa será> 100vh. ¿Tiene sentido?
Máximo
Gracias, resuelto ahora. Si alguien tiene el mismo problema (el .svgarchivo se procesa bien, pero cambiarle el nombre a .htmlcausa inexactitud): el navegador agrega automáticamente la <body>etiqueta con el valor predeterminado margin:8incluso si el archivo no tiene <body>etiqueta. Entonces la solución es agregar<style>body{margin:0}</style>
Pavel
15

Si está dispuesto a poner un elemento contenedor alrededor de su imagen, una solución CSS pura es simple. Verá, el 99% de la altura no tiene significado cuando el elemento padre se extenderá verticalmente para contener sus hijos. El padre debe tener una altura fija, digamos ... la altura de la ventana gráfica.

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%;
}

Juega con el violín .

Mark E. Haase
fuente
¿Puedes hacer esto con un en <div>lugar de un <img>?
StevoHN
@sebnukem No noté ese requisito antes. Actualicé mi respuesta.
Mark E. Haase
Esto no maximiza la altura de mi imagen ancha.
Sridhar Sarnobat
4

Cambiar el tamaño de la imagen para que se ajuste a la pantalla por el lado más largo manteniendo su relación de aspecto

img[src$="#fit"] {
    width: 100vw;
    height: auto;
    max-width: none;
    max-height: 100vh;
    object-fit: contain;
}
  • width: 100vw - el ancho de la imagen será el 100% del puerto de visualización

  • height: auto - la altura de la imagen se escalará proporcionalmente

  • max-height: 100vw - si la altura de la imagen fuera mayor que el puerto de visualización, se reducirá para ajustarse a la pantalla, por lo que el ancho de la imagen se reducirá debido a la siguiente propiedad

  • object-fit: contain - el contenido reemplazado se escala para mantener su relación de aspecto mientras se ajusta dentro del cuadro de contenido del elemento

    Nota: object-fites totalmente compatible solo desde IE 16.0

am0wa
fuente
1
Sin embargo, como esa solución, debe mencionar que el ajuste de objetos no es compatible con IE11, que lamentablemente todavía se usa ampliamente.
Blackbam
@DivijSehgal, entonces no lo necesita object-fito podría usar explícitamente object-fit: fill;cuál es el predeterminado .
am0wa
¿Qué pasa si queremos centrar verticalmente?
Fmstrat
¿Qué pasa si queremos centrar verticalmente? Simplemente agregue: margin: auto;
gato
La solución funciona junto con html y body style de otra respuesta: html, body {width: 100%; altura: 100%; margen: 0; acolchado: 0; }
Ivan Kovtun
3

Mi regla general de CSS perezoso:

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

Esto puede acercar la imagen si es de baja resolución para empezar (eso tiene que ver con la calidad de la imagen y el tamaño en las dimensiones. Para centrar su imagen, también puede probar (en el CSS)

display:block;    
margin: auto 0; 

para centrar tu imagen

en tu HTML:

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

Sé que ya hay algunas respuestas aquí, pero esto es lo que usé:

max-width: 100%;
max-height: 100vh;
width: auto;
margin: auto;
TomC
fuente
No tengo idea de por qué, pero esto funciona de maravilla. ¡Me encantaría una explicación!
SeedyROM
Yo tampoco, pero fue lo que encontré después de mucho buscar.
TomC
2

Tenía un requisito similar y tenía que hacerlo con CSS y JavaScript básicos. No hay JQuery disponible.

Esto es lo que tengo trabajando.

<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>

Nota: No he usado el 100% para el ancho de la imagen, ya que siempre se debe considerar un poco de relleno.

Rohit Vipin Mathews
fuente
2
Con CSS 3 obtenemos las unidades "vh" y "vw" que son porcentaje de altura de ventana y porcentaje de ancho de ventana respectivamente. simplemente img {ancho máximo: 95vw; max-height: 95vh;} podría ser suficiente.
bobpaul
Si puede agregarlo como respuesta, podría ser útil para cualquiera que llegue a esto más adelante.
Rohit Vipin Mathews
También puede apilar varias imágenes en el área visible. Para dos imágenes, coloque dos imgetiquetas en el bodyde la página y establezca max-heighten 49vh. La visualización de más de dos imágenes en el área visible se deja como ejercicio para el lector.
Andrew Beals
2

Hazlo simple. Gracias

.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
fuente
¡Gracias! simplemente agregando style = "height: 80vh;" en la etiqueta de la imagen me funcionó.
Tobias J.
1
width: 100%;
overflow: hidden;

Creo que eso debería funcionar.

RobinJ
fuente
Hola, gracias por tu respuesta, pero no funciona y no puede funcionar lógicamente cuando la altura de la imagen es mayor que la ventana.
sebnukem
1
Bueno ... ¿Qué es lo que pretendes hacer? ¿Quieres estirarlo? ¿O deberían dejarse intactas las proporciones originales (supongo que esto es lo que quieres)?
RobinJ
1

Sobre la base de la respuesta de @ Rohit, esto corrige los problemas marcados por Chrome, cambia el tamaño de las imágenes de manera confiable y también funciona para varias imágenes que están apiladas verticalmente, por ejemplo, <img src="foo.jpg"><br><img src="bar.jpg"><br><img src="baz.jpg"> probablemente haya una forma más elegante de hacer esto.

<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
fuente
0

Use este código en su etiqueta de estilo

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