Image d'arrière-plan à 100% de largeur avec une hauteur `` automatique ''

89

Je travaille actuellement sur une page de destination mobile pour une entreprise. C'est une mise en page vraiment basique, mais sous l'en-tête, il y a une image d'un produit qui aura toujours une largeur de 100% (le design montre qu'il va toujours d'un bord à l'autre). En fonction de la largeur de l'écran, la hauteur de l'image s'ajustera évidemment en conséquence. Je l'ai fait à l'origine avec une img (avec une largeur CSS de 100%) et cela fonctionnait très bien, mais j'ai réalisé que j'aimerais utiliser des requêtes multimédias pour servir différentes images en fonction de différentes résolutions - disons un petit, moyen et une grande version de la même image, par exemple. Je sais que vous ne pouvez pas changer le src img avec CSS donc j'ai pensé que je devrais utiliser un arrière-plan CSS pour l'image par opposition à une balise img dans le HTML.

Je n'arrive pas à faire fonctionner cela correctement car le div avec l'image d'arrière-plan a besoin à la fois d'une largeur et d'une hauteur pour afficher l'arrière-plan. Je peux évidemment utiliser 'width: 100%' mais que dois-je utiliser pour la hauteur? Je peux mettre une hauteur fixe aléatoire comme 150px, puis je peux voir les 150px supérieurs de l'image, mais ce n'est pas la solution car il n'y a pas de hauteur fixe. J'ai eu un jeu et j'ai trouvé qu'une fois qu'il y a une hauteur (testée avec 150px), je peux utiliser 'background-size: 100%' pour adapter correctement l'image dans le div. Je peux utiliser le CSS3 plus récent pour ce projet car il est uniquement destiné aux mobiles.

J'ai ajouté un exemple approximatif ci-dessous. Veuillez excuser les styles en ligne, mais je voulais donner un exemple de base pour essayer de rendre ma question un peu plus claire.

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

Dois-je peut-être donner au conteneur div une hauteur en pourcentage basée sur la page entière ou est-ce que je regarde cela complètement faux?

De plus, pensez-vous que les arrière-plans CSS sont le meilleur moyen de le faire? Il existe peut-être une technique qui sert différentes balises img en fonction de la largeur de l'appareil / de l'écran. L'idée générale est que le modèle de page de destination sera utilisé plusieurs fois avec différentes images de produits, je dois donc m'assurer de le développer de la meilleure façon possible.

Je m'excuse, c'est un peu long, mais je vais et vient de ce projet au suivant, alors j'aimerais que cette petite chose soit faite. Merci d'avance pour votre temps, c'est très apprécié. Cordialement

Darryl Young
la source
Un navigateur peut choisir de ne pas télécharger une ressource image si elle a display: none, donc vous pouvez toujours afficher différentes images avec des requêtes multimédias sans JS
Ben Taliadoros

Réponses:

16

Au lieu d'utiliser, background-imagevous pouvez utiliser imgdirectement et pour que l'image s'étale sur toute la largeur de la fenêtre, essayez d'utiliser max-width:100%;et rappelez-vous de ne pas appliquer de rembourrage ou de marge à votre div de conteneur principal car ils augmenteront la largeur totale du conteneur. En utilisant cette règle, vous pouvez avoir une largeur d'image égale à la largeur du navigateur et la hauteur changera également en fonction du rapport hauteur / largeur. Merci.

Edit: Changer l'image sur une taille différente de la fenêtre

