Aujourd’hui, nous allons mettre un peu de côté le PHP et la logique de notre architecture MVC pour nous concentrer sur la mise en page. Ce jour 19 sera dédié à deux éléments clés de l’interface d’un site : le header et le footer.
Ce sont souvent les premières et les dernières choses qu’un visiteur voit sur un site web. Leur rôle est donc essentiel, à la fois pour l’ergonomie, l’identité du site et la navigation.
Notre objectif n’est pas de créer quelque chose de « beau » pour impressionner, mais plutôt un design clair, minimaliste et agréable à utiliser. Un bon design, ce n’est pas celui qui en met plein la vue, mais celui qui se fait oublier tellement il est intuitif. Nous allons donc construire un en-tête simple, avec un menu responsive, qui s’adapte aux petits écrans, ainsi qu’un pied de page qui donne des repères et des informations utiles.
Nous allons prendre le temps de bien réfléchir à ce que nous mettons dans notre en-tête, aux liens de navigation, à leur position, à leur comportement sur mobile. Puis, nous ajouterons un footer cohérent, sobre et fonctionnel. Cette mise en page sera intégrée à notre structure MVC, comme toujours, pour qu’elle soit réutilisable facilement sur toutes les pages du site.
Cela nous permettra aussi d’améliorer l’expérience utilisateur, car un bon header et un bon footer facilitent la compréhension et la navigation. Pas besoin de décorations inutiles, ce qui compte, c’est l’efficacité, la lisibilité, et la cohérence.
- Pourquoi commencer par le header et le footer ?
- Le design minimaliste : principes et objectifs
- Le reset CSS : pourquoi et comment l'utiliser ?
- Implémenter nos polices Google Fonts dans notre site web
- Implémenter les couleurs et la typographie à notre feuille de styles
- Créer notre banque d'icônes
- Coder le header : HTML simple et clair
- Coder le footer : utile, cohérent, discret
- Tester l’affichage sur desktop, mobile et tablette
Pourquoi commencer par le header et le footer ?
Quand on crée un site web, il peut être tentant de commencer par le contenu principal ou les fonctionnalités les plus visibles. Mais en réalité, il est souvent plus logique de poser d’abord les bases de notre interface : le header (l’en-tête) et le footer (le pied de page). Ces deux zones encadrent toutes les pages de notre site. Elles sont visibles en permanence, ou presque, et leur rôle est bien plus important qu’il n’y paraît.
En commençant par le header et le footer, nous définissons un cadre de navigation commun. Ce cadre, une fois en place, nous permet ensuite de créer nos autres pages plus facilement, avec une structure déjà claire et cohérente. C’est un peu comme construire une maison : avant d’aménager chaque pièce, nous posons les murs porteurs, les ouvertures, les fondations. Ici, le header et le footer font partie de ces fondations visuelles.
Le header est la première chose que la majorité des visiteurs voit. Il contient souvent le logo, le nom du site et le menu de navigation. Grâce à lui, on comprend rapidement où l’on se trouve et comment accéder aux différentes parties du site. C’est donc un point de repère très important. Si ce header est mal conçu, l’utilisateur peut se perdre ou, pire, quitter le site sans chercher plus loin.
Le footer, lui, est en bas de page. Il peut paraître secondaire, mais il joue un rôle essentiel pour donner des informations complémentaires : des liens utiles, des mentions légales, un lien vers la page de contact… Parfois, les utilisateurs scrollent jusqu’en bas pour chercher justement ce genre de détails. Si le footer est vide ou mal pensé, cela donne une impression d’inachevé.
En créant ces deux éléments dès le départ, nous faisons aussi un choix stratégique : celui de penser notre site comme un tout cohérent. Le design que nous allons poser ici va se retrouver sur toutes les pages. Il doit donc être simple, clair, facile à utiliser, et adaptable sur tous les écrans. En le faisant maintenant, nous évitons de devoir tout reprendre plus tard.
Puisque notre site web, Créa-code, utilise une structure MVC, nous allons majoritairement intervenir sur le fichier de app/Views/partials/header.php, le fichier app/Views/partials/footer.php, qui sont inclus dans toutes nos vues. Cela nous fera gagner du temps, et cela garantira que notre interface reste toujours uniforme.
Nous commençons par le header et le footer pour poser les fondations de l’interface utilisateur, faciliter la navigation, améliorer la cohérence du site et gagner du temps pour la suite. C’est une étape essentielle, même si elle ne contient pas encore de grandes fonctionnalités. Nous construisons ici le squelette de l’expérience utilisateur, celui que les visiteurs ressentiront dès leurs premières secondes sur notre site.
Le design minimaliste : principes et objectifs
Avant de commencer à écrire une seule ligne de code, nous allons reprendre nos travaux sur le design de notre site web(Jour 07 : Typographie et identité visuelle et Jour 11 : Maquette du site). Et plus précisément le design minimaliste. Mais qu’est-ce que ça veut dire exactement ? Et pourquoi faire ce choix ?
Un design minimaliste, c’est un design simple, sans trop d’éléments visuels, sans décorations inutiles, sans effets qui détournent l’attention. Ce n’est pas un design vide ou triste, c’est un design qui va droit à l’essentiel. Nous avons choisit ce style car notre but n’est pas d’impressionner, mais de guider l’utilisateur. Nous voulons qu’il comprenne rapidement où il est, où cliquer, comment revenir en arrière, comment se connecter ou s’inscrire, sans réfléchir pendant des heures. Bref, le rendre accessible à tous.
Dans ce type de design, chaque élément est pensé pour une raison précise. Si quelque chose n’est pas utile ou ne sert pas à améliorer la compréhension, nous ne le mettons pas. Par exemple, un bouton doit être visible, lisible, facile à cliquer. Il ne doit pas être entouré de dix couleurs différentes ou caché au milieu d’images. Nous allons utiliser les couleurs qui nous avons sélectionné avec beaucoup d’espace autour des éléments (on appelle cela les margin et le padding) pour que tout respire et soit clair.
Nous allons aussi penser à la taille des textes, à leur lisibilité, au contraste entre le texte et l’arrière-plan. Le but est que tout soit facile à lire sur ordinateur, mais aussi sur téléphone. Un design minimaliste s’adapte très bien aux petits écrans, car il évite les complications. Moins il y a de choses à gérer, plus le résultat est fluide, rapide et agréable à utiliser.
Nous choisissons également ce style pour une autre raison : il est plus facile à maintenir. Si, plus tard, nous voulons changer une couleur ou déplacer un élément, ce sera plus simple si le design est clair et léger. En plus, cela rend notre code plus propre et plus facile à comprendre pour d’autres développeurs, ou pour nous-mêmes dans quelques semaines.
Ce design minimaliste est aussi un choix stratégique. Beaucoup de sites modernes utilisent cette approche parce qu’elle fonctionne bien. Elle rassure l’utilisateur, elle donne une impression de sérieux, de professionnalisme. Et surtout, elle met en avant le contenu. C’est le contenu qui compte, pas la décoration.
Alors, notre objectif est clair : créer une interface simple, lisible, agréable, sans surcharge. Nous allons coder un header et un footer qui suivent ces principes, avec une navigation évidente, une bonne hiérarchie visuelle, et des choix logiques. Ce sera la base de tout le reste de notre site. Et même si nous ajoutons plus tard des effets ou des éléments plus complexes, nous partirons toujours de cette base simple et solide.
Le design minimaliste est un design réfléchi. Il ne s’agit pas de faire moins pour aller plus vite, mais de faire mieux avec moins. Nous allons apprendre à choisir chaque détail avec soin, pour que l’ensemble soit clair, léger et vraiment utile.
Le reset CSS : pourquoi et comment l’utiliser ?
Avant même de commencer à styliser notre header ou notre footer, nous devons préparer une base propre. Et pour cela, nous allons utiliser ce qu’on appelle un reset CSS. C’est une étape que beaucoup de développeurs font au tout début d’un projet, car elle permet de repartir sur une base neutre, identique sur tous les navigateurs.
Mais pourquoi faut-il faire cela ? Parce que tous les navigateurs (comme Chrome, Firefox, Safari…) ont leurs propres styles par défaut. Par exemple, un titre <h1>
peut apparaître plus gros dans Firefox que dans Chrome. Un paragraphe peut avoir plus d’espace en haut ou en bas selon le navigateur. Et ces petites différences peuvent vite rendre notre site désorganisé ou moche, surtout quand on veut créer quelque chose de propre et cohérent.
Avec un reset CSS, nous allons donc enlever ou réinitialiser tous ces styles par défaut. Cela ne veut pas dire supprimer tout le style, mais plutôt partir de zéro. C’est comme si nous effacions le tableau avant de commencer à dessiner. Cela nous donne un meilleur contrôle sur l’apparence de chaque élément.
Nous allons maintenant écrire un code CSS de reset. Ce code devra être placé tout au début de notre fichier principal de styles : app/public/assets/css/styles.css. Il va uniformiser le rendu des éléments HTML et corriger certains comportements gênants. Voici le code que nous allons utiliser :
/* reset.css */
/* On retire les marges et les paddings automatiques de tous les éléments */
* {
margin: 0;
padding: 0;
box-sizing: border-box;
}
/* On définit une hauteur minimale à 100% pour body et html pour bien gérer les hauteurs de page */
html, body {
height: 100%;
font-family: sans-serif;
line-height: 1.5;
-webkit-font-smoothing: antialiased;
-moz-osx-font-smoothing: grayscale;
}
/* On enlève les styles de listes par défaut */
ul, ol {
list-style: none;
}
/* On enlève les styles des liens bleus soulignés */
a {
text-decoration: none;
color: inherit;
}
/* On uniformise les boutons */
button {
border: none;
background: none;
font: inherit;
cursor: pointer;
}
/* On s’assure que les images ne dépassent pas leur conteneur */
img {
max-width: 100%;
display: block;
}
/* On remet les balises HTML à un comportement simple et prévisible */
h1, h2, h3, h4, h5, h6, p, figure, blockquote {
margin: 0;
padding: 0;
font-weight: normal;
}
/* On évite que les éléments comme les formulaires ou les inputs soient trop différents d’un navigateur à l’autre */
input, textarea, select {
font: inherit;
border: none;
outline: none;
background: none;
}
Prenons maintenant un moment pour comprendre ce que fait ce code :
Nous commençons par cibler tous les éléments (*
) pour leur enlever les marges (margin
) et les espacements intérieurs (padding
) ajoutés automatiquement. Sans cela, chaque navigateur ajoute ses propres valeurs, ce qui rend le rendu imprévisible.
On ajoute aussi box-sizing: border-box;
pour que les dimensions qu’on définit soient plus simples à gérer. Cela veut dire que si on dit qu’un élément fait 200 pixels de large, ce sera bien 200 pixels, y compris les bordures et les paddings.
Ensuite, nous forçons le html
et le body
à prendre toute la hauteur de la page. Cela nous servira plus tard, notamment pour créer des mises en page qui prennent toute la hauteur de l’écran, comme un footer toujours en bas. On définit aussi une police par défaut simple (sans-serif
) et une bonne hauteur de ligne (line-height: 1.5
) pour rendre le texte plus lisible. Les deux propriétés suivantes rendent le texte plus net selon le navigateur et le système d’exploitation.
Nous supprimons les puces des listes (ul
, ol
) car souvent, nous préférons créer des listes avec nos propres styles. De la même façon, nous supprimons les décorations des liens (a
) pour qu’ils n’apparaissent pas bleus et soulignés si nous ne le voulons pas. Nous allons les styliser plus tard, selon notre design.
Pour les boutons, nous retirons les styles par défaut. Certains navigateurs leur mettent un fond gris ou une bordure bleue. Ici, nous les remettons à zéro pour qu’ils ressemblent à du texte de base, et nous ajoutons cursor: pointer;
pour qu’ils réagissent comme des boutons.
Les images sont souvent problématiques si elles dépassent du conteneur. Avec max-width: 100%
, nous nous assurons qu’elles restent bien dans leur cadre, même si elles sont très grandes. Le display: block
permet aussi d’enlever l’espace blanc qui apparaît parfois sous les images.
Enfin, nous remettons à zéro les titres (h1
à h6
), les paragraphes (p
), les figures et les citations (blockquote
). Cela évite que certains éléments aient des marges différentes selon les navigateurs.
Pour finir, nous uniformisons aussi les champs de formulaire (input
, textarea
, select
) pour qu’ils utilisent la même police que le reste du site, et pour éviter des effets ou des couleurs par défaut étranges.
Grâce à ce reset CSS, nous allons pouvoir styliser notre site de manière stable, sans être surpris par des comportements différents selon le navigateur utilisé. C’est une base très simple, mais très importante. Une fois ce code en place, nous pourrons passer à la création de nos vrais styles, en sachant exactement ce que nous faisons.
Nous allons minimiser ce code pour qu’il prenne le moins de place possible. On retire donc les commentaires et les espaces inutiles. Il s’agit de même code que celui ci-dessus :
*{margin:0;padding:0;box-sizing:border-box;}html,body{height:100%;font-family:sans-serif;line-height:1.5;-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale;}ul,ol{list-style:none;}a{text-decoration:none;color:inherit;}button{border:none;background:none;font:inherit;cursor:pointer;}img{max-width:100%;display:block;}h1,h2,h3,h4,h5,h6,p,figure,blockquote{margin:0;padding:0;font-weight:normal;}input,textarea,select{font:inherit;border:none;outline:none;background:none;}
Maintenant que nous avons nettoyé notre terrain, nous pouvons commencer à construire notre design proprement.
Implémenter nos polices Google Fonts dans notre site web
Pour que notre site soit agréable à lire et qu’il ait une vraie identité visuelle, il est très important de bien choisir les polices d’écriture. Une police, ce n’est pas seulement une question de style. Elle joue un rôle essentiel dans l’expérience utilisateur. Une bonne police rend la lecture confortable, donne une certaine personnalité au site, et aide à structurer l’information.
Lors du jour 7, nous avons choisi deux polices complémentaires : Inter pour les titres, et Nunito Sans pour le texte courant. Aujourd’hui, nous allons apprendre à les ajouter correctement à notre site grâce à Google Fonts, un service gratuit et très simple à utiliser.
Pourquoi utiliser Google Fonts ?
Google Fonts est une bibliothèque en ligne qui propose des centaines de polices gratuites. Nous pouvons les parcourir, les tester, et surtout les intégrer facilement dans nos projets web. L’avantage, c’est que tout fonctionne directement dans le navigateur. Pas besoin de télécharger ou d’installer quoi que ce soit sur notre ordinateur.
L’autre avantage, c’est que les polices hébergées par Google Fonts sont optimisées pour le web. Elles sont légères, rapides à charger, et compatibles avec tous les navigateurs modernes. Elles s’afficheront correctement, que l’utilisateur soit sur Chrome, Firefox, Safari ou même sur un smartphone.
Pour ce projet, nous avons choisi d’utiliser deux familles de polices bien distinctes :
- Inter pour les titres. Elle est moderne, simple, bien adaptée aux interfaces web. Elle attire l’attention sans être trop lourde, et elle existe en plusieurs graisses (épaisseurs).
- Nunito Sans pour le texte courant. C’est une police douce, très lisible, idéale pour les paragraphes et la lecture sur écran.
Nous allons maintenant les intégrer dans notre site Créa-code.
Étape 1 : générer le lien d’importation
La première étape consiste à se rendre sur le site officiel de Google Fonts : https://fonts.google.com
Une fois sur le site, nous recherchons les deux polices que nous avons choisies : Inter et Nunito Sans. Pour chaque police, nous sélectionnons les épaisseurs dont nous avons besoin.
Pour notre projet, nous avons décidé d’utiliser :
- 400 (Regular) pour les textes courants
- 600 (Semi-Bold) pour les titres
- 700 (Bold) si besoin pour mettre certains titres ou boutons en valeur
Une fois les épaisseurs sélectionnées, Google Fonts génère automatiquement un lien spécial que nous pouvons copier. Il ressemble à ceci :
<!-- Préconnexion -->
<link rel="preconnect" href="https://fonts.googleapis.com">
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>
<!-- Lien combiné -->
<link href="https://fonts.googleapis.com/css2?family=Inter:wght@400;600;700&family=Playfair+Display:wght@400&display=swap" rel="stylesheet">
Nous allons copier ce lien et l’ajouter tout en haut, entre les balises head
de notre fichier app/Views/layout.php. Cela permettra de précharger les polices dès le début, avant même que les styles soient appliqués à nos titres et paragraphes.
Nos headers HTTP actuels bloquent Google Fonts, car style-src
est trop restrictif. Toujours dans le fichier app/Views/layout.php, nous allons adapter notre directive CSP et la remplacer par celle-ci :
header("Content-Security-Policy: default-src 'self'; script-src 'self' https://www.googletagmanager.com https://www.google-analytics.com 'unsafe-inline'; connect-src 'self' https://www.google-analytics.com https://region1.google-analytics.com; style-src 'self' https://fonts.googleapis.com; font-src https://fonts.gstatic.com;");
Étape 2 : appliquer les polices dans notre code CSS
Maintenant que les polices sont chargées depuis Google Fonts, nous allons les utiliser dans nos styles CSS. Pour cela, nous allons déclarer des variables globales avec les noms des polices, pour pouvoir les réutiliser facilement.
Voici un exemple :
:root {
--font-title: 'Inter', sans-serif;
--font-text: 'Nunito Sans', sans-serif;
}
Cela signifie que nous créons deux variables CSS. L’une pour les titres, l’autre pour les textes. Le nom exact de la police doit être écrit entre guillemets, tel qu’il apparaît sur Google Fonts. Le sans-serif
à la fin est une police de secours : si jamais Inter ou Nunito Sans ne se charge pas (problème de connexion ou de navigateur), le texte s’affichera quand même avec une police sans empattement par défaut, comme Arial.
Étape 3 : utiliser les polices sur nos éléments
Une fois les polices chargées et déclarées, il ne reste plus qu’à les appliquer aux bons éléments dans notre CSS.
Pour les paragraphes, nous utilisons Nunito Sans :
body {
font-family: var(--font-text);
font-size: 16px;
}
Ici, nous définissons la police de tout le corps de la page. Comme body
englobe tous les textes, cela signifie que tous les paragraphes utiliseront Nunito Sans par défaut, avec une taille lisible de 16 pixels.
Pour les titres, nous appliquons Inter :
h1, h2, h3, h4, h5, h6 {
font-family: var(--font-title);
font-weight: 600;
line-height: 1.2;
}
Nous utilisons une épaisseur semi-bold (600) pour que les titres ressortent sans être trop lourds.
En mettant tout cela en place, nous obtenons un site cohérent visuellement. Les titres sont modernes, nets, bien visibles grâce à la police Inter. Le texte est doux, rond, agréable à lire, grâce à Nunito Sans. Ces deux polices fonctionnent parfaitement ensemble, tout en donnant à notre site une touche professionnelle, lisible et équilibrée.
Pourquoi c’est important de faire ça dès le début
Si nous attendons la fin du projet pour appliquer la bonne typographie, nous risquons d’avoir à tout reprendre. Chaque titre, chaque bloc de texte, chaque bouton devrait alors être modifié, ce qui peut vite devenir long et confus. En ajoutant nos polices dès le départ, nous posons une base solide, claire, et surtout cohérente.
Cela nous permet aussi de garder un style harmonieux sur toutes les pages, sans devoir y penser à chaque fois. Et si un jour nous souhaitons changer de police, il suffira de modifier une seule ligne de code, grâce à nos variables CSS.
Implémenter les couleurs et la typographie à notre feuille de styles
Maintenant que nous avons une base propre grâce au reset CSS et nos police Google Fonts, nous allons enfin donner à notre site son identité visuelle. Ces choix visuels, établis lors du jour 07, sont essentiels : ils permettent à notre interface d’être cohérente, agréable à lire, et reconnaissable.
Lors du jour 11, nous avions conçu une maquette avec une ligne graphique claire. Aujourd’hui, nous allons la traduire en règles CSS. Nous allons coder les éléments fondamentaux : le fond général, le texte courant, les titres, les couleurs d’interaction (jaune et bleu), ainsi que les styles associés aux messages système (succès ou erreur).

