Comment faire pour que la hauteur de div s'ajuste automatiquement à la taille de l'arrière-plan?

270

Comment puis-je obtenir un div pour s'ajuster automatiquement à la taille de l'arrière-plan que je lui ai défini sans lui définir une hauteur (ou une hauteur minimale) spécifique?

JohnIdol
la source

Réponses:

255

Une autre solution, peut-être inefficace, serait d'inclure l'image sous un imgélément défini sur visibility: hidden;. Faites ensuite background-imagela même chose que l'image div.

Cela définira la div environnante à la taille de l'image dans l' imgélément mais l'affichera comme arrière-plan.

<div style="background-image: url(http://your-image.jpg);">
 <img src="http://your-image.jpg" style="visibility: hidden;" />
</div>
Tmac
la source
16
pas exactement utile car l'image utilisera l '«espace» et le contenu aura l'air d'avoir une grande marge supérieure.
Bart Calixto
35
Peut-être que je manque quelque chose, mais si vous allez mettre imgdans votre balisage de toute façon, pourquoi ne pas tout simplement pas cacher la réelle <img>et embêtez pas avec un background-imageou l' autre? Quel avantage y a-t-il à faire les choses de cette façon?
Mark Amery
3
Bonne réponse, mais le navigateur ne doit-il pas alors le charger deux fois?
www139
8
@ www139 Quand vous dites charge, que voulez-vous dire exactement? Une fois l'image téléchargée, elle est vraisemblablement mise en cache. À partir de ce moment, toutes les autres demandes sont basées sur une copie locale. Donc non. Il n'est pas téléchargé deux fois. Mais, il est chargé deux fois.
Tmac
2
@MarkAmery L'une des choses les plus intéressantes background-imageest qu'il peut utiliser les modes de mélange CSS , alors imgqu'il ne le peut pas.
Aaron Gray
539

Il existe un moyen très agréable et cool de faire fonctionner une image d'arrière-plan comme un imgélément afin qu'elle s'ajuste heightautomatiquement. Vous devez connaître l'image widthet le heightrapport. Réglez le heightconteneur sur 0 et définissez le padding-toppourcentage en fonction du rapport d'image.

Il ressemblera à ceci:

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) */
}

Vous venez d'obtenir une image d'arrière-plan avec une hauteur automatique qui fonctionnera comme un élément img. Voici un prototype fonctionnel (vous pouvez redimensionner et vérifier la hauteur de div): http://jsfiddle.net/TPEFn/2/

Hasanavi
la source
23
En effet génial! Juste pour les générations futures qui regardent cette réponse, si vous utilisez la boussole (scss), j'ai créé un mixin à partir de cela en utilisant leurs fonctions d'assistance pour faire les calculs pour vous: @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
Pour ceux qui se demandent, le rembourrage ne crée pas d'espace blanc car il ajoute simplement de la hauteur à l'élément. L'image est une image d'arrière-plan, elle s'affiche donc avec un positionnement et un espacement appropriés. C'est assez stupide, nous devons trouver des astuces comme celles-ci pour CSS.
ahnbizcad
9
Malheureusement, le padding-top ne vous permet pas de mettre quoi que ce soit d'autre dans la div, comme des éléments de formulaire sur l'arrière-plan.
Gary Hayes
14
@GaryHayes vous pouvez définir position:relativele div et mettre un autre div à l'intérieur avec position:absolute; top:0; bottom:0; left:0; right:0;set
lexith
17
Bien que cette méthode fonctionne pour afficher une image d'arrière-plan, elle rend le div lui-même moins utile en le remplissant de remplissage. Kryptik a suggéré d'ajouter un div absolument positionné à l'intérieur du conteneur, mais alors pourquoi s'embêter avec une image d'arrière-plan? Vous pouvez alors simplement utiliser une image réelle dans la division de contenu si vous voulez simplement tout placer en position absolue dessus. Cela va à l'encontre du but d'utiliser une image d'arrière-plan en premier lieu.
paulmz
35

Il n'y a aucun moyen de régler automatiquement la taille de l'image d'arrière-plan à l'aide de CSS.

Vous pouvez le pirater en mesurant l'image d'arrière-plan sur le serveur, puis en appliquant ces attributs à la div, comme d'autres l'ont mentionné.