$(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 cette façon, vous modifiez votre image dans une taille différente du navigateur.

maksbd19
la source
Merci d'avoir pris le temps de faire ça pour moi, c'est très apprécié. Je viens de l'essayer rapidement et cela semble fonctionner.
Darryl Young
2
Cette vieille réponse avait l'air attrayante ... mais n'est-il pas vrai que le navigateur mobile va toujours télécharger (mais pas afficher) l'image initialement définie dans le HTML comme src? Si tel est le cas, ce n'est pas une question de départ, car il s'agit de conserver les ressources de l'appareil mobile.
Tim Gallant
1
Je pense que Tim Gallant a raison sur celui-ci - dans ce cas, le navigateur chargera les deux images en tant que ressource, puis affichera simplement la résolution inférieure. Donc, bien que cela semble attrayant, sur mobile, c'est en fait plus lent que de ne charger que la haute résolution et avec ce sacrifice, vous ne verrez que l'image de résolution inférieure ... le pire des deux mondes.
petit homme minuscule
1
Mauvaise réponse. Voté contre. Code simplement gonflé et ancien.
TheBlackBenzKid
Insérez des requêtes multimédias qui ajoutent un affichage: aucune aux images que vous ne voulez pas afficher - la plupart des navigateurs ne les téléchargeront pas
Ben Taliadoros
213

Tim S. était beaucoup plus proche d'une réponse «correcte» que celle actuellement acceptée. Si vous voulez avoir une image d'arrière-plan de 100% de largeur et de hauteur variable réalisée avec CSS, au lieu d'utiliser cover(qui permettra à l'image de s'étendre sur les côtés) ou contain(qui ne permet pas du tout à l'image de s'étendre), il suffit définissez le CSS comme ceci:

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

Cela définira votre image d'arrière-plan sur une largeur de 100% et permettra à la hauteur de déborder. Vous pouvez désormais utiliser des requêtes multimédias pour échanger cette image au lieu de vous fier à JavaScript.

EDIT: Je viens de réaliser (3 mois plus tard) que vous ne voulez probablement pas que l'image déborde; vous semblez vouloir que l'élément conteneur soit redimensionné en fonction de son image d'arrière-plan (pour préserver son rapport hauteur / largeur), ce qui n'est pas possible avec CSS pour autant que je sache.

J'espère que vous pourrez bientôt utiliser le nouvel attribut srcset sur l' imgélément. Si vous souhaitez utiliser des imgéléments maintenant, la réponse actuellement acceptée est probablement la meilleure.

Cependant, vous pouvez créer un élément d'image d'arrière-plan réactif avec un rapport hauteur / largeur constant en utilisant purement CSS. Pour ce faire, définissez le heightsur 0 et définissez le padding-bottomsur un pourcentage de la propre largeur de l'élément, comme suit:

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

Pour utiliser différents rapports hauteur / largeur, divisez la hauteur de l'image d'origine par sa propre largeur et multipliez par 100 pour obtenir la valeur en pourcentage. Cela fonctionne car le pourcentage de remplissage est toujours calculé en fonction de la largeur, même s'il s'agit d'un remplissage vertical.

cr0ybot
la source
4
parfait, une recherche rapide sur Google m'a amené ici, problème résolu!
J King
6
Des réponses comme celle-ci devraient être acceptées, elles répondent à la question. Bien sûr, donnez une "meilleure solution" mais répondez également à la question, puis lorsque les gens la trouveront, ils obtiendront la réponse qu'ils veulent!
tim.baker
Cela ne fonctionne pas pour moi, j'utilise Google Chrome 47.0. Est-ce parce que la réponse est dépassée?
MeV
Pourriez-vous être plus précis sur la partie qui ne fonctionne pas? J'ai donné plusieurs réponses possibles, donc si une partie ne fonctionne pas, je peux développer davantage pour donner une réponse meilleure et plus à jour.
cr0ybot
pour une raison peu claire, le réglage a background-size: autorésolu mon problème sur toutes les orientations des appareils.
n__o
17

Essaye ça

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

Version simplifiée

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

Vous pouvez utiliser la propriété CSS background-sizeet la définir sur coverou contain, selon vos préférences. La couverture couvrira entièrement la fenêtre, tandis que contenir fera en sorte qu'un côté s'adapte à la fenêtre, ne couvrant ainsi pas toute la page (à moins que le rapport hauteur / largeur de l'écran ne soit égal à l'image).

Veuillez noter qu'il s'agit d'une propriété CSS3. Dans les anciens navigateurs, cette propriété est ignorée. Vous pouvez également utiliser javascript pour modifier les paramètres CSS en fonction de la taille de la fenêtre, mais ce n'est pas préférable.

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

Utilisez simplement une image d'arrière-plan à deux couleurs:

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

Nous sommes en 2017 et vous pouvez maintenant utiliser la fonction object-fit qui a un support décent . Il fonctionne de la même manière qu'un div background-sizemais sur l'élément lui-même, et sur tout élément comprenant des images.

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