¿Cómo hacer que la altura div se ajuste automáticamente al tamaño del fondo?

270

¿Cómo consigo que un div se ajuste automáticamente al tamaño del fondo que configuré sin establecer una altura específica (o altura mínima)?

JohnIdol
fuente

Respuestas:

255

Otra solución, quizás ineficiente, sería incluir la imagen bajo un imgconjunto de elementos visibility: hidden;. Luego haz elbackground-image div del entorno sea igual a la imagen.

Esto establecerá el div circundante al tamaño de la imagen en el imgelemento, pero lo mostrará como fondo.

<div style="background-image: url(http://your-image.jpg);">
 <img src="http://your-image.jpg" style="visibility: hidden;" />
</div>
Tmac
fuente
16
no es exactamente útil ya que la imagen usará el 'espacio' y el contenido parecerá tener un gran margen superior.
Bart Calixto
35
Quizás me estoy perdiendo algo, pero si vas a poner un imgmarcado en tu marcado de todos modos, ¿por qué no simplemente no escondes lo real <img>y no te molestas con background-imageninguno? ¿Qué ventaja hay de hacer las cosas de esta manera?
Mark Amery
3
Buena respuesta, pero ¿no tiene que cargar el navegador dos veces?
www139
8
@ www139 Cuando dices cargar, ¿qué quieres decir exactamente? Una vez que la imagen se ha descargado, presumiblemente se almacena en caché. A partir de ese momento, cualquier otra solicitud se basa en una copia local. Entonces no. No se descarga dos veces. Pero, se carga dos veces.
Tmac
2
@ MarkAmery Una de las mejores cosas background-imagees que puede usar modos de mezcla CSS , mientras imgque no puede.
Aaron Gray
539

Hay una manera muy agradable y genial de hacer que una imagen de fondo funcione como un imgelemento para que se ajuste heightautomáticamente. Necesitas saber la imagen widthy la heightproporción. Establezca el heightcontenedor en 0 y establezca el padding-topporcentaje según la relación de la imagen.

Se verá así:

div {
    background-image: url('http://www.pets4homes.co.uk/images/articles/1111/large/feline-influenza-all-about-cat-flu-5239fffd61ddf.jpg');
    background-size: contain;
    background-repeat: no-repeat;
    width: 100%;
    height: 0;
    padding-top: 66.64%; /* (img-height / img-width * container-width) */
                /* (853 / 1280 * 100) */
}

Acaba de obtener una imagen de fondo con altura automática que funcionará como un elemento img. Aquí hay un prototipo funcional (puede cambiar el tamaño y verificar la altura del div): http://jsfiddle.net/TPEFn/2/

Hasanavi
fuente
23
De hecho increíble! Solo para las generaciones futuras que vean esta respuesta, si está usando la brújula (scss), creé un mixin a partir de esto usando sus funciones de ayuda para hacer los cálculos por usted: @mixin div-same-size-as-background-img($url) { background-image: url($url); background-size: contain; background-repeat: no-repeat; width: 100%; height: 0; padding-top: percentage(image-height($url) / image-width($url)); }
Benjamin K.
20
Para su información para aquellos que se preguntan, el acolchado no crea un espacio en blanco porque solo agrega altura al elemento. La imagen es una imagen de fondo, por lo que se muestra con el posicionamiento y el espaciado adecuados. Es bastante estúpido que tengamos que inventar trucos como estos para CSS.
ahnbizcad
9
Desafortunadamente, el relleno superior no le permite poner nada más en el div, como elementos de formulario sobre el fondo.
Gary Hayes
14
@GaryHayes puedes configurar position:relativeel div y poner otro div dentro con position:absolute; top:0; bottom:0; left:0; right:0;set
lexith
17
Aunque este método funciona para mostrar una imagen de fondo, hace que el div en sí sea menos útil al rellenarlo con relleno. Kryptik sugirió agregar un div en posición absoluta dentro del contenedor, pero ¿por qué molestarse con una imagen de fondo? Entonces podría usar una imagen real en el div de contenido si va a colocar todo en absoluto sobre ella. Esto anula el propósito de usar una imagen de fondo en primer lugar.
paulmz
35