Vous pouvez également pirater du javascript pour redimensionner la div en fonction de la taille de l'image (une fois que l'image a été téléchargée) - c'est essentiellement la même chose.

Si vous avez besoin de votre div pour ajuster automatiquement l'image, je pourrais vous demander pourquoi ne mettez-vous pas simplement une <img>étiquette à l'intérieur de votre div?

Orion Edwards
la source
Merci - mais j'en ai besoin comme arrière-plan pour que l'astuce d'image ne le fasse pas. Je suppose que je vais pirater du javascript comme vous le dites dans le pire des cas, mais cela n'en vaut probablement pas la peine.
JohnIdol
3
^^ Ce n'est probablement pas une bonne idée. Le navigateur peut prendre plusieurs secondes avant que votre image ne soit téléchargée, et vous ne pouvez pas la mesurer jusque-là, donc votre div sera suspendu à la mauvaise taille pendant un certain temps!
Orion Edwards
1
Il pourrait simplement exécuter le JavaScript lorsque le document est prêt.
Scott Tesler
1
Vous ne pouvez pas changer srcd'une imgdes requêtes des médias, mais vous pouvez modifier le fichier utilisé comme une image de fond avec les requêtes des médias.
Scott Marcus
21

Cette réponse est similaire aux autres, mais est globalement la meilleure pour la plupart des applications. Vous devez connaître la taille de l'image avant la main, ce que vous faites habituellement. Cela vous permettra d'ajouter du texte de superposition, des titres, etc. sans remplissage négatif ni positionnement absolu de l'image. Leur clé est de définir le pourcentage de remplissage pour qu'il corresponde au rapport d'aspect de l'image, comme illustré dans l'exemple ci-dessous. J'ai utilisé cette réponse et j'ai simplement ajouté un fond d'image.

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

horsejockey
la source
2
-1 pour utiliser! Important - et un lien vers une autre réponse. Veuillez envisager de copier le code correspondant de l'autre réponse (avec attribution) i afin que celle-ci soit plus complète et en cas de pourriture du lien.
totallyNotLizards du
@jammypeach est-ce mieux?
horsejockey
1
@horsejockey, sauf si je manque quelque chose, cela n'améliore pas l'image. Il ne fait que le masquer.
dwkns
@dwkns Curieusement, tous les appels en arrière-plan doivent être dans le même élément. J'ai trouvé qu'il était en train de recadrer lorsque j'ai spécifié "background: url ()" sur un identifiant spécifique et "background-size: contain" dans une classe générale.
Nathan Williams
@dwkns Update: j'ai pu résoudre ce problème en utilisant "background-image: url ()" au lieu de "background: url ()".
Nathan Williams
15

Peut-être que cela peut aider, ce n'est pas exactement un arrière-plan, mais vous avez l'idée:

<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
la source
veuillez expliquer pourquoi vous avez conservé la position d'img comme parent?
Divyanshu Jimmy
1
Probablement parce qu'il a float: left;cassé son positionnement
Isaac
12

Je suis presque sûr que cela ne sera jamais vu jusqu'ici. Mais si votre problème était le même que le mien, c'était ma solution:

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

Je voulais avoir un div au centre de l'image, et cela me le permettra.

Carpk
la source
9

Il existe une solution CSS pure que les autres réponses ont manqué.

La propriété "content:" est principalement utilisée pour insérer du contenu textuel dans un élément, mais peut également être utilisée pour insérer du contenu d'image.

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

Cela entraînera le div redimensionner sa hauteur à la taille réelle des pixels de l'image. Pour redimensionner également la largeur, ajoutez:

.my-div {
    display: inline-block;
}
Bernie Sumption
la source
1
J'aime cette solution, mais lorsque le navigateur est plus petit, il y a beaucoup d'espace blanc sous l'image d'en-tête qui est réglé pour être réactif.
MG1
6

Vous pouvez le faire côté serveur: en mesurant l'image puis en définissant la taille div, OU en chargeant l'image avec JS, lisez ses attributs puis définissez la taille DIV.

Et voici une idée, mettez la même image à l'intérieur du div comme une balise IMG, mais donnez-lui de la visibilité: caché + jouer avec la position relative + donner à ce div l'image en arrière-plan.