Des formations informatique pour tous !
Débutant ou curieux ? Apprenez le développement web, le référencement, le webmarketing, la bureautique, à maîtriser vos appareils Apple et bien plus encore…
Formateur indépendant, professionnel du web depuis 2006, je vous accompagne pas à pas et en cours particulier, que vous soyez débutant ou que vous souhaitiez progresser. En visio, à votre rythme, et toujours avec pédagogie.
Découvrez mes formations Qui suis-je ?Voici le code que nous ajoutons dans notre fichier public/assets/css/styles.css :
/* Reset CSS */
*{margin:0;padding:0;box-sizing:border-box;}html,body{height:100%;font-family:sans-serif;line-height:1.5;-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale;}ul,ol{list-style:none;}a{text-decoration:none;color:inherit;}button{border:none;background:none;font:inherit;cursor:pointer;}img{max-width:100%;display:block;}h1,h2,h3,h4,h5,h6,p,figure,blockquote{margin:0;padding:0;font-weight:normal;}input,textarea,select{font:inherit;border:none;outline:none;background:none;}
/* Déclaration des variables CSS globales */
:root {
--color-bg: #FFFFFF; /* Fond principal : blanc, neutre et clair */
--color-bg-alt: #F4F4F4; /* Fond secondaire : gris clair pour les blocs alternés */
--color-text: #1E1E1E; /* Texte principal : anthracite, bonne lisibilité */
--color-text-secondary: #4A4A4A; /* Texte secondaire : gris foncé */
--color-accent-primary: #FFED13; /* Couleur d’accent : jaune vif pour attirer l’attention */
--color-accent-secondary: #0056B3; /* Accent secondaire : bleu foncé pour les interactions */
--color-success: #3CCF91; /* Vert doux : messages de succès ou progression */
--color-error: #FF4D4D; /* Rouge clair : erreurs, alertes */
--font-title: 'Inter', sans-serif;
--font-text: 'Nunito Sans', sans-serif;
}
/*************************
* *
* STYLES GÉNÉRAUX *
* *
*************************/
/* Application des polices et couleurs de base */
body {
font-family: var(--font-text);
font-size: 16px;
color: var(--color-text);
background-color: var(--color-bg);
-webkit-font-smoothing: antialiased;
-moz-osx-font-smoothing: grayscale;
padding-top: 120px;
}
/* Titres : police Inter, bonne hiérarchie visuelle */
h1, h2, h3, h4, h5, h6 {
font-family: var(--font-title);
font-weight: 600;
color: var(--color-text);
line-height: 1.2;
margin-bottom: 0.5em;
letter-spacing: -0.4px;
}
/* Tailles spécifiques pour chaque niveau de titre */
h1 { font-size: 2.25rem; } /* ~36px */
h2 { font-size: 1.875rem; } /* ~30px */
h3 { font-size: 1.5rem; } /* ~24px */
h4 { font-size: 1.25rem; } /* ~20px */
h5 { font-size: 1rem; } /* ~16px */
h6 { font-size: 0.875rem; } /* ~14px */
/* Paragraphe courant : texte noir, lisible, espacé */
p {
font-family: var(--font-text);
font-size: 1rem;
color: var(--color-text);
margin-bottom: 1.2em;
}
/* Texte secondaire : plus discret, utilisé dans les infos complémentaires */
.small, .text-secondary {
font-size: 0.9rem;
color: var(--color-text-secondary);
}
/* Liens : couleur d’accent (jaune), interaction visible au survol */
a {
color: var(--color-accent-secondary);
text-decoration: none;
transition: color 0.2s ease;
}
a:hover {
color: var(--color-text-secondary);
}
/* Boutons standards : accent jaune sur fond blanc */
button, .btn {
font-family: var(--font-title);
background-color: var(--color-accent);
color: var(--color-text);
padding: 0.6em 1.2em;
font-size: 1rem;
font-weight: 600;
border-radius: 4px;
border: none;
cursor: pointer;
transition: all 0.2s ease, color 0.2s ease;
}
button:hover {
background-color: var(--color-accent-hover);
color: #fff;
}
button svg, .btn svg {
width: 20px;
height: 20px;
vertical-align: middle;
margin-right: 0.2rem;
position: relative;
top: -1px;
}
.btn-login {
background: transparent;
color: var(--color-text-secondary);
border: 1px solid var(--color-text-secondary);
}
.btn-signin {
background: var(--color-accent-primary);
color: var(--color-text);
border: 1px solid var(--color-text-secondary);
}
.btn-signin:hover, .btn-login:hover {
background: var(--color-text-secondary);
color: var(--color-bg);
}
/* Messages système */
.alert-success {
background-color: var(--color-success);
color: var(--color-bg);
padding: 1em;
border-radius: 4px;
font-weight: 600;
}
.alert-error {
background-color: var(--color-error);
color: var(--color-bg);
padding: 1em;
border-radius: 4px;
font-weight: 600;
}
/* Sections alternées avec fond gris clair */
.section-alt {
background-color: var(--color-bg-alt);
padding: 2em;
border-radius: 8px;
}
.container {
max-width: 1300px;
margin: 0 auto;
}
Ce code sera surement ajuster au fil du développement.
Créer notre banque d’icônes
Nous allons stocker une dizaine d’icônes SVG de manière centralisée dans un fichier PHP pour pouvoir les appeler facilement dans nos vues, sans dupliquer le code.
Le dossier Helpers
est parfait pour ce genre de logique non liée à un modèle ou une vue, mais utile dans plusieurs parties de ton site :
/app
/Views
/Models
/Controllers
/Helpers
IconHelper.php
Nous pouvons maintenant créer un fichier PHP contenant toutes les icônes (en version inline SVG), sous forme de fonctions ou tableau associatif. Il sera dans le dossier app/Helpers/.
Pourquoi choisir des SVG individuels
Performances optimisées
– Pas de chargement d’une bibliothèque entière inutilement.
– Chaque SVG ne pèse que quelques Ko, voire moins.
Contrôle total
– Vous pouvez modifier la couleur, la taille, le style, l’animation… directement avec du CSS.
Pas de dépendance externe
– Pas besoin d’appels à des CDN comme Font Awesome.
– Plus rapide, plus sécurisé, moins de requêtes HTTP.
Accessibilité et SEO
– Un SVG bien structuré peut être lisible pour les lecteurs d’écran.
– Mieux indexé qu’une icône webfont.
Si vous avez moins de 15 icônes, utilisez des SVG individuels (inline ou en fichier).
N’utilisez Font Awesome ou autre bibliothèque que si vous en avez besoin de plus de 30, ou si vous changez souvent d’icônes dans vos projets.
Le fichier IconHelper.php
<?php
namespace App\Helpers;
class IconHelper
{
public static function get($name, $class = '')
{
$icons = [
'twitter' => '<svg class="%s" xmlns="http://www.w3.org/2000/svg" fill="currentColor" viewBox="0 0 24 24"><path d="M22.46 6c-.77.35-1.6.58-2.46.69a4.3 4.3 0 001.88-2.37 8.55 8.55 0 01-2.72 1.04 4.27 4.27 0 00-7.27 3.89 12.11 12.11 0 01-8.8-4.46 4.27 4.27 0 001.32 5.7 4.23 4.23 0 01-1.93-.53v.05a4.27 4.27 0 003.42 4.18 4.3 4.3 0 01-1.92.07 4.28 4.28 0 004 2.97 8.57 8.57 0 01-5.3 1.83A8.75 8.75 0 012 19.54a12.07 12.07 0 006.56 1.92c7.88 0 12.2-6.53 12.2-12.2v-.56A8.67 8.67 0 0024 5.3a8.48 8.48 0 01-2.54.7z"/></svg>',
'instagram' => '<svg class="%s" xmlns="http://www.w3.org/2000/svg" fill="currentColor" viewBox="0 0 24 24"><path d="M7.75 2h8.5A5.75 5.75 0 0122 7.75v8.5A5.75 5.75 0 0116.25 22h-8.5A5.75 5.75 0 012 16.25v-8.5A5.75 5.75 0 017.75 2zm0 1.5A4.25 4.25 0 003.5 7.75v8.5A4.25 4.25 0 007.75 20.5h8.5a4.25 4.25 0 004.25-4.25v-8.5A4.25 4.25 0 0016.25 3.5h-8.5zM12 7a5 5 0 110 10 5 5 0 010-10zm0 1.5a3.5 3.5 0 100 7 3.5 3.5 0 000-7zm4.75-2.25a1 1 0 110 2 1 1 0 010-2z"/></svg>',
'twitch' => '<svg class="%s" xmlns="http://www.w3.org/2000/svg" fill="currentColor" viewBox="0 0 24 24"><path d="M4.265 2L2 5.219v15.563h5.03V22h3.219l3.218-3.218h4.825L22 14.718V2H4.265zm16.155 11.6l-2.112 2.112h-4.826l-3.218 3.218v-3.218H6.03V3.375h14.39V13.6zM14.748 6.94v4.23h1.41v-4.23h-1.41zm-4.223 0v4.23h1.411v-4.23h-1.41z"/></svg>',
'youtube' => '<svg class="%s" xmlns="http://www.w3.org/2000/svg" fill="currentColor" viewBox="0 0 24 24"><path d="M19.615 3.184A3.002 3.002 0 0021.64 5.2c.574 2.11.574 6.5.574 6.5s0 4.39-.574 6.5a3.002 3.002 0 01-2.025 2.016C17.501 21 12 21 12 21s-5.501 0-7.615-.784A3.002 3.002 0 012.36 18.2C1.786 16.09 1.786 11.7 1.786 11.7s0-4.39.574-6.5A3.002 3.002 0 014.385 3.184C6.499 2.4 12 2.4 12 2.4s5.501 0 7.615.784zM10 15.27l5.25-3.57L10 8.13v7.14z"/></svg>',
'github' => '<svg class="%s" xmlns="http://www.w3.org/2000/svg" fill="currentColor" viewBox="0 0 24 24"><path d="M12 2C6.48 2 2 6.58 2 12.26c0 4.5 2.87 8.32 6.84 9.67.5.1.68-.22.68-.48 0-.24-.01-.87-.01-1.7-2.78.62-3.37-1.37-3.37-1.37-.45-1.17-1.11-1.48-1.11-1.48-.91-.64.07-.63.07-.63 1 .07 1.53 1.06 1.53 1.06.89 1.57 2.34 1.12 2.91.86.09-.67.35-1.12.63-1.37-2.22-.26-4.56-1.14-4.56-5.06 0-1.12.39-2.03 1.03-2.75-.1-.26-.45-1.3.1-2.7 0 0 .84-.27 2.75 1.04A9.38 9.38 0 0112 6.81c.85.01 1.7.12 2.5.35 1.91-1.31 2.75-1.04 2.75-1.04.55 1.4.2 2.44.1 2.7.64.72 1.03 1.63 1.03 2.75 0 3.93-2.34 4.8-4.57 5.06.36.31.68.93.68 1.87 0 1.35-.01 2.44-.01 2.78 0 .27.18.59.69.49A10.02 10.02 0 0022 12.26C22 6.58 17.52 2 12 2z"/></svg>',
'user' => '<svg class="%s" xmlns="http://www.w3.org/2000/svg" fill="currentColor" viewBox="0 0 24 24"><path d="M12 12a5 5 0 100-10 5 5 0 000 10zm0 2c-3.33 0-10 1.67-10 5v3h20v-3c0-3.33-6.67-5-10-5z"/></svg>',
'login' => '<svg class="%s" xmlns="http://www.w3.org/2000/svg" fill="currentColor" viewBox="0 0 24 24"><path d="M10.09 15.59L12.67 13H3v-2h9.67l-2.58-2.59L11.5 7l5 5-5 5-1.41-1.41zM19 3H9a2 2 0 00-2 2v4h2V5h10v14H9v-4H7v4a2 2 0 002 2h10a2 2 0 002-2V5a2 2 0 00-2-2z"/></svg>',
'logout' => '<svg class="%s" xmlns="http://www.w3.org/2000/svg" fill="currentColor" viewBox="0 0 24 24"><path d="M16 17l1.41-1.41L13.83 12l3.58-3.59L16 7l-6 6 6 6z"/><path d="M20 3H10a2 2 0 00-2 2v4h2V5h10v14H10v-4H8v4a2 2 0 002 2h10a2 2 0 002-2V5a2 2 0 00-2-2z"/></svg>'
// Ajoutez ici d'autres icônes
];
return isset($icons[$name]) ? sprintf($icons[$name], htmlspecialchars($class)) : '';
}
}
Pour les utiliser dans une vue (par exemple dans header.php
) :
use App\Helpers\IconHelper;
?>
<nav>
<a href="/compte">
<?= IconHelper::get('user', 'maClasse') ?>
Mon compte
</a>
</nav>
Il ne restera plus qu’à ajouter nos icônes, au format SVG, dans notre fichier IconHelper.php
et les appeler ensuite dans nos vues.
Coder le header : HTML simple et clair