No hay forma de ajustar automáticamente el tamaño de la imagen de fondo con CSS.

Puede hackearlo midiendo la imagen de fondo en el servidor y luego aplicando esos atributos al div, como otros han mencionado.

También podría hackear algunos javascript para cambiar el tamaño del div en función del tamaño de la imagen (una vez que la imagen se haya descargado), esto es básicamente lo mismo.

Si necesita que su div se ajuste automáticamente a la imagen, podría preguntarle por qué no coloca una <img>etiqueta dentro de su div.

Orion Edwards
fuente
Gracias, pero lo necesito como fondo para que el truco de la imagen no lo haga. Supongo que voy a hackear algunos javascript como dices en el peor de los casos, pero probablemente no valga la pena.
JohnIdol
3
^^ Probablemente no sea una buena idea. El navegador puede tardar varios segundos antes de que se descargue su imagen, y no puede medirla hasta entonces, por lo que su div estará colgando en el tamaño incorrecto durante bastante tiempo.
Orion Edwards
1
Podría ejecutar el JavaScript cuando el documento esté listo entonces.
Scott Tesler
1
No puede cambiar el srcde un imgcon consultas de medios, pero puede cambiar el archivo utilizado como imagen de fondo con consultas de medios.
Scott Marcus
21

Esta respuesta es similar a otras, pero en general es la mejor para la mayoría de las aplicaciones. Debe conocer el tamaño de la imagen de antemano, lo que generalmente hace. Esto le permitirá agregar texto superpuesto, títulos, etc. sin relleno negativo o posicionamiento absoluto de la imagen. La clave es establecer el% de relleno para que coincida con la relación de aspecto de la imagen como se ve en el siguiente ejemplo. Usé esta respuesta y esencialmente solo agregué un fondo de imagen.

.wrapper {
  width: 100%;
  /* whatever width you want */
  display: inline-block;
  position: relative;
  background-size: contain;
  background: url('https://upload.wikimedia.org/wikipedia/en/thumb/6/67/Wiki-llama.jpg/1600px-Wiki-llama.jpg') top center no-repeat;
  margin: 0 auto;
}
.wrapper:after {
  padding-top: 75%;
  /* this llama image is 800x600 so set the padding top % to match 600/800 = .75 */
  display: block;
  content: '';
}
.main {
  position: absolute;
  top: 0;
  bottom: 0;
  right: 0;
  left: 0;
  color: black;
  text-align: center;
  margin-top: 5%;
}
<div class="wrapper">
  <div class="main">
    This is where your overlay content goes, titles, text, buttons, etc.
  </div>
</div>

jinete
fuente
2
-1 para usar! Important - y vincular a otra respuesta. Considere copiar el código correspondiente de la otra respuesta (con atribución) i para que esta sea más completa y en caso de rotura del enlace.
totallyNotLizards
@jammypeach es esto mejor?
Horsejockey
1
@horsejockey a menos que me falte algo, esto no escala la imagen. Simplemente lo enmascara.
dwkns
@dwkns Por extraño que parezca, todas las llamadas en segundo plano deben estar en un elemento. Descubrí que se estaba recortando cuando especifiqué "background: url ()" en una identificación específica y "background-size: contienen" en una clase general.
Nathan Williams
@dwkns Actualización: pude solucionar ese problema usando "background-image: url ()" en lugar de "background: url ()".
Nathan Williams
15

Tal vez esto pueda ayudar, no es exactamente un fondo, pero tienes la idea:

<style>
div {
    float: left;
    position: relative;
}
div img {
    position: relative;
}

div div {
    position: absolute;
    top:0;
    left:0;
}
</style>

<div>
    <img src="http://antwrp.gsfc.nasa.gov/apod/image/0903/omegacen_davis.jpg" />
    <div>Hi there</div>
</div>
Luca Matteis
fuente
explique por qué mantuvo la posición de img como relativo?
Divyanshu Jimmy
1
Probablemente porque float: left;rompió su posicionamiento
Isaac
12

Estoy bastante seguro de que esto nunca se habrá visto hasta aquí. Pero si su problema era el mismo que el mío, esta era mi solución:

.imaged-container{
  background-image:url('<%= asset_path("landing-page.png") %> ');
  background-repeat: no-repeat;
  background-size: 100%;
  height: 65vw;
}

