Une plongée profonde dans l'ajustement d'objet et la taille d'arrière-plan en CSS
Publié: 2022-03-10object-fit
et background-size
, quand nous pouvons les utiliser et pourquoi, ainsi que des cas d'utilisation pratiques et des recommandations. Plongeons dedans. Nous ne sommes pas toujours en mesure de charger des images de tailles différentes pour un élément HTML. Si nous utilisons une largeur et une hauteur qui ne sont pas proportionnelles au format de l'image, l'image peut être compressée ou étirée. Ce n'est pas bon, et cela peut être résolu soit avec object-fit
pour un élément img
, soit en utilisant background-size
.
Tout d'abord, définissons le problème. Considérez la figure suivante :
Pourquoi cela arrive-t-il?
Une image aura un rapport d'aspect, et le navigateur remplira la boîte contenant cette image. Si le rapport d'aspect de l'image est différent de la largeur et de la hauteur spécifiées pour celle-ci, le résultat sera une image comprimée ou étirée.
Nous le voyons sur la figure suivante :
La solution
Nous n'avons pas toujours besoin d'ajouter une image de taille différente lorsque le rapport d'aspect de l'image ne s'aligne pas sur la largeur et la hauteur de l'élément contenant. Avant de plonger dans les solutions CSS, je veux vous montrer comment nous faisions cela dans les applications de retouche photo :
Maintenant que nous comprenons comment cela fonctionne, voyons comment cela fonctionne dans le navigateur. ( Alerte spoiler : c'est plus facile ! )
object-fit
CSS
La propriété object-fit
définit comment le contenu d'un élément remplacé tel que img
ou video
doit être redimensionné pour s'adapter à son conteneur. La valeur par défaut pour object-fit
est fill
, ce qui peut entraîner la compression ou l'étirement d'une image.
Passons en revue les valeurs possibles.
Valeurs possibles pour object-fit
object-fit: contain
Dans ce cas, l'image sera redimensionnée pour s'adapter au format de son conteneur. Si le rapport d'aspect de l'image ne correspond pas à celui du conteneur, il sera mis en boîte aux lettres.
object-fit: cover
Ici, l'image sera également redimensionnée pour s'adapter au rapport d'aspect de son conteneur, et si le rapport d'aspect de l'image ne correspond pas à celui du conteneur, alors elle sera coupée pour s'adapter.
object-fit: fill
Avec cela, l'image sera redimensionnée pour s'adapter au rapport d'aspect de son conteneur, et si le rapport d'aspect de l'image ne correspond pas à celui du conteneur, elle sera soit comprimée, soit étirée. Nous ne voulons pas cela.
object-fit: none
Dans ce cas, l'image ne sera pas du tout redimensionnée, ni étirée ni comprimée. Elle fonctionne comme la valeur de cover
, mais elle ne respecte pas les proportions de son conteneur.
Outre object-fit
, nous avons également la propriété object-position
, qui est responsable du positionnement d'une image dans son conteneur.
Valeurs possibles pour object-position
La propriété object-position
fonctionne de la même manière que la propriété background-position
de CSS :
Les mots-clés du top
et du bottom
fonctionnent également lorsque le rapport d'aspect de la boîte contenante est verticalement plus grand :
background-size
CSS
Avec background-size
, la première différence est que nous avons affaire à l'arrière-plan, pas à un élément HTML ( img
).
Valeurs possibles pour background-size
Les valeurs possibles pour background-size
sont auto
, contain
et cover
.
background-size: auto
Avec auto
, l'image restera à sa taille par défaut :
background-size: cover
Ici, l'image sera redimensionnée pour tenir dans le conteneur. Si les rapports d'aspect ne sont pas les mêmes, l'image sera masquée pour s'adapter.
background-size: contain
Dans ce cas, l'image sera redimensionnée pour tenir dans le conteneur. Si les rapports d'aspect sont désactivés, l'image sera en format letterbox comme indiqué dans l'exemple suivant :
Quant à background-position
, il est similaire au fonctionnement d' object-position
. La seule différence est que la position par défaut de object-position
est différente de celle de background-position
.
Quand ne pas utiliser object-fit
ou background-size
Si l'élément ou l'image a une hauteur fixe et que background-size: cover
ou object-fit: cover
lui est appliqué, il y aura un point où l'image sera trop large, perdant ainsi des détails importants qui pourraient affecter la façon dont l'utilisateur perçoit l'image.
Prenons l'exemple suivant dans lequel l'image se voit attribuer une hauteur fixe :
.card__thumb { height: 220px; }
Si le conteneur de la carte est trop large, cela se traduira par ce que nous voyons à droite (une image trop large). C'est parce que nous ne spécifions pas de rapport d'aspect.
Il n'y a qu'un des deux correctifs pour cela. La première consiste à utiliser le padding hack pour créer un rapport intrinsèque.
.card__thumb { position: relative; padding-bottom: 75%; height: 0; } .card__thumb img { position: absolute; left: 0; top: 0; width: 100%; height: 100%; object-fit: cover; }
La deuxième solution consiste à utiliser la nouvelle propriété CSS aspect-ratio
. En l'utilisant, nous pouvons faire ce qui suit :
.card__thumb img { aspect-ratio: 4 / 3; }
Remarque : J'ai déjà écrit en détail sur la propriété de aspect-ratio
au cas où vous voudriez en savoir plus : "Apprenons à propos du rapport d'aspect en CSS".
Cas d'utilisation et exemples
Avatars d'utilisateurs
Un cas d'utilisation parfait pour object-fit: cover
est constituée d'avatars d'utilisateurs. Le format d'image autorisé pour un avatar est souvent carré. Placer une image dans un conteneur carré pourrait déformer l'image.
.c-avatar { object-fit: cover; }
Liste des logos
La liste des clients d'une entreprise est importante. Nous utiliserons souvent des logos à cette fin. Parce que les logos auront des tailles différentes, nous avons besoin d'un moyen de les redimensionner sans les déformer.
Heureusement, object-fit: contain
est une bonne solution pour cela.
.logo__img { width: 150px; height: 80px; object-fit: contain; }
Vignette de l'article
C'est un cas d'utilisation très courant. Le conteneur d'une vignette d'article peut ne pas toujours avoir une image avec le même rapport d'aspect. Ce problème devrait être résolu par le système de gestion de contenu (CMS) en premier lieu, mais ce n'est pas toujours le cas.
.article__thumb { object-fit: cover; }
Fond de héros
Dans ce cas d'utilisation, la décision d'utiliser un élément img
ou un arrière-plan CSS dépendra des éléments suivants :
- L'image est-elle importante ? Si CSS est désactivé pour une raison quelconque, voudrions-nous que l'utilisateur voie l'image ?
- Ou le but de l'image est-il simplement décoratif ?
En fonction de notre réponse, nous pouvons décider quelle fonctionnalité utiliser. Si l'image est importante :
<section class="hero"> <img class="hero__thumb" src="thumb.jpg" alt="" /> </section>
.hero { position: relative; } .hero__thumb { position: absolute; left: 0; top: 0; width: 100%; height: 100%; object-fit: cover; }
Si l'image est décorative , nous pouvons utiliser background-image
:
.hero { position: relative; background-image: linear-gradient(to top, #a34242, rgba(0,0,0,0), url("thumb.jpg"); background-repeat: no-repeat; background-size: cover; }
Le CSS est plus court dans ce cas. Assurez-vous que tout texte placé sur l'image est lisible et accessible.
Ajouter un arrière-plan à une image avec object-fit: contain
Saviez-vous que vous pouvez ajouter une couleur de fond à img
? Nous en tirerions profit si nous utilisions également object-fit: contain
.
Dans l'exemple ci-dessous, nous avons une grille d'images. Lorsque les proportions de l'image et du conteneur sont différentes, la couleur d'arrière-plan apparaît.
img { object-fit: contain; background-color: #def4fd; }
Élément vidéo
Avez-vous déjà eu besoin d'une video
en arrière-plan ? Si tel est le cas, vous vouliez probablement qu'il occupe toute la largeur et la hauteur de son parent.
.hero { position: relative; background-color: #def4fd; } .hero__video { position: aboslute; left: 0; top: 0; width: 100%; height: 100%; }
Pour qu'il couvre entièrement la largeur et la hauteur de son parent, nous devons remplacer la valeur object-fit
par défaut :
.hero__video { /* other styles */ object-fit: cover; }
Conclusion
Comme nous l'avons vu, l' object-fit
et background-size
sont très utiles pour gérer différents formats d'image. Nous n'aurons pas toujours le contrôle sur la définition des dimensions parfaites pour chaque image, et c'est là que ces deux fonctionnalités CSS brillent.
Un rappel amical sur les implications pour l'accessibilité du choix entre un élément img
et un arrière-plan CSS : si l'image est purement décorative, optez pour un arrière-plan CSS. Sinon, un img
est plus approprié.
J'espère que vous avez trouvé cet article utile. Merci pour la lecture.