Voici un exemple de structure HTML complète pour un header
de site web comme celui de Créa-code, avec : une sémantique propre et accessible, un logo à gauche, des liens de navigation au centre (visibles sur desktop), deux boutons à droite “Connexion” et “Inscription” et un menu burger responsive (mobile).
<?php
use App\Helpers\IconHelper;
?>
<!-- Header principal du site -->
<header id="header" role="banner">
<div class="header-container">
<!-- Logo du site -->
<a href="<?= BASE_URL ?>" class="logo" aria-label="Accueil Créa-code">
<img src="<?= BASE_URL ?>assets/img/logo-crea-code-horizontal500x100.webp" alt="Créa-code">
</a>
<!-- Menu de navigation principal -->
<nav class="main-nav" role="navigation" aria-label="Navigation principale">
<ul class="nav-links">
<li><a href="#">Parcours</a></li>
<li><a href="#">Exercices</a></li>
<li><a href="#">Classement</a></li>
<li><a href="#">Blog</a></li>
</ul>
</nav>
<!-- Boutons d'action utilisateur -->
<div class="auth-buttons">
<?php if (isset($_SESSION['user']) && $_SESSION['user']['is_active'] == 1): ?>
<a class="btn btn-signin" href="<?= BASE_URL ?>dashboard"><?= IconHelper::get('user', 'icon-rs') ?> Dashboard</a>
<a class="btn btn-login" href="<?= BASE_URL ?>logout"><?= IconHelper::get('logout', 'icon-rs') ?> Déconnexion</a>
<?php elseif (isset($_SESSION['user']) && $_SESSION['user']['is_active'] == 0): ?>
<a class="btn btn-login" href="<?= BASE_URL ?><?= IconHelper::get('user', 'icon-rs') ?> login">Connexion</a>
<?php else: ?>
<a class="btn btn-signin" href="<?= BASE_URL ?>signin"><?= IconHelper::get('login', 'icon-rs') ?> Inscription</a>
<a class="btn btn-login" href="<?= BASE_URL ?>login"><?= IconHelper::get('user', 'icon-rs') ?> Connexion</a>
<?php endif; ?>
</div>
<!-- Icône burger pour menu mobile -->
<button class="burger" aria-label="Menu mobile" aria-controls="mobile-menu" aria-expanded="false">
<span class="burger-line"></span>
<span class="burger-line"></span>
<span class="burger-line"></span>
</button>
</div>
<!-- Menu mobile (affiché uniquement sur petit écran) -->
<div id="mobile-menu" class="mobile-menu">
<ul>
<a href="<?= BASE_URL ?>" class="logo" aria-label="Accueil Créa-code">
<img src="<?= BASE_URL ?>assets/img/logo-crea-code-horizontal500x100.webp" alt="Créa-code">
</a>
<li><a href="#">- Parcours -</a></li>
<li><a href="#">- Exercices -</a></li>
<li><a href="#">- Quizz -</a></li>
<li><a href="#">- Missions -</a></li>
<li><a href="https://blog.crea-troyes.fr">- Blog -</a></li>
<?php if (isset($_SESSION['user']) && $_SESSION['user']['is_active'] == 1): ?>
<a class="btn btn-signin" href="<?= BASE_URL ?>dashboard"><?= IconHelper::get('user', 'icon-rs') ?> Dashboard</a>
<a class="btn btn-login" href="<?= BASE_URL ?>logout"><?= IconHelper::get('logout', 'icon-rs') ?> Déconnexion</a>
<?php elseif (isset($_SESSION['user']) && $_SESSION['user']['is_active'] == 0): ?>
<a class="btn btn-login" href="<?= BASE_URL ?>login"><?= IconHelper::get('user', 'icon-rs') ?> Connexion</a>
<?php else: ?>
<a class="btn btn-signin" href="<?= BASE_URL ?>signin"><?= IconHelper::get('login', 'icon-rs') ?> Inscription</a>
<a class="btn btn-login" href="<?= BASE_URL ?>login"><?= IconHelper::get('user', 'icon-rs') ?> Connexion</a>
<?php endif; ?>
</ul>
</div>
</header>
Voici le code CSS qui va nous permettre d’avoir un menu responsive (desktop + mobile), un header fixe en haut de la page, un fond en dégradé vertical du gris #f4f4f4
vers blanc #ffffff
, un menu burger visible en version mobile uniquement et un menu mobile déroulant propre.
Nous allons ajouter le code suivant au fichier public/assets/css/styles.css :
/*************************
* *
* HEADER *
* *
*************************/
#header {
position: fixed;
top: 0;
left: 0;
width: 100%;
background: linear-gradient(to bottom, #f4f4f4 0%, #ffffff 100%);
z-index: 1000;
box-shadow: 0 2px 5px rgba(0,0,0,0.05);
}
.header-container {
display: flex;
justify-content: space-between;
align-items: center;
max-width: 1200px;
padding: 1rem 2rem;
margin: 0 auto;
}
.logo img {
height: 40px;
position: relative;
top: -5px;
}
.main-nav ul {
list-style: none;
display: flex;
gap: 1.5rem;
margin: 0;
padding: 0;
}
.main-nav a {
text-decoration: none;
color: var(--color-text-secondary);
font-weight: 500;
}
.main-nav a:hover {
text-decoration: underline;
color: var(--color-accent-secondary);
font-weight: 500;
}
.auth-buttons {
display: flex;
gap: 1rem;
}
#header .btn {
font-size: 0.85rem;
}
.burger {
display: none;
flex-direction: column;
justify-content: center;
gap: 1px;
width: 30px;
height: 30px;
background: none;
border: none;
cursor: pointer;
z-index: 10001;
position: relative;
top: -2px;
}
.burger-line {
border-radius: 2px;
border: 2px solid var(--color-text-secondary);
width: 30px;
margin-bottom: 5px;
position: relative;
top: 6px;
right: 10px;
transition: transform 0.3s ease, opacity 0.3s ease;
}
.burger.open .burger-line:nth-child(1) {
transform: rotate(45deg) translateY(15px);
}
.burger.open .burger-line:nth-child(2) {
opacity: 0;
}
.burger.open .burger-line:nth-child(3) {
transform: rotate(-45deg) translateY(-15px);
}
.burger.open {
position: relative;
right:-15px;
}
.mobile-menu {
position: fixed;
top: 0;
left: 0;
width: 100vw;
height: 100vh;
background: var(--color-bg);
padding: 3rem 2rem;
display: flex;
flex-direction: column;
gap: 1.5rem;
justify-content: center;
align-items: center;
z-index: 9999;
opacity: 0;
transform: translateY(-20px);
pointer-events: none;
transition: opacity 0.3s ease, transform 0.3s ease;
}
.mobile-menu.open {
opacity: 1;
transform: translateY(0);
pointer-events: auto;
}
.mobile-menu ul {
list-style: none;
margin: 0;
padding: 0;
display: flex;
flex-direction: column;
gap: 1rem;
}
.mobile-menu a {
text-decoration: none;
color: var(--color-text-secondary);
font-weight: 500;
}
À ce code CSS, nous allons ajouter nos points de rupture à l’aide des media-query pour rendre ce menu responsive :
/*************************
* *
* RESPONSIVE *
* *
*************************/
@media (max-width: 950px) {
.main-nav,
.auth-buttons {
display: none;
}
.burger {
display: flex;
}
.mobile-menu {
display: flex;
text-align: center;
}
.mobile-menu ul img {
height: 60px;
}
.mobile-menu ul li:last-of-type, .mobile-menu ul a img {
padding-bottom: 1em;
}
.mobile-menu .btn {
max-width: 160px;
width: 100%;;
display: block;
margin: 0 auto;
}
.mobile-menu[hidden] {
display: none !important;
}
}
Enfin, nous ajoutons un peu de Javascript pour faire fonctionner notre menu hamburger. Ce code est à ajouter un un nouveau fichier public/assets/js/menu-responsive.js. Ce fichier sera relier aux pages du site un peu plus loin de cet article :
document.addEventListener('DOMContentLoaded', function () {
const burger = document.querySelector('.burger');
const mobileMenu = document.getElementById('mobile-menu');
const links = mobileMenu.querySelectorAll('a');
// Fonction pour ouvrir/fermer le menu
function toggleMenu() {
const isOpen = mobileMenu.classList.contains('open');
mobileMenu.classList.toggle('open');
burger.classList.toggle('open');
burger.setAttribute('aria-expanded', String(!isOpen));
}
// Clic sur le burger
burger.addEventListener('click', toggleMenu);
// Clic sur un lien du menu => on ferme le menu
links.forEach(link => {
link.addEventListener('click', () => {
mobileMenu.classList.remove('open');
burger.classList.remove('open');
burger.setAttribute('aria-expanded', 'false');
});
});
// Touche Échap => on ferme le menu
document.addEventListener('keydown', function (e) {
if (e.key === 'Escape' && mobileMenu.classList.contains('open')) {
mobileMenu.classList.remove('open');
burger.classList.remove('open');
burger.setAttribute('aria-expanded', 'false');
}
});
});
Coder le footer : utile, cohérent, discret