Quería tener un div en el centro de la imagen, y esto me permitirá eso.

Carpa
fuente
9

Hay una solución CSS pura que las otras respuestas han perdido.

La propiedad "content:" se usa principalmente para insertar contenido de texto en un elemento, pero también se puede usar para insertar contenido de imagen.

.my-div:before {
    content: url("image.png");
}

Esto hará que el div cambie el tamaño de su altura al tamaño de píxel real de la imagen. Para cambiar el tamaño del ancho también, agregue:

.my-div {
    display: inline-block;
}
Bernie Sumption
fuente
1
Me gusta esta solución, pero cuando el navegador se hace más pequeño, queda mucho espacio en blanco debajo de la imagen del encabezado, que está configurado para responder.
MG1
6

Puede hacerlo del lado del servidor: midiendo la imagen y luego configurando el tamaño div, O cargando la imagen con JS, lea sus atributos y luego configure el tamaño DIV.

Y aquí hay una idea, poner la misma imagen dentro del div como una etiqueta IMG, pero darle visibilidad: oculto + jugar con posición relativa + darle a este div la imagen como fondo.

Itay Moav -Malimovka
fuente
jajaja ¿por qué requieren del lado del servidor? Debería poder implementarse con CSS.
GTHell
1
@GTHell jajaja - mira el año que respondí
Itay Moav -Malimovka
@ ItayMoav-Malimovka jeje, no se dio cuenta de eso.
GTHell
5

Tuve este problema y encontré la respuesta de Hasanavi, pero recibí un pequeño error al mostrar la imagen de fondo en una pantalla panorámica: la imagen de fondo no se extendió a todo el ancho de la pantalla.

Así que aquí está mi solución, basada en el código de Hasanavi pero mejor ... y esto debería funcionar tanto en pantallas extra anchas como móviles.

/*WIDE SCREEN SUPPORT*/
@media screen and (min-width: 769px) { 
    div {
        background-image: url('http://www.pets4homes.co.uk/images/articles/1111/large/feline-influenza-all-about-cat-flu-5239fffd61ddf.jpg');
        background-size: cover;
        background-repeat: no-repeat;
        width: 100%;
        height: 0;
        padding-top: 66.64%; /* (img-height / img-width * container-width) */
                    /* (853 / 1280 * 100) */
    }
}

/*MOBILE SUPPORT*/
@media screen and (max-width: 768px) {
    div {
        background-image: url('http://www.pets4homes.co.uk/images/articles/1111/large/feline-influenza-all-about-cat-flu-5239fffd61ddf.jpg');
        background-size: contain;
        background-repeat: no-repeat;
        width: 100%;
        height: 0;
        padding-top: 66.64%; /* (img-height / img-width * container-width) */
                    /* (853 / 1280 * 100) */
    }
}

Como habrás notado, la background-size: contain;propiedad no encaja bien en pantallas extra anchas, y la background-size: cover;propiedad no encaja bien en pantallas móviles, así que usé este @mediaatributo para jugar con los tamaños de pantalla y solucionar este problema.

Martin Schwartz
fuente
3

Qué tal esto :)

.fixed-centered-covers-entire-page{
    margin:auto;
    background-image: url('https://i.imgur.com/Ljd0YBi.jpg');
    background-repeat: no-repeat;background-size:cover;
    background-position: 50%;
    background-color: #fff;
    left:0;
    right:0;
    top:0;
    bottom:0;
    z-index:-1;
    position:fixed;
}
<div class="fixed-centered-covers-entire-page"></div>

Demostración: http://jsfiddle.net/josephmcasey/KhPaF/

Joseph Casey
fuente
3

Si se trata de una única imagen de fondo predeterminada y desea que el div responda sin distorsionar la relación de aspecto de la imagen de fondo, primero puede calcular la relación de aspecto de la imagen y luego crear un div que conserve su relación de aspecto haciendo lo siguiente :

Digamos que quiere una relación de aspecto de 4/1 y el ancho del div es 32%:

div {
  width: 32%; 
  padding-bottom: 8%; 
}

Esto resulta del hecho de que el relleno se calcula en función del ancho del elemento contenedor.

