Dans la famille je veux apprendre à coder des sites, je demande le premier article. Comme tout projet qui commence mal, je n’ai aucune idée de ce vers quoi je veux aller. Par contre, je sais que je n’ai pas des masses de connaissances, je vais donc commencer par agrandir ces dernières.

L’approche est simple: si je tombe sur un site qui me plaît et que je vois quelque chose que je ne sais pas faire, je le décortique, le comprends et l’apprends afin de pouvoir le réutiliser ailleurs. Aujourd’hui, je m’intéresse aux images de fond dans les pages web.

De ce que je comprends, il y a deux grandes façons d’afficher des images dans une page web:

  1. En HTML avec la balise <img src="path"/>,
  2. En CSS avec la propriété background-image.

Je vais commencer par jeter un œil aux deux approches.

HTML <img>

En parcourant la référence sur la balise img je constate rapidement qu’elle ne contient qu’un seul attribut obligatoire: src. Cet attribut contient le chemin vers l’image que l’on désire afficher. Autrement dit, <img src="/favicon.png"> devrait afficher l’image favicon.png disponible à la racine de ce site.


<img
src="/favicon.png"
alt="favicon example"
style="
    display: block;
    margin-left: auto;
    margin-right: auto;
">

favicon example


#Success 👌

L’image ci-dessus est certes affichée mais aussi centrée. Il est nécessaire d’ajouter un peu de CSS pour cela, rien de folichon.

  1. Afficher l’image comme un block afin qu’elle soit séparée du texte avant et après.
  2. Régler les marges à gauche et à droite sur auto pour que le navigateur égalise les espaces de chaque côté de l’image.

CSS

En CSS rien d’aussi direct. L’image n’est pas référencée dans le code HTML dans le sens où elle n’est pas intégrée au DOM. À la place, elle vient remplir le fond d’une balise comme détaillé dans la référence de la propriété background-image.

background-image


<div style="background-image: url('/favicon.png');"></div>

#Failure 👎

Enfin, est-ce vraiment un échec? L’image n’est pas visible, certes. Mais le code fonctionne parfaitement: il y a une image affichée sous le contenu d’une balise div vide. Il est donc parfaitement normal qu’elle ne soit pas visible, elle n’a rien à recouvrir.


<div style="
    background-image: url('/favicon.png');
    width: 50%;
    height: 40vh;
    margin-left: auto;
    margin-right: auto;
"></div>

#Success 👌

Les dimensions sont désormais fixées: la largeur vaut la moitié de l’espace attribuée au texte, la hauteur vaut 40% de la hauteur de l’écran et la même astuce que pour l’image en HTML a été utilisée pour le centrage.

background-repeat

Par défaut, une image intégrée via la propriété CSS background-image est répétée, horizontalement et verticalement. Une seconde propriété, background-repeat dont on peut trouver la référence ici permet de contrôler ce comportement.


<div style="
    background-image: url('/favicon.png');
    background-color: purple;
    background-repeat: no-repeat;
    width: 50%;
    height: 40vh;
    margin-left: auto;
    margin-right: auto;
"></div>

#Success 👌

Dans l’exemple précédent, je désactive la répétition de l’image et j’ajoute un fond violet pour mettre en évidence le fait que les dimensions ne changent pas, seule le comportement de l’image de fond est altéré.

background-size

Une autre façon de traiter le comportement des images de fond est proposée par la propriété background-size dont on peut trouver la référence ici. Cette propriété accepte au moins un argument correspondant à la largeur de l’image. Un second argument, facultatif, indique la hauteur recherchée.


<div style="
    background-image: url('/favicon.png');
    background-size: 100% 100%;
    width: 50%;
    height: 40vh;
    margin-left: auto;
    margin-right: auto;
"></div>

Dans l’exemple ci-dessus, background-size: 100% 100% demande à étirer l’image de manière à ce qu’elle couvre la totalité de la balise <div>.