Itay Moav -Malimovka
la source
lol pourquoi exiger côté serveur? Il devrait pouvoir être implémenté avec CSS.
GTHell
1
@GTHell hahaha - vérifiez l'année à laquelle j'ai répondu
Itay Moav -Malimovka
@ ItayMoav-Malimovka hehe, n'a pas remarqué cela.
GTHell
5

J'ai eu ce problème et j'ai trouvé la réponse de Hasanavi mais j'ai eu un petit bug lors de l'affichage de l'image d'arrière-plan sur un écran large - L'image d'arrière-plan ne s'est pas propagée sur toute la largeur de l'écran.

Voici donc ma solution - basée sur le code de Hasanavi mais en mieux ... et cela devrait fonctionner à la fois sur les écrans extra-larges et mobiles.

/*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) */
    }
}

Comme vous l'avez peut-être remarqué, la background-size: contain;propriété ne s'adapte pas bien aux écrans extra larges et la background-size: cover;propriété ne convient pas aux écrans mobiles.J'ai donc utilisé cet @mediaattribut pour jouer avec les tailles d'écran et résoudre ce problème.

martin schwartz
la source
3

Que dis-tu de ça :)

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

Démo: http://jsfiddle.net/josephmcasey/KhPaF/

Joseph Casey
la source
3

S'il s'agit d'une seule image d'arrière-plan prédéterminée et que vous voulez que le div réponde sans déformer le rapport d'aspect de l'image d'arrière-plan, vous pouvez d'abord calculer le rapport d'aspect de l'image, puis créer un div qui préserve son rapport d'aspect en procédant comme suit :

Supposons que vous souhaitiez un rapport d'aspect de 4/1 et que la largeur de la division soit de 32%:

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

Cela résulte du fait que le rembourrage est calculé en fonction de la largeur de l'élément conteneur.

Mal de crâne
la source
1

Peut-être que cela peut aider, ce n'est pas exactement un arrière-plan, mais vous avez l'idée 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
la source
1

Vous pouvez faire quelque chose comme ça

<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
la source
1

Si vous connaissez le rapport de l'image au moment de la construction, que vous voulez la hauteur basée sur la hauteur de la fenêtre et que vous êtes d'accord pour cibler les navigateurs modernes (IE9 +) , vous pouvez utiliser des unités de fenêtre pour cela:

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

Pas tout à fait ce que le PO demandait, mais probablement un bon ajustement pour beaucoup de ceux qui consultent cette question, alors je voulais donner une autre option ici.

Violon: https://jsfiddle.net/6Lkzdnge/

fredrivett
la source
1

J'ai regardé certaines des solutions et elles sont excellentes mais je pense que j'ai trouvé un moyen étonnamment facile.

Tout d'abord, nous devons obtenir le rapport de l'image d'arrière-plan. Nous divisons simplement une dimension par une autre. Ensuite, nous obtenons quelque chose comme par exemple 66,4%

Lorsque nous avons un rapport d'image, nous pouvons simplement calculer la hauteur de la division en multipliant le rapport par la largeur de la fenêtre d'affichage:

height: calc(0.664 * 100vw);

Pour moi, cela fonctionne, définit la hauteur de div correctement et la change lorsque la fenêtre est redimensionnée.

Landeeyo
la source
1

Supposons que vous ayez quelque chose comme ça:

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

et vous voulez lui ajouter un arrière-plan, mais vous ne connaissez pas la dimension de l'image.

J'ai eu un problème similaire et je l'ai résolu en utilisant la grille:

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-indexest juste pour placer l'image réellement à l'arrière-plan, vous pouvez bien sûr la placer img.backgroundau-dessus de div.content.

REMARQUE : cela peut provoquer la div.contentmême hauteur de l'image, donc si vous div.contentavez des enfants placés en fonction de sa hauteur, vous pouvez définir un nombre qui ne ressemble pas à 'auto'.

魏 一 元
la source
0

Eu ce problème avec le CMS Umbraco et dans ce scénario, vous pouvez ajouter l'image à la div en utilisant quelque chose comme ça pour l'attribut 'style' de la div:

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