Dolor de cabeza
fuente
1

Puede ser que esto pueda ayudar, no es exactamente un fondo, pero tienes la idea simple

    <style>
div {
    float: left;
    position: relative;
}
div img {
    position: relative;
}

div div {
    position: absolute;
    top:0;
    left:0;
}
</style>

<div>
    <img src="http://www.planwallpaper.com/static/images/recycled_texture_background_by_sandeep_m-d6aeau9_PZ9chud.jpg" />
    <div>Hello</div>
</div>
Engr
fuente
1

Puedes hacer algo asi

<div style="background-image: url(http://your-image.jpg); position:relative;">
 <img src="http://your-image.jpg" style="opacity: 0;" />
<div style="position: absolute;top: 0;width: 100%;height: 100%;">my content goes here</div>
</div>
Mas
fuente
1

Si conoce la proporción de la imagen en el momento de la creación, desea que la altura se base en la altura de la ventana y está bien orientada a los navegadores modernos (IE9 +) , entonces puede usar unidades de ventana para esto:

.width-ratio-of-height {
  overflow-x: scroll;
  height: 100vh;
  width: 500vh; /* width here is 5x height */
  background-image: url("http://placehold.it/5000x1000");
  background-size: cover;
}

No es exactamente lo que pedía el OP, pero probablemente sea una buena opción para muchos de los que ven esta pregunta, por lo que quería dar otra opción aquí.

Violín: https://jsfiddle.net/6Lkzdnge/

fredrivett
fuente
1

Miré algunas de las soluciones y son geniales, pero creo que encontré una manera sorprendentemente fácil.

Primero, necesitamos obtener la proporción de la imagen de fondo. Simplemente dividimos una dimensión por otra. Luego obtenemos algo como, por ejemplo, 66.4%

Cuando tenemos una relación de imagen, simplemente podemos calcular la altura del div multiplicando la relación por el ancho de la vista:

height: calc(0.664 * 100vw);

Para mí, funciona, establece la altura div correctamente y la cambia cuando se cambia el tamaño de la ventana.

Landeeyo
fuente
1

Supongamos que tienes algo como esto:

<div class="content">
    ... // inner HTML
</div>

y desea agregarle un fondo, pero no conoce la dimensión de la imagen.

Tuve un problema similar y lo resolví usando grid:

HTML

<div class="outer">
    <div class="content">
        ... // inner HTML
    </div>
    <img class="background" />
</div>

CSS

.outer{
    display: grid;
    grid-template: auto / auto;
    // or you can assign a name for this block
}
.content{
    grid-area: 1 / 1 / 2 / 2;
    z-index: 2;
}
.background{
    grid-area: 1 / 1 / 2 / 2;
    z-index: 1;
}

z-indexes solo para colocar la imagen en el fondo, por supuesto, puede colocarla img.backgroundencima del div.content.

NOTA : puede causar que div.contenttenga la misma altura de la imagen, por lo que si div.contenttiene hijos que se colocan de acuerdo con su altura, es posible que desee establecer un número que no sea algo como 'auto'.

魏 一 元
fuente
0

Tuve este problema con el Umbraco CMS y en este escenario puede agregar la imagen al div usando algo como esto para el atributo 'style' del div:

style="background: url('@(image.mediaItem.Image.umbracoFile)') no-repeat scroll 0 0 transparent; height: @(image.mediaItem.Image.umbracoHeight)px"
Chris Halcrow
fuente
0

He estado lidiando con este problema por un tiempo y decidí escribir un complemento jquery para resolver este problema. Este complemento encontrará todos los elementos con la clase "show-bg" (o puede pasarle su propio selector) y calculará sus dimensiones de imagen de fondo. todo lo que tiene que hacer es incluir este código, marcar los elementos deseados con class = "show

¡Disfrutar!

https://bitbucket.org/tomeralmog/jquery.heightfrombg

Tomer Almog
fuente
0

La mejor solución que se me ocurre es especificando su ancho y alto en porcentaje. Esto le permitirá cambiar el tamaño de su pantalla según el tamaño de su monitor. es más de diseño receptivo ...

Por una instancia tienes

<br/>
<div> . //This you set the width percent to %100
    <div> //This you set the width percent to any amount . if you put it by 50% , it will be half
    </div>
 </div>

