Imagen de fondo de 100% de ancho con una altura 'automática'

89

Actualmente estoy trabajando en una página de destino móvil para una empresa. Es un diseño realmente básico, pero debajo del encabezado hay una imagen de un producto que siempre tendrá un ancho del 100% (el diseño muestra que siempre va de un borde a otro). Dependiendo del ancho de la pantalla, la altura de la imagen obviamente se ajustará en consecuencia. Originalmente hice esto con un img (con un ancho de CSS del 100%) y funcionó muy bien, pero me di cuenta de que me gustaría usar consultas de medios para mostrar diferentes imágenes basadas en diferentes resoluciones, digamos una pequeña, mediana y una versión grande de la misma imagen, por ejemplo. Sé que no puedes cambiar el src img con CSS, así que pensé que debería usar un fondo CSS para la imagen en lugar de una etiqueta img en el HTML.

Parece que no puedo hacer que esto funcione correctamente ya que el div con la imagen de fondo necesita tanto un ancho como un alto para mostrar el fondo. Obviamente puedo usar 'ancho: 100%' pero ¿qué uso para la altura? Puedo poner una altura fija aleatoria como 150px y luego puedo ver los 150px superiores de la imagen, pero esta no es la solución ya que no hay una altura fija. Tuve una jugada y descubrí que una vez que hay una altura (probada con 150px) puedo usar 'background-size: 100%' para ajustar la imagen en el div correctamente. Puedo usar el CSS3 más reciente para este proyecto, ya que está dirigido únicamente a dispositivos móviles.

Agregué un ejemplo aproximado a continuación. Disculpe los estilos en línea, pero quería dar un ejemplo básico para intentar aclarar un poco mi pregunta.

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

¿Es posible que tenga que darle al contenedor div un porcentaje de altura basado en toda la página o estoy viendo esto completamente mal?

Además, ¿crees que los fondos CSS son la mejor manera de hacer esto? Tal vez haya una técnica que sirva diferentes etiquetas img según el ancho del dispositivo / pantalla. La idea general es que la plantilla de la página de destino se usará varias veces con diferentes imágenes de productos, por lo que debo asegurarme de desarrollarla de la mejor manera posible.

Me disculpo porque esto es un poco largo, pero estoy yendo y viniendo de este proyecto al siguiente, así que me gustaría terminar esta pequeña cosa. Gracias de antemano por su tiempo, es muy apreciado. Saludos

Darryl Young
fuente
Un navegador puede optar por no descargar un recurso de imagen si tiene display: none, por lo que siempre puede mostrar diferentes imágenes con consultas de medios sin JS
Ben Taliadoros

Respuestas:

16

En lugar de usar background-image, puede usar imgdirectamente y para que la imagen se extienda por todo el ancho de la ventana gráfica, intente usar max-width:100%;y recuerde que no aplique ningún relleno o margen a su div contenedor principal, ya que aumentarán el ancho total del contenedor. Con esta regla, puede tener un ancho de imagen igual al ancho del navegador y la altura también cambiará de acuerdo con la relación de aspecto. Gracias.

Editar: cambiar la imagen en diferentes tamaños de la ventana

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

De esta manera, cambia su imagen en diferentes tamaños del navegador.

maksbd19
fuente
Gracias por tomarse el tiempo para hacer esto por mí, es muy apreciado. Lo intenté rápidamente y parece estar funcionando.
Darryl Young
2
Esta vieja respuesta parecía atractiva ... pero ¿no es cierto que el navegador móvil todavía descargará (simplemente no mostrará) la imagen configurada inicialmente en el HTML como src? Si es así, eso no es un comienzo, ya que el objetivo es conservar los recursos del dispositivo móvil.
Tim Gallant
1
Creo que Tim Gallant tiene razón en este caso: en este caso, el navegador cargará ambas imágenes como recurso y luego mostrará la de menor resolución. Entonces, si bien esto parece atractivo, en dispositivos móviles es más lento que cargar solo el de alta resolución y con ese sacrificio solo verá la imagen de menor resolución ... lo peor de ambos mundos.
pequeño hombrecito
1
Mala respuesta. Voto en contra. Código simplemente hinchado y antiguo.
TheBlackBenzKid
Insertar consultas de medios que agregan visualización: ninguna a las imágenes que no desea mostrar; la mayoría de los navegadores no las descargarán
Ben Taliadoros
213

Tim S. estaba mucho más cerca de una respuesta "correcta" que la aceptada actualmente. Si desea tener una imagen de fondo 100% de ancho y altura variable hecha con CSS, en lugar de usar cover(lo que permitirá que la imagen se extienda desde los lados) o contain(que no permita que la imagen se extienda en absoluto), simplemente establece el CSS así:

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

Esto establecerá su imagen de fondo al 100% de ancho y permitirá que la altura se desborde. Ahora puede usar consultas de medios para intercambiar esa imagen en lugar de confiar en JavaScript.

EDITAR: Me acabo de dar cuenta (3 meses después) de que probablemente no quieras que la imagen se desborde; parece que desea que el elemento contenedor cambie de tamaño en función de su imagen de fondo (para preservar su relación de aspecto), lo que no es posible con CSS que yo sepa.

Con suerte, pronto podrá utilizar el nuevo atributo srcset en el imgelemento. Si desea utilizar imgelementos ahora, la respuesta aceptada actualmente es probablemente la mejor.

Sin embargo, puede crear un elemento de imagen de fondo sensible con una relación de aspecto constante utilizando únicamente CSS. Para hacer esto, establece el heighten 0 y establece el padding-bottomen un porcentaje del ancho propio del elemento, así:

.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 utilizar diferentes relaciones de aspecto, divida la altura de la imagen original por su propio ancho y multiplique por 100 para obtener el valor porcentual. Esto funciona porque el porcentaje de relleno siempre se calcula en función del ancho, incluso si es un relleno vertical.

cr0ybot
fuente
4
perfecto, la búsqueda rápida en Google me trajo aquí, ¡problema resuelto!
J King
6
Respuestas como esta deberían ser las aceptadas, responden a la pregunta. Por supuesto, dé una "mejor solución", pero también responda la pregunta y, cuando la gente la encuentre, obtendrá la respuesta que desea.
tim.baker
Esto no funciona para mí, estoy usando Google Chrome 47.0. ¿Puede ser porque la respuesta está desactualizada?
MiV
¿Podría ser más específico sobre qué parte no funciona? Di varias respuestas posibles, por lo que si una parte no funciona, puedo desarrollar más para dar una respuesta mejor y más actualizada.
cr0ybot
por alguna razón poco clara, la configuración background-size: autoresolvió mi problema en todas las orientaciones de dispositivos.
n__o
17

Prueba esto

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

Versión simplificada

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

Puede utilizar la propiedad CSS background-sizey establecerla en covero contain, según sus preferencias. La cubierta cubrirá la ventana por completo, mientras que contener hará que un lado se ajuste a la ventana, por lo que no cubrirá toda la página (a menos que la relación de aspecto de la pantalla sea igual a la imagen).

Tenga en cuenta que esta es una propiedad CSS3. En los navegadores más antiguos, esta propiedad se ignora. Alternativamente, puede usar javascript para cambiar la configuración de CSS según el tamaño de la ventana, pero esto no es lo preferido.

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

Simplemente use una imagen de fondo de dos colores:

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

Es 2017, y ahora puede usar el ajuste de objetos que tiene un soporte decente . Funciona de la misma manera que un div, background-sizepero en el elemento en sí y en cualquier elemento, incluidas las imágenes.

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