Elle dispose aussi de deux mots-clés contain et cover. Le premier, contain affichera l’image complète sur un axe et la répètera sur l’autre axe. Ainsi, l’image est toujours visible en entier au moins une fois et se répète si nécessaire horizontalement ou verticalement. Le second cover affichera l’intégralité d’une des deux dimensions de l’image et cachera l’autre dimension.


<div style="width: 100%; height: 40vh; display: grid; grid-template-columns: 1fr 1fr; gap: 2vw">
<div style="background-image: url('/favicon.png'); background-size: contain; width: 100%; height: 100%; resize: both; overflow: scroll; grid-column: 1"></div>
<div style="background-image: url('/favicon.png'); background-size: cover;   width: 100%; height: 100%; resize: both; overflow: scroll; grid-column: 2"></div>
</div>

Dans l’exemple précédent, les deux mots-clés contain et cover sont illustrés et il est possible de manipuler les dimensions à la souris pour bien saisir la différence entre les deux.

Assemblage

Il est temps d’assembler un peu tout ça en un tout cohérent. Comme dit au début de cette page, le but était de copier m’inspirer d’une page et de comprendre comment tout ou une partie fonctionnait. Je me suis ici intéressé à la première partie de cette page: je voulais savoir comment étaient placées les différentes images de fond.


<div style="
    width: 100%;
    height: 40vh;
    background-color: #d99962;
    background-repeat: no-repeat;
    background-image: url('woman.svg'), url('leaf.svg');
    background-position: left, right;
    display: flex;
    justify-content: center;
    align-items: center;
">
<img src="logo.svg" alt="logo example" style="width: 17%;" />
</div>
logo example

À défaut de texte comme sur la page d’origine, j’ai placé une simple image avec la balise <img> au centre d’une balise <div> plus compliquée. La balise <div> voit ses dimensions fixées et a un fond indiqué par la propriété CSS background-color. Je désactive la répétition des images de fond via background-re[eat: no-repeat comme vu précédemment puis je définis non pas une mais deux images de fond. J’utilise ensuite la propriété CSS background-position dont la référence explique comment spécifier les positions d’autant d’images que nécessaire. Les trois dernières propriétés servent à centrer horizontalement et verticalement l’image contenue via la balise <img>.

Amélioration

Si je devais utiliser cette technique sur un véritable site et pas simplement dans une page de blog, j’ajouterai des media queries afin de n’afficher les deux images de fond que si la place disponible était suffisante. Autrement dit, je n’afficherais que l’une ou l’autre sur un écran de petite taille. Il n’est pas possible d’utiliser des media queries dans le CSS inline donc pas de démonstration pour cela.

Bonus

Toujours sur cette même page il reste une dernière petite surprise. Vers le milieu de la page se trouve une citation sur fond de ciel par nuit sombre: bleu nuit avec d’innombrables étoiles. Alors que le texte se déplace verticalement sur la page, le fond quant à lui reste immobile.


<div style="
    width: 100%;
    height: 40vh;
    background-color: #242426;
    background-image: url('stars.svg');
    background-attachment: fixed;
    margin-left: auto;
    margin-right: auto;
    display: flex;
    justify-content: center;
    align-items: center;
">
<figure style="color: white;">
<blockquote cite="https://en.wikipedia.org/wiki/Quis_custodiet_ipsos_custodes%3F" style="font-family: serif; font-size: 200%; font-weight: bold;">Quis custodiet ipsos custodes?</blockquote>
<figcaption style="text-align: right;">Juvenal – Circa 100 AD</figcaption>
</figure>
</div>
Quis custodiet ipsos custodes?
Juvenal – Circa 100 AD

La propriété CSS background-attachment agit décrite ici sur le comportement des images de fond. La valeur fixed permet de fixer l’image de fond au view-port et pas à la balise courante.

Conclusion

Il reste quelques propriétés CSS que je n’ai pas abordés mais autant garder les liens pour le futur: background-clip et background-blend-mode.

J’ai l’impression de revenir au collège quand je découvrais les joies du HTML/CSS via le site du zéro en grappillant quelques octets de connaissances via le modem 56k de la famille. J’ai appris bien plus que ce que j’avais prévu avec une simple question et je suis bien content de me coucher moins ignorant ce soir.