Le footer est souvent la dernière chose que nous voyons sur une page, mais il ne faut pas le traiter comme un simple ajout décoratif. C’est un espace stratégique, à la fois pour l’expérience utilisateur et pour le référencement naturel. Un footer bien pensé permet de conclure la page avec clarté, tout en proposant des options utiles : des liens importants, un formulaire d’inscription, ou un accès rapide à nos réseaux sociaux.
Nous allons ici construire un footer moderne, avec une forme en vague décorative, un design léger, mais efficace. Chaque partie du footer a été pensée pour combiner esthétique, accessibilité, ergonomie et performance SEO.
Une vague pour séparer le footer du reste
Avant même le contenu du footer, nous avons ajouté une vague SVG. Ce petit détail visuel permet de créer une transition douce entre la fin du contenu principal et le début du pied de page. Cela rend la page plus fluide à lire et lui donne un aspect plus vivant, plus engageant.
Le SVG est léger, responsive et accessible, car nous ajoutons aria-hidden="true"
pour indiquer qu’il est purement décoratif et qu’il n’a pas besoin d’être lu par un lecteur d’écran.
La couleur de la vague (#F4F4F4
) correspond à notre fond alterné défini dans notre styleguide. Elle marque bien la séparation sans créer de rupture trop nette.
Le formulaire de newsletter
Juste après la vague, le footer commence par une section dédiée à l’inscription à notre newsletter. C’est un excellent moyen de prolonger la relation avec nos visiteurs, surtout ceux qui apprécient notre contenu. Le formulaire est simple : un champ email et un bouton d’envoi.
Nous utilisons une balise <label>
pour l’accessibilité, mais comme nous n’avons pas besoin de l’afficher visuellement, nous lui appliquons une classe .visually-hidden
. Cela garantit que les utilisateurs de lecteurs d’écran puissent comprendre ce que contient le champ, tout en gardant le design épuré.
Vous pourrez gérer l’inscription à la newsletter en stockant directement dans une table les adresses mail des visiteurs ou utilisateurs inscrits, soit passé immédiatement par un gestionnaire de newsletter tel que MailChimp. Nous aborderons ce sujet demain ;).
Les liens utiles
Ensuite, nous avons placé un <nav>
contenant des liens secondaires. Ce sont des pages importantes mais qui ne font pas partie du cœur de navigation : à propos, conditions, contact, etc.
Le fait d’utiliser une balise nav
avec un aria-label
(“Liens utiles”) est une bonne pratique SEO et accessibilité : cela aide à structurer la page, pour les moteurs de recherche comme pour les utilisateurs.
Les réseaux sociaux
Nous avons ensuite une section dédiée aux réseaux sociaux. Ce sont des liens vers nos profils externes (YouTube, Instagram, etc.). Les icônes sont intégrées dans des balises <a>
avec des aria-label
pour préciser la destination.
Nous avons caché les titres de section avec visually-hidden
pour que l’ensemble reste propre, mais continue à être compris par les technologies d’assistance.
Le copyright
Enfin, le footer se termine par une ligne de texte classique indiquant le nom du site, l’année, et la mention « Tous droits réservés ». Cela montre que le site est actif et maintenu, et donne une touche de professionnalisme.
Accessibilité et sémantique
Tout au long de ce footer, nous avons fait attention à respecter la structure HTML5. Nous utilisons des balises footer
, section
, form
, nav
, ul
, et aria-label
pour aider les outils comme les lecteurs d’écran à comprendre la structure.
Grâce à cela, nous améliorons à la fois l’expérience des visiteurs en situation de handicap et le référencement naturel (SEO), puisque les moteurs de recherche lisent cette structure.
Pour commencer, ajoutons notre vague sous forme de SVG au fichier IconHelper.php
:
$icons = [
// ...
'footer_wave' => '<svg class="%s" viewBox="0 0 1440 150" preserveAspectRatio="none" xmlns="http://www.w3.org/2000/svg"><path d="M0,80 C360,160 1080,0 1440,100 L1440,0 L0,0 Z" fill="#F4F4F4"></path></svg>',
// ...
];
Le code HTML du fichier app/Views/partials/footer.php :
<?php
use App\Helpers\IconHelper;
?>
<!-- Vague décorative au-dessus du footer -->
<div class="footer-wave" aria-hidden="true">
<?= IconHelper::get('footer_wave', 'icon-wave') ?>
</div>
<footer role="contentinfo">
<div class="container">
<section class="footer-newsletter" aria-labelledby="newsletter-title">
<h4 id="newsletter-title">Recevez nos astuces web</h4>
<p>Inscrivez-vous à notre newsletter pour ne rien rater des nouveaux exercices et tutoriels.</p>
<form action="#" method="post">
<input type="email" id="newsletter-email" name="email" placeholder="Votre adresse email" required>
<button type="submit">S'inscrire</button>
</form>
</section>
<div class="footer-about" aria-label="À propos de Créa-code">
<section class="footer-logo">
<h2 class="visually-hidden">À propos de <img src="<?= BASE_URL ?>/assets/img/logo-crea-code-horizontal500x100.webp" alt="logo Créa-code"></h2>
<p><a href="<?= BASE_URL ?>">Créa-code</a> est une plateforme <strong>100% gratuite</strong> dédiée à l'apprentissage du développement web. Nous proposons des exercices pratiques, des tutoriels et des ressources pour vous aider à progresser.
Notre mission est de rendre l'apprentissage du code accessible à tous, que vous soyez débutant ou développeur confirmé.</p>
<ul class="footer-tag" aria-label="Tags">
<li>HTML</li>
<li>CSS</li>
<li>PHP</li>
<li>JavaScript</li>
<li>JSON</li>
<li>MySQL</li>
<li>Apache</li>
</ul>
</section>
<nav class="footer-links" aria-label="Créa-code">
<header>
<h3>Créa-code</h3>
</header>
<ul>
<li><a href="#">Dashboard</a></li>
<li><a href="#">Chapitres</a></li>
<li><a href="#">Exercices</a></li>
<li><a href="#">Classement</a></li>
</ul>
</nav>
<nav class="footer-links" aria-label="Ressources">
<header>
<h3>Ressources</h3>
</header>
<ul>
<li><a href="https://formation.crea-troyes.fr">Formation</a></li>
<li><a href="https://blog.crea-troyes.fr">Blog</a></li>
<li><a href="https://crea-troyes.fr">Agence</a></li>
</ul>
</nav>
<nav class="footer-links" aria-label="Liens utiles">
<header>
<h3>Informations</h3>
</header>
<ul>
<li><a href="#">À propos</a></li>
<li><a href="#">Contact</a></li>
<li><a href="#">CGU</a></li>
</ul>
</nav>
</div>
<section class="footer-social" aria-label="Suivez-nous sur les réseaux sociaux">
<h4 class="visually-hidden">Restez connecté</h4>
<ul>
<li><a href="https://twitter.com/creatroyes" aria-label="Twitter"><?= IconHelper::get('twitter', 'icon-rs') ?></a></li>
<li><a href="https://www.instagram.com/creatroyes/" aria-label="Instagram"><?= IconHelper::get('instagram', 'icon-rs') ?></a></li>
<li><a href="https://www.twitch.tv/creatroyes" aria-label="Twitch"><?= IconHelper::get('twitch', 'icon-rs') ?></a></li>
<li><a href="https://www.youtube.com/@Creatroyes" aria-label="YouTube"><?= IconHelper::get('youtube', 'icon-rs') ?></a></li>
<li><a href="https://github.com/crea-troyes" aria-label="GitHub"><?= IconHelper::get('github', 'icon-rs') ?></a></li>
</ul>
</section>
<div class="footer-copy">
<p><small>© <?= date("Y"); ?> Créa-code. Tous droits réservés.</small></p>
</div>
</div>
</footer>
Ce footer, qui est une base solide, sera amener a évoluer, notamment au niveau des liens. Passons maintenant à sa mise en page, nous allons ajouter le code CSS suivant dans le fichier app/public/assets/css/styles.css :
/*************************
* *
* FOOTER *
* *
*************************/
.footer-wave svg {
transform: scaleY(-1);
display: block;
width: 100%;
height: 80px;
}
.footer-wave svg path {
fill: var(--color-bg-alt);
}
footer {
background-color: var(--color-bg-alt);
padding: 4em 0 2em;
}
/* --- Newsletter --- */
footer .footer-newsletter {
margin-bottom: 5em;
text-align: center;
}
footer .footer-newsletter h4 {
font-size: 1.5rem;
}
footer .footer-newsletter input[type="email"] {
width: 100%;
max-width: 300px;
padding: 0.5em;
border: 1px solid var(--color-text-secondary);
border-radius: 4px;
font-size: 1rem;
background: var(--color-bg);
color: var(--color-text);
transition: border-color 0.2s ease;
}
footer .footer-newsletter input[type="email"]:focus,
footer .footer-newsletter input[type="email"]:hover {
border-color: var(--color-accent-secondary);
outline: none;
}
footer .footer-newsletter button {
margin-left: 0.5em;
padding: 0.5em 1em;
}
/* --- About Section --- */
footer .footer-about {
display: flex;
flex-direction: row;
gap: 4em;
margin-bottom: 3em;
border-top: 1px solid var(--color-bg);
border-bottom: 1px solid var(--color-bg);
padding: 5em 0;
}
footer .footer-about a:hover {
color: var(--color-text);
text-decoration: underline;
}
footer .footer-about .footer-logo {
flex: 4;
padding-right: 3em;
}
footer .footer-about .footer-logo h2 {
font-size: 1.5rem;
margin-top: -20px;
}
footer .footer-about .footer-logo h2 img {
height: 40px;
display: inline;
position: relative;
top: 7px;
}
footer .footer-about .footer-logo ul li {
display: inline-block;
background: var(--color-text-secondary);
color: var(--color-bg);
padding: 0.5em 0.75rem;
border-radius: 2rem;
margin-right: 0.3em;
font-size: 12px;
font-weight: 600;
outline: 0;
background-size: 125px;
}
footer .footer-about .footer-links {
flex: 1;
}
footer .footer-about .footer-links header h3 {
font-size: 1.5rem;
}
footer .footer-about .footer-links ul li {
margin-bottom: 0.5em;
font-size: 0.875rem;
padding-left: .2em;
}
/* --- Social --- */
footer .footer-social {
flex: 1;
display: flex;
flex-direction: column;
align-items: center;
}
footer .footer-social h4 {
font-size: 1.5rem;
}
footer .footer-social ul {
display: flex;
gap: 1em;
}
footer .footer-social ul li {
display: inline-block;
}
footer .footer-social ul li a {
color: var(--color-text-secondary);
font-size: 1.5rem;
transition: color 0.2s ease;
}
footer .footer-social ul li a:hover {
color: var(--color-accent-secondary);
}
footer .footer-social ul li a svg {
width: 24px;
height: 24px;
}
/* --- Copyright --- */
footer .footer-copy p {
text-align: center;
font-size: 12px;
color: var(--color-text-secondary);
margin-top: 1em;
}
Ajoutons des media-query afin de rendre ce footer responsive :
/*************************
* *
* RESPONSIVE *
* *
*************************/
@media (max-width: 1400px) {
.container {
max-width: 90%;
margin: 0 5%;
}
}
@media (max-width: 1250px) {
footer .footer-about {
gap: 2em;
}
footer .footer-about .footer-logo {
flex: 5;
padding-right: 2em;
}
footer .footer-about .footer-logo ul li {
font-size: 11px;
}
footer .footer-about .footer-links header h3 {
font-size: 1rem;
}
}
@media (max-width: 1023px) {
footer .footer-about {
flex-direction: column;
border-bottom: none;
padding: 5em 0 2em;
gap: 1em;
}
footer .footer-about .footer-logo {
margin-bottom: 3em;
}
.footer-links ul {
display: none;
padding-left: 0.2em;
margin: 1em 0 1.5em;
font-size: 1rem;
}
footer .footer-about .footer-links ul li {
margin-bottom: 0.7em;
font-size: 1rem;
padding-left: 0;
}
.footer-links header {
display: flex;
justify-content: space-between;
align-items: center;
cursor: pointer;
border-bottom: 1px solid var(--color-bg);
padding-bottom: 10px;
}
.footer-links h3 {
position: relative;
font-size: 1.1rem;
margin: 0;
}
.footer-links header::after {
content: "+";
font-size: 1.2rem;
color: var(--color-text-secondary, #777);
transition: transform 0.3s ease;
}
.footer-links.active ul {
display: block;
}
.footer-links.active header::after {
content: "−"; /* signe moins */
}
}
@media (max-width: 748px) {
footer {
padding: 2em 0 2em;
}
footer .footer-newsletter input[type="email"] {
display: block;
width: 90%;
max-width: 300px;
margin: 0 auto 10px;
}
footer .footer-newsletter button {
width: 90%;
max-width: 300px;
margin: 0 auto;
}
footer .footer-about .footer-logo span {
display: none;
}
footer .footer-about .footer-logo ul {
line-height: 2;
}
footer .footer-about .footer-logo ul li {
padding: 0.2em 1rem;
}
footer .footer-social h4 {
font-size: 1rem;
margin-bottom: 20px;
}
}
Enfin, on ajoute un peu de JavaScript au footer pour déployer les menus en responsive. Relier le script depuis app/Views/partials/footer.php.
<script src="<?= BASE_URL ?>assets/js/menu-responsive.js" defer></script>
Puis, on ajoute au fichier public/assets/js/footer-responsive.js :
document.querySelectorAll('.footer-links header').forEach(header => {
header.addEventListener('click', () => {
const nav = header.closest('.footer-links');
nav.classList.toggle('active');
});
});
Ce footer est simple, clair, mais très bien structuré. Il donne une impression de professionnalisme, facilite l’engagement avec les visiteurs, et renforce l’identité de notre site. Grâce à la vague SVG, il s’intègre parfaitement avec le reste du design sans casser la fluidité. Il est entièrement personnalisable, et il nous servira de base pour toutes les pages du projet.
Maintenant que le bas de la page est posé, nous allons pouvoir remonter vers le haut : au prochain chapitre, nous coderons ensemble le header responsive, qui guidera nos utilisateurs dès leur arrivée sur le site.
Voici une version complète et sémantique du footer, incluant une vague SVG en haut, un formulaire de newsletter, des liens utiles, et des réseaux sociaux, tout en gardant l’accessibilité et le SEO comme priorités.
Tester l’affichage sur desktop, mobile et tablette
Maintenant que notre header et notre footer sont codés, que nos polices sont en place et que les bases du design sont posées, nous devons absolument vérifier comment tout cela s’affiche sur les différents appareils. Le but, c’est que notre site soit lisible, beau et surtout facile à utiliser, que l’on soit sur un ordinateur, un téléphone ou une tablette.
Ce que nous cherchons, ce n’est pas que tout soit « parfaitement identique » sur chaque écran, mais que chaque version soit adaptée. Le texte doit rester lisible, les boutons doivent être cliquables, les espaces doivent respirer et le contenu doit s’adapter à la taille de l’écran. C’est ce qu’on appelle un design responsive.
Pourquoi c’est important de tester sur plusieurs supports
Aujourd’hui, une grande partie des visiteurs vient sur les sites depuis leur smartphone. D’autres consultent sur une tablette ou un écran d’ordinateur classique. Si notre site ne s’adapte pas correctement à ces différentes tailles, l’expérience utilisateur sera mauvaise. Le visiteur devra zoomer, glisser horizontalement, ou ne verra même pas certains éléments. Résultat : il quitte le site.
Nous voulons l’éviter. Un bon affichage partout, c’est plus de confort, plus de professionnalisme, et donc plus de chances que les gens restent et reviennent.
Comment faire ces tests simplement
Nous allons d’abord tester directement dans notre navigateur, sans avoir besoin de plusieurs appareils physiques. La plupart des navigateurs modernes, comme Chrome, Firefox ou Edge, proposent des outils intégrés qui permettent de simuler des écrans de différentes tailles.
Voici comment nous allons faire avec Google Chrome (la méthode est presque la même sur Firefox ou les autres navigateurs) :
- Nous ouvrons notre site dans Chrome.
- Nous appuyons sur la touche F12 pour ouvrir les outils développeur.
- Ensuite, nous cliquons sur l’icône en forme de petit téléphone et tablette en haut à gauche des outils (c’est l’outil de test mobile).
- Là, nous pouvons choisir différents formats dans un menu déroulant : iPhone, iPad, Galaxy, mais aussi des tailles génériques comme 375px, 768px ou 1024px.
En faisant cela, nous pouvons tester en direct ce qui se passe lorsque notre site s’affiche sur un petit écran.
Nous vérifions si :
- les éléments ne se chevauchent pas,
- les textes ne deviennent pas trop petits,
- les marges ne disparaissent pas,
- les boutons restent accessibles et lisibles.
Nous pouvons même faire défiler la page, tester les liens, interagir avec le formulaire de newsletter ou cliquer sur les icônes de réseaux sociaux, comme si nous étions vraiment sur un mobile.
Repérer les problèmes et les corriger
Parfois, nous allons remarquer que certains éléments sont trop serrés, que les textes sont trop petits, ou que des blocs s’alignent mal. Par exemple, notre formulaire d’inscription peut paraître bien sur un écran large, mais sur mobile, il peut se retrouver trop à l’étroit.
Quand cela arrive, nous revenons dans notre fichier CSS et nous ajoutons ou corrigeons des règles spécifiques pour les petits écrans, avec des media queries.
Un media query permet de dire au navigateur : « si l’écran fait moins de X pixels, applique ce style ». C’est très utile pour ajuster certaines choses uniquement sur mobile ou tablette.
Grâce à ces règles, nous gardons un footer lisible et agréable, même sur un téléphone.
Et sur un vrai appareil ?
Même si les outils du navigateur sont très utiles, il est toujours bon de faire un test sur un vrai téléphone ou une vraie tablette si possible. Nous ouvrons le site dans le navigateur du téléphone, et nous vérifions que tout fonctionne :
- le texte s’affiche bien,
- les boutons sont cliquables,
- il n’y a pas de problème de défilement horizontal,
- les formulaires sont utilisables avec le clavier du téléphone.
Il peut aussi être utile de faire pivoter l’écran pour voir si l’affichage reste stable en mode paysage. Cela nous aide à voir si des éléments débordent ou si certains blocs deviennent trop larges.
Conclusion
Tester l’affichage de notre site sur différentes tailles d’écran est une étape indispensable. Cela nous permet de corriger rapidement les problèmes d’adaptation, d’améliorer l’expérience utilisateur, et de donner une image plus professionnelle de notre projet. Un site qui fonctionne bien sur mobile et tablette est aujourd’hui essentiel, car de plus en plus d’utilisateurs naviguent depuis leur téléphone.
En vérifiant dès maintenant l’affichage de notre footer, nous posons des bases solides pour la suite. Chaque élément que nous coderons ensuite devra suivre cette logique responsive, pour un site fluide et agréable sur tous les supports.
Demain, nous aborderons la liaison du formulaire à un service de gestion de mailing type MailChimp.