Je traite ce problème depuis un certain temps et j'ai décidé d'écrire un plugin jquery pour résoudre ce problème. Ce plugin trouvera tous les éléments avec la classe "show-bg" (ou vous pouvez lui passer votre propre sélecteur) et calculera leurs dimensions d'image de fond. tout ce que vous avez à faire est d'inclure ce code, marquez les éléments souhaités avec class = "show

Prendre plaisir!

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

Tomer Almog
la source
0

La meilleure solution à laquelle je peux penser est de spécifier votre largeur et votre hauteur en pourcentage. Cela vous permettra de redimensionner votre écran en fonction de la taille de votre moniteur. sa disposition plus réactive ..

Par exemple. vous avez

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

C'est la meilleure option si vous souhaitez une mise en page réactive, je ne recommanderais pas float, dans certains cas, float est correct à utiliser. mais dans la plupart des cas, nous évitons d'utiliser float car cela affectera un certain nombre de choses lorsque vous effectuez des tests inter-navigateurs.

J'espère que cela t'aides :)

FaridAvesko
la source
-1

en fait c'est assez simple quand on sait comment faire:

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

l'astuce consiste simplement à définir le div inclus juste comme un div normal avec des valeurs dimensionnelles identiques aux valeurs dimensionnelles d'arrière-plan (dans cet exemple, 100% et 40vw).

c. schaefer
la source
Vous définissez la hauteur pour qu'elle soit proportionnelle à la largeur de la fenêtre. Cela ne fonctionnera pas dans tous les cas - et une partie de votre contenu, comme la vitesse des données, n'a rien à voir avec votre réponse.
Polyducks
La plupart des choses ne sont-elles pas «assez faciles quand on sait comment faire»?
Scott Marcus
-2

J'ai résolu cela en utilisant jQuery. Jusqu'à ce que les nouvelles règles CSS autorisent ce type de comportement nativement, je trouve que c'est la meilleure façon de le faire.

Configurez vos divs

Ci-dessous, vous avez votre div sur lequel vous souhaitez que l'arrière-plan apparaisse ("héros"), puis le contenu / texte intérieur que vous souhaitez superposer au-dessus de votre image d'arrière-plan ("intérieur"). Vous pouvez (et devez) déplacer les styles en ligne vers votre classe de héros. Je les ai laissés ici, il est donc rapide et facile de voir quels styles y sont appliqués.

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

Calculer le rapport hauteur / largeur de l'image

Calculez ensuite le rapport hauteur / largeur de votre image en divisant la hauteur de votre image par la largeur. Par exemple, si la hauteur de votre image est de 660 et votre largeur de 1280, votre rapport d'aspect est de 0,5156.

Configurer un événement de redimensionnement de fenêtre jQuery pour ajuster la hauteur

Enfin, ajoutez un écouteur d'événements jQuery pour le redimensionnement de la fenêtre, puis calculez la hauteur de votre div de héros en fonction du rapport d'aspect et mettez-le à jour. Cette solution laisse généralement un pixel supplémentaire en bas en raison de calculs imparfaits en utilisant le rapport d'aspect, nous ajoutons donc -1 à la taille résultante.

$(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);
}

Assurez-vous que cela fonctionne au chargement de la page

Vous devez effectuer l'appel de redimensionnement ci-dessus lorsque la page se charge pour que les tailles d'image soient calculées au départ. Si vous ne le faites pas, le div du héros ne s'ajustera pas tant que vous n'aurez pas redimensionné la fenêtre. J'ai configuré une fonction distincte pour effectuer les ajustements de redimensionnement. Voici le code complet que j'utilise.

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
la source
-2

Si vous pouvez créer une image sur Photoshop où le calque principal a une opacité de 1 ou plus et est fondamentalement transparent, mettez cette img dans le div, puis faites de l'image réelle l'image d'arrière-plan. ALORS définissez l'opacité de l'img à 1 et ajoutez les dimensions de taille que vous souhaitez.

Cette image se fait de cette façon, et vous ne pouvez même pas faire glisser l'image invisible de la page, ce qui est cool.

Tommy Nicholas
la source
-4

il suffit d'ajouter à div

style="overflow:hidden;"
Tevfik Aktaş
la source