Créer un effet Polaroid sur nos images en CSS

post-thumb

Vous souhaitez afficher vos photos de manières originales sur votre site internet ? Voyons ensemble comment réaliser cet effet polaroid entièrement en HTML / CSS !

La structure HTML

Pour commencer, je vous propose de voir comment nous allons architecturer notre fichier HTML :

Schéma architecture du polaroid

Voyons un peu ce que nous avons là…

Si nous devions retranscrire notre Polaroid sous forme d’éléments HTML, voici ce que cela donnerait :

  • Notre Polaroid est un élément <article>.
  • Il contient un élément <header> et un titre de niveau 2 <h2>.
  • Dans notre élément <header> nous retrouvons notre image <img>.
  • Le tout est contenu dans un élément parent <main>.

Une fois mis sous forme HTML, nous nous retrouvons avec ce code :

<body>
	<main>
		<article>
			<header>
				<img src="./public/img/alastor.jpg" alt="Alastor" />
			</header>
			<h2>Alastor</h2>
		</article>
		<article>
			<header>
				<img src="./public/img/husk.jpg" alt="Husk" />
			</header>
			<h2>Husk</h2>
		</article>
	</main>
</body>

Pour l’exemple ici, j’ai décidé d’ajouter deux Polaroids, mais libre à vous d’en ajouter autant que vous le souhaitez !

Passons au style !

Après avoir réalisé toute notre architecture HTML, passons ce qui va nous permettre de donner vie à nos Polaroids : le style !

La bonne pratique : le reset CSS

Avant de nous attaquer au style, je vous recommande de “réinitialiser” votre CSS (reset CSS).

Pourquoi me diriez-vous ? Eh bien cela va nous permettre de retirer les règles de stylisation présentes de base sur notre navigateur. L’intérêt de faire ça, est de faciliter grandement l’intégration de nos éléments et de s’assurer qu’ils s’afficheront tous de la même manière sur n’importe quel navigateur.

Voici le reset CSS que j’utilise personnellement sur chacun de mes projets et que j’adapte selon mes besoins :

*,
::before,
::after {
	padding: 0;
	margin: 0;
	box-sizing: border-box;
}

Le sélecteur étoile (*) permet de cibler l’ensemble des éléments présent dans notre HTML.

À noter ici que les pseudo éléments ::before et ::after ne sont pas nécessaires dans ce projet, du fait que nous n’allons pas les utiliser

Stylisons nos Polaroids

Pour comprendre l’ensemble des règles de style que nous allons appliquer ici, je vous met à disposition un schéma avec les différentes mesures :

Schéma dimension polaroid

Commençons avec notre balise <article> :

article {
	width: 300px;
	padding: 25px;
	background-color: #fbfcfc;
	box-shadow: rgba(0, 0, 0, 0.1) 0px 4px 12px;

	display: flex;
	align-items: center;
	flex-direction: column;
}

Nous ne définissons pas de hauteur à notre élément ?

La réponse est non, elle va être définie par notre image ainsi que son titre.

Nous utilisons Flexbox pour centrer nos éléments beaucoup plus facilement et rapidement.

En attendant l’arrivée de notre article dédié à ce dernier, vous pouvez retrouver plus d’informations illustrées sur le site cssreference.io

Et pour finir, j’ajoute une petite ombre portée avec la propriété box-shadow.

Passons au <header> ainsi qu’à l’image <img> présente à l’intérieur :

header {
	width: 100%;
}

header img{
	width: 100%;
	aspect-ratio: 1/1;
	object-fit: cover;
	object-position: center;
}
  • Nous avons appliqué une largeur de 100% (width: 100%) au <header>, il va donc prendre toute la largeur disponible soit 300px - (25px x 2) = 250px. Les 50px de soustraits sont dus au padding à gauche et à droite appliqué sur l’élément parent <article>.

  • Nous demandons également à notre image de prendre toute la largeur disponible.

  • D’avoir un ratio de 1:1 qui équivaut à un format carré (aspect-ratio: 1/1).

  • De s’adapter en conséquence sur la largeur et sur la hauteur (object-fit: cover) puis de se centrer sur elle-même (object-position: center).