Esta es la mejor opción si desea un diseño receptivo, no recomendaría float, en algunos casos está bien usar float. pero en la mayoría de los casos, evitamos el uso de flotante, ya que afectará una gran cantidad de cosas cuando realice pruebas en varios navegadores.

Espero que esto ayude :)

FaridAvesko
fuente
-1

en realidad es bastante fácil cuando sabes cómo hacerlo:

<section data-speed='.618' data-type='background' style='background: url(someUrl) 
top center no-repeat fixed;  width: 100%; height: 40vw;'>
<div style='width: 100%; height: 40vw;'>
</div>
</section>

El truco consiste en establecer el div incluido como un div normal con valores dimensionales iguales a los valores dimensionales de fondo (en este ejemplo, 100% y 40vw).

C. Schaefer
fuente
Está configurando la altura para que sea una proporción del ancho de la ventana. Esto no funcionará en todos los casos, y parte de su contenido, como la velocidad de datos, no tiene nada que ver con su respuesta.
Polyducks el
¿No son la mayoría de las cosas "bastante fáciles cuando sabes cómo hacerlo"?
Scott Marcus el
-2

Resolví esto usando jQuery. Hasta que las nuevas reglas CSS permitan este tipo de comportamiento de forma nativa, creo que es la mejor manera de hacerlo.

Configura tus divs

A continuación tiene su div en el que desea que aparezca el fondo ("héroe") y luego el contenido / texto interno que desea superponer en la parte superior de su imagen de fondo ("interno"). Puede (y debe) mover los estilos en línea a su clase de héroe. Los dejé aquí, así que es rápido y fácil ver qué estilos se le aplican.

<div class="hero" style="background-image: url('your-image.png'); background-size: 100%; background-repeat: no-repeat; width: 100%;">
    <div class="inner">overlay content</div>
</div>

Calcular la relación de aspecto de la imagen

Luego calcule su relación de aspecto para su imagen dividiendo la altura de su imagen por el ancho. Por ejemplo, si la altura de su imagen es 660 y su ancho es 1280, su relación de aspecto es 0.5156.

Configure un evento de cambio de tamaño de la ventana jQuery para ajustar la altura

Finalmente, agregue un detector de eventos jQuery para cambiar el tamaño de la ventana y luego calcule la altura de su div div en función de la relación de aspecto y actualícela. Esta solución generalmente deja un píxel adicional en la parte inferior debido a cálculos imperfectos que usan la relación de aspecto, por lo que agregamos un -1 al tamaño resultante.

$(window).on("resize", function ()
{
    var aspect_ratio = .5156; /* or whatever yours is */
    var new_hero_height = ($(window).width()*aspect_ratio) - 1;
    $(".hero").height(new_hero_height);
}

Asegúrese de que funcione en la carga de la página

Debe realizar la llamada de cambio de tamaño anterior cuando se carga la página para calcular los tamaños de imagen desde el principio. Si no lo hace, entonces el div hero no se ajustará hasta que cambie el tamaño de la ventana. Configuré una función separada para hacer los ajustes de cambio de tamaño. Aquí está el código completo que uso.

function updateHeroDiv()
{
    var aspect_ratio = .5156; /* or whatever yours is */
    var new_hero_height = ($(window).width()*aspect_ratio) - 1;
    $(".hero").height(new_hero_height);
}

$(document).ready(function() 
{       
    // calls the function on page load
    updateHeroDiv(); 

    // calls the function on window resize
    $(window).on("resize", function ()
    {
        updateHeroDiv();        
    }
});
Art Geigel
fuente
-2

Si puede hacer una imagen en Photoshop donde la capa principal tiene una opacidad de 1 o menos y es básicamente transparente, coloque esa imagen en el div y luego convierta la imagen real en la imagen de fondo. ENTONCES establezca la opacidad del img en 1 y agregue las dimensiones de tamaño que desee.

Esa imagen se hace de esa manera, y ni siquiera puedes arrastrar la imagen invisible fuera de la página, lo cual es genial.

Tommy Nicholas
fuente
-4

solo agrega a div

style="overflow:hidden;"
Tevfik Aktaş
fuente