La propriété object-fit permet de définir la façon dont un élément doit s’adapter à son conteneur en utilisant sa largeur et sa hauteur.

Plus d’informations sur la propriété object-fit ici

Schéma de démonstration de la propriété object-fit

La propriété object-position permet de définir l’alignement d’un élément au sein de son conteneur.

Plus d’informations sur la propriété object-position ici

Schéma de démonstration de la propriété object-position

Passons au style de notre titre :

article h2{
	margin-top: 10px;
	font-size: 1.75rem;
	font-family: "Shadows Into Light", cursive;
}

La police d’écriture utilisée ici est Shadows Into Light disponible gratuitement sur Google Fonts.

Pour rendre accessible cette police sur notre site, il ne faut pas oublier de l’importer dans notre fichier CSS :

@import url("https://fonts.googleapis.com/css2?family=Shadows+Into+Light&display=swap");

Positionnons nos Polaroids

Nos Polaroids sont maintenant stylisés, passons sans plus tarder à leur positionnement.

Pour commencer, ajoutons les propriétés position sur nos éléments :

main{
	position: relative;
}

article{
	// ... 
	position: absolute;
}

Ici, nous avons défini les règles suivantes :

  • Nous demandons à nos éléments <article> de se positionner par rapport à son élément parent positionné le plus proche (position: absolute).
  • Nous positionnons notre élément <main> sur le flux actuel (position: relative). Il devient alors l’élément parent positionné le plus proche de nos éléments <article>.

Voici deux schémas qui montrent l’importance de définir une position sur l’élément parent :

Schéma de démonstration de la propriété object-position sans relative Schéma de démonstration de la propriété position avec relative

Pour faire simple, ici, nous demandons à notre élément .orange de se positionner uniquement par rapport à notre élément .bleu.

Une fois ceci fait, j’en profite pour donner une hauteur à mon élément <main>. Ici, je vais lui demander de prendre la hauteur totale de l’écran du navigateur de l’utilisateur :

main{
	// ...
	height: 100vh;
}

Ceci est possible grâce aux unités Viewport : Ici 100vh représente 100% de la hauteur de la fenêtre du navigateur.

Nous avons également la même chose avec la largeur : l’unité vw.

Maintenant, voyons comment nous allons placer nos Polaroids sur notre page :

Je vais utiliser les pseudo classes :first-child - :nth-child(nombre) - :last-child qui permettent de cibler un élément spécifique selon son ordre dans la page.

  • :first-child permets de cibler le premier élément.
  • :last-child permets de cibler le dernier élément.
  • :nth-child(nombre) permets de cibler un élément en lui précisant un nombre faisant référence à son emplacement.
article:first-child{
	top: 40%;
	left: 43%;
}

article:last-child{
	top: 55%;
	left: 58%;
}

Ici, je définis leur emplacement avec les propriétés top et left.

  • top: 40% signifie : place-toi à 40% par rapport au haut de l’élément.
  • left: 43% signifie : place-toi à 43% par rapport à la gauche de l’élément.

Il faut savoir que lorsque l’on déplace nos éléments, ces derniers se déplacent par rapport à leur point le plus haut à gauche.

Ici, ce n’est pas ce que nous souhaitons, voyons alors comment faire en sorte qu’ils se déplacent par rapport au point le plus au centre :

article:first-child{
	// ...
	transform: translate(-50%, -50%);
}

article:last-child{
	// ...
	transform: translate(-50%, -50%);
}

Cela est possible grâce à la propriété transform et à la fonction translate(). Ici, nous demandons à nos éléments de se décaler de -50% par rapport à eux même vers la gauche et vers le haut.

Schéma de démonstration de la propriété transform

Profitons d’être sur la propriété transform pour appliquer une rotation sur nos Polaroids avec la fonction rotate() :

article:first-child{
	// ...
	transform: translate(-50%, -50%) rotate(-5deg);
}

article:last-child{
	// ...
	transform: translate(-50%, -50%) rotate(5deg);
}

Voyons maintenant comment faire pour réarranger l’ordre de superposition de nos éléments :

Il faut utiliser la propriété z-index, à première vue, elle peut paraître un peu complexe, mais je vous rassure, c’est beaucoup plus simple que ce qu’il n’y paraît.

Le z-index va prendre un nombre en tant que valeur. Ce nombre correspond à l’ordre de superposition de notre élément. Plus ce dernier sera élevé, plus notre élément sera placé haut dans l’ordre.

Je vous ai fait un petit schéma pour vous aider à mieux comprendre comment cela fonctionne :

Schéma de démonstration de la propriété z-index
  • Le bloc rouge à un z-index supérieur au bloc vert (2 > 1), il est donc placé devant ce dernier.
  • Le bloc rouge à un z-index inférieur au bloc bleu (2 < 3), il est donc placé derrière ce dernier.
  • Le bloc bleu à un z-index supérieur au bloc vert (3 > 1), il est donc placé devant ce dernier.

Une fois ceci compris, appliquons ça dans notre code :

article:first-child{
	// ...
	z-index: 10;
}

article:last-child{
	// ...
	z-index: 100;
}

Ici, rien n’a bougé, le premier élément était déjà derrière le dernier élément par défaut, mais si vous le souhaitez, vous pouvez faire l’inverse et les réaranger à votre guise.

Animons nos Polaroids au survol !

On a presque terminé ! Il ne nous reste que la petite transition lors du survol de la souris sur les Polaroids. Et tout ça va être possible avec la pseudo classe :hover qui nous permet de définir des règles de style lors du survol. C’est exactement ce qu’il nous faut !

Pour commencer, j’aimerais qu’au survol, mon Polaroid passe devant tout les autres. Ajoutons un z-index plus conséquent :

article:hover{
	z-index: 1000;
}

Ensuite, j’aimerais que sa rotation redevienne normale. Faisons ça avec la propriété transform :

article:hover{
	// ...
	transform: translate(-50%, -50%) rotate(0deg);
}

À noter ici qu’il faut garder la fonction translate(-50%, -50%), car sinon elle ne sera plus prise en compte lors du survol.

Ajoutons une ombre un peu plus prononcée :

article:hover{
	// ...
	box-shadow: rgba(0, 0, 0, 0.2) 0px 12px 28px 0px, 
				rgba(0, 0, 0, 0.1) 0px 2px 4px 0px,
				rgba(255, 255, 255, 0.05) 0px 0px 0px 1px inset;
}

Ok ok, on a mis toutes les règles que l’on souhaite lors du survol, mais la transition est nette… Comment faire pour réaliser une transition fluide et progressive ?

C’est ici que la propriété transition rentre en jeu ! Cette dernière va nous permettre, comme son nom l’indique, de réaliser une transition sur nos éléments.

Elle prend en paramètre 3 valeurs :

  • La propriété dans lequel nous souhaitons faire la transition.
  • Le temps de la transition
  • Le type de transition

De mon côté, je souhaite que toutes les propriétés de mon élément se voit recevoir une transition (all), que cela dure 0.1 seconde et que la transition sois lente au début, rapide puis lente à la fin pour donner un effet de tirage de carte.

article{
	// ...
	transition: all 0.1s ease-in-out;
}

Retrouvez plus d’informations illustrées sur la propriété transition sur cssreference.io

Et pour terminer, je souhaite que le curseur de ma souris devienne une main de sélection sur mes Polaroids. J’utilise donc la propriété cursor avec comme valeur pointer :

article{
	// ...
	cursor: pointer;
}

Et voici ce qui clôture cet article, j’espère qu’il vous a plus tout autant que le projet mis en avant avec celui-ci.

N’hésitez pas à aller faire un tour sur notre site, voir les autres articles ou même de rejoindre notre communauté sur Discord !

À très bientôt ! :D

Tu pourrais aussi aimer