Aujourd’hui, nous allons travailler sur un aspect fondamental de toute application web : l’interface de connexion et d’inscription. Ces deux formulaires sont souvent la première interaction qu’un utilisateur a avec notre site. Leur esthétique, leur clarté et leur ergonomie jouent un rôle crucial dans la réassurance de l’utilisateur et la confiance qu’il accordera à notre plateforme.
Sur le site Créa-code, nous souhaitons que chaque visiteur ait une expérience fluide et agréable, même sur mobile. Cela signifie que notre mise en page doit être responsive, c’est-à-dire capable de s’adapter à toutes les tailles d’écran.
Nous allons aussi profiter de cette étape pour optimiser ces pages pour le référencement naturel (SEO). Même si ce ne sont pas les pages les plus stratégiques pour le positionnement sur Google, elles peuvent tout de même contribuer à la qualité globale du site et à l’expérience utilisateur.
- Structuration HTML : une base saine
- Le CSS moderne et responsive
- Responsive design
- Étendre ce style à la page d’inscription
- SEO : contenu optimisé pour la pages de formulaire d'inscription
- Faut-il indexer les pages de connexion et inscription ?
- Gérer dynamiquement la balise dans le layout (vue globale)
- Les valeurs possibles pour robots
Objectif du jour
Nous allons :
- Créer une mise en page CSS claire, moderne et responsive pour les deux formulaires (connexion et inscription) que nous avons codé les jours 15 (formulaire d’inscription) et 16 (formulaire de connexion).
- Ajouter du contenu sémantique et optimisé SEO à ces pages, pour renforcer la clarté et la crédibilité du site.
- Expliquer chaque ligne de code CSS pour apprendre à maîtriser la logique de la mise en page.
Structuration HTML : une base saine
Avant d’appliquer notre CSS, vérifions que notre HTML est sémantiquement correct. Pour aller plus loin en accessibilité et SEO, nous allons légèrement ajuster la structure.
Exemple de structure HTML pour la page de connexion
<main class="auth-page">
<section class="auth-container">
<h1><img class="img-theme-switch" src="<?= BASE_URL ?>assets/img/logo-crea-code-horizontal500x100.webp"
data-src-light="<?= BASE_URL ?>assets/img/logo-crea-code-horizontal500x100.webp"
data-src-dark="<?= BASE_URL ?>assets/img/logo-crea-code-horizontal-dark.webp"
alt="Logo Créa-code"
loading="lazy"></h1>
<hr>
<p>Connectez-vous à votre espace pour accéder à vos parcours, vos challenges et votre progression sur
Créa-code.</p>
<?php if (!empty($errors)) : ?>
<div class="form-errors" role="alert">
<?php foreach ($errors as $error) : ?>
<p><?= htmlspecialchars($error) ?></p>
<?php endforeach; ?>
</div>
<?php endif; ?>
<form id="login-form" action="<?= BASE_URL ?>login/post" method="post" novalidate>
<input type="email" name="email" id="email" placeholder="Adresse mail">
<input type="password" name="password" id="password" placeholder="Mot de passe" required>
<div id="email-error" class="error-message"></div>
<div id="password-error" class="error-message"></div>
<p id="forgot-password"><a href="<?= BASE_URL ?>forgot">Mot de passe oublié ?</a></p>
<button class="btn btn-signin" type="submit">Se connecter</button>
</form>
<p>Pas encore inscrit ?<br><a href="<?= BASE_URL ?>signin">Créer un compte gratuitement</a></p>
</section>
</main>
<script src="<?= BASE_URL ?>assets/js/login-form-validation.js" defer></script>
Pourquoi cette structure est importante ?
- La balise
<main>
indique le contenu principal de la page. - La section avec
class="auth-container"
regroupe le titre, la description, les erreurs et le formulaire, ce qui améliore la lisibilité et facilite le ciblage CSS. - On ajoute un petit paragraphe de description pour le SEO : Google apprécie qu’une page ait un minimum de contenu textuel.
- Le
role="alert"
dans la div des erreurs signale aux lecteurs d’écran qu’un message important est présent.
Le CSS moderne et responsive
Passons maintenant à la partie tant attendue : la mise en page CSS. Voici un exemple complet que nous allons ajouter à notre feuille de style pour ces deux formulaires, que nous commenterons ensemble ligne par ligne.
Fichier : public/assets/css/styles.css
/*************************
* *
* Formulaire *
* *
*************************/
.auth-page {
display: flex;
justify-content: center;
align-items: center;
padding: 2rem 1rem;
}
.auth-container {
background-color: var(--color-bg-alt);
padding: 2rem;
border-radius: 12px;
max-width: 400px;
width: 100%;
}
.auth-container h1 img {
height: 2.5rem;
}
.auth-container hr {
border: none;
border-top: 1px solid var(--border-color);
margin: 1.5rem 0;
}
.auth-container p {
font-size: 0.95rem;
margin-bottom: 1.5rem;
color: var(--color-text-secondary);
}
.auth-container #forgot-password {
text-align: right;
margin: 1rem 0 -0.5rem;
font-size: 0.9rem;
}
.auth-container input,
.auth-container select {
width: 100%;
padding: 0.75rem;
font-size: 1rem;
border: 1px solid var(--border-color);
background-color: var(--color-bg);
color: var(--color-text);
transition: border-color 0.3s;
margin: 0;
border-bottom: none;
}
.auth-container select {
appearance: none;
background-image: url("data:image/svg+xml;utf8,<svg fill='currentColor' height='20' viewBox='0 0 20 20' width='20' xmlns='http://www.w3.org/2000/svg'><path d='M5.5 7l4.5 4 4.5-4z'/></svg>");
background-repeat: no-repeat;
background-position: right 0.75rem center;
background-size: 1rem;
padding-right: 2rem;
margin-top: 1rem;
outline: none;
border-bottom: 1px solid var(--border-color);
}
.auth-container input:first-of-type {
border-radius: 8px 8px 0 0;
}
.auth-container input:last-of-type {
border-radius: 0 0 8px 8px;
border-bottom: 1px solid var(--border-color);
}
.auth-container input:focus,
.auth-container select:focus {
border-color: var(--color-accent-secondary);
outline: none;
}
.auth-container button {
display: inline-block;
width: 100%;
margin: 1.5rem 0;
padding: 0.75rem;
}
.error-message,
.form-errors {
color: var(--color-error);
font-size: 0.9rem;
margin-top: 0.5rem;
text-align:center;
}
.form-errors p {
margin-bottom: 0.5rem;
}

Décryptage complet du CSS : ligne par ligne
Nous allons maintenant passer en revue toutes les règles CSS que nous avons écrites, et expliquer pourquoi elles sont là, à quoi elles servent, et comment elles contribuent à une interface moderne et responsive.
Le conteneur principal .auth-page
.auth-page {
display: flex;
justify-content: center;
align-items: center;
padding: 2rem 1rem;
}
Pourquoi cette structure ?
Nous utilisons ici Flexbox pour centrer notre formulaire horizontalement et verticalement dans la page. C’est propre, efficace, et surtout, c’est responsive naturellement.
display: flex
active Flexbox.justify-content: center
centre sur l’axe horizontal.align-items: center
centre sur l’axe vertical.padding: 2rem 1rem
ajoute un peu d’air autour (haut/bas et gauche/droite), ce qui améliore la lisibilité sur mobile.
Le bloc .auth-container
.auth-container {
background-color: var(--color-bg-alt);
padding: 2rem;
border-radius: 12px;
max-width: 400px;
width: 100%;
}
C’est ici que la magie opère.
Nous créons une carte gris claire, qui flotte au centre de la page :
background-color:
rend le fond visible sur le gris clair.padding: 2rem
donne de l’espace intérieur, pour aérer les champs.border-radius: 12px
adoucit les angles, pour un look moderne.max-width: 400px
limite la largeur du formulaire (idéal sur desktop).width: 100%
permet l’adaptation sur mobile.
Le logo et le texte
.auth-container h1 img {
height: 2.5rem;
}
.auth-container p {
font-size: 0.95rem;
margin-bottom: 1.5rem;
color: var(--color-text-secondary);
}
.auth-container #forgot-password {
text-align: right;
margin: 1rem 0 -0.5rem;
font-size: 0.9rem;
}
Le logo est visuellement mis en valeur avec une taille adaptée.
Le paragraphe d’introduction est plus petit, plus léger en couleur et sert à rassurer et expliquer les bénéfices de l’action (se connecter, s’inscrire, etc.).
Important : SEO
Ce petit texte est très important pour le SEO.
Il permet à Google de comprendre le contenu de la page et offre des mots-clés naturels : « compte », « parcours », « challenges », « progression », etc.
Les champs du formulaire
.auth-container input,
.auth-container select {
width: 100%;
padding: 0.75rem;
font-size: 1rem;
border: 1px solid var(--border-color);
background-color: var(--color-bg);
color: var(--color-text);
transition: border-color 0.3s;
margin: 0;
border-bottom: none;
}
Ici, nous donnons un style homogène à tous les champs :
padding: 0.75rem
rend le champ agréable à cliquer ou toucher.background-color:
ajoute un léger contraste avec le background de la carte.
Et en focus :
.auth-container input:focus,
.auth-container select:focus {
border-color: var(--color-accent-secondary);
outline: none;
}
On change la couleur de la bordure pour donner un retour visuel clair à l’utilisateur. C’est une règle d’ergonomie visuelle essentielle.
Le bouton de soumission
.auth-container button {
display: inline-block;
width: 100%;
margin: 1.5rem 0;
padding: 0.75rem;
}
- Largeur à 100% pour l’ergonomie sur mobile.
- Jaune pour attirer l’attention (class
btn-singin
définit précédemment). - Survol plus foncé pour indiquer la réactivité du bouton.
Les erreurs et liens
.error-message,
.form-errors {
color: var(--color-error);
font-size: 0.9rem;
margin-top: 0.5rem;
text-align:center;
}
La couleur rouge symbolise une erreur. Elle est suffisamment vive, donc visible, mais pas agressive. L’espace vertical les rend lisibles sans surcharge.
Enfin, les liens sont visibles, cohérents avec la couleur du bouton, et soulignés au survol. Cela améliore l’accessibilité.
Responsive design
@media screen and (max-width: 500px) {
.auth-page {
padding: 0rem 1rem 2rem;
}
.auth-container {
padding: 1.5rem 1rem;
}
}
Sur les petits écrans, on réduit le padding intérieur pour que tout tienne bien dans la largeur de l’écran. On garde quand même un peu d’air pour que la lecture reste confortable.
Étendre ce style à la page d’inscription
Le formulaire d’inscription étant plus long, nous allons y intégrer une logique de blocs visuels bien séparés pour ne pas fatiguer l’utilisateur. Grâce à notre mise en page fluide, aucun changement CSS n’est nécessaire : il suffit d’organiser le HTML proprement, et les styles s’appliquent naturellement.
Nous pourrions éventuellement ajouter une classe form-section
pour regrouper les champs par catégorie (identité, sécurité, niveau), mais cela reste facultatif.
SEO : contenu optimisé pour la pages de formulaire d’inscription
Pour finir, nous ajoutons ce texte en-dessous du formulaire d’inscription, pour enrichir la page :
<main class="auth-page">
<section class="auth-container">
<h1><img class="img-theme-switch" src="<?= BASE_URL ?>assets/img/logo-crea-code-horizontal500x100.webp"
data-src-light="<?= BASE_URL ?>assets/img/logo-crea-code-horizontal500x100.webp"
data-src-dark="<?= BASE_URL ?>assets/img/logo-crea-code-horizontal-dark.webp"
alt="Logo Créa-code"
loading="lazy"></h1>
<hr>
<p><strong>L'inscription est gratuite</strong> et vous permet d'accéder à tous les parcours et exercices, de suivre vos progrès et de débloquer des challenges
selon votre niveau. Plus vous avancez, plus vous apprenez !</p>
<p><strong>Pas besoin d’être un expert</strong> : notre parcours est conçu pour vous guider pas à pas, avec des explications
claires et des exemples concrets afin d'apprendre de façon <strong>ludique</strong>.</p>
<form id="signupForm" action="<?= BASE_URL ?>register" method="POST" novalidate>
<input type="text" name="pseudo" id="pseudo" value="<?= $_SESSION['old']['pseudo'] ?? '' ?>" placeholder="Votre pseudo" required>
<input type="email" name="email" id="email" value="<?= $_SESSION['old']['email'] ?? '' ?>" placeholder="Votre mail" required>
<input type="password" name="password" id="password" placeholder="Mot de passe" required>
<input type="password" name="confirm_password" id="confirm_password" placeholder="Confirmer le mot de passe" required>
<select name="niveau" id="niveau">
<option value="">-- Choisissez un niveau --</option>
<option value="débutant" <?= ($_SESSION['old']['niveau'] ?? '') === 'débutant' ? 'selected' : '' ?>>Débutant</option>
<option value="intermédiaire" <?= ($_SESSION['old']['niveau'] ?? '') === 'intermédiaire' ? 'selected' : '' ?>>Intermédiaire</option>
<option value="expérimenté" <?= ($_SESSION['old']['niveau'] ?? '') === 'expérimenté' ? 'selected' : '' ?>>Expérimenté</option>
<option value="professionnel" <?= ($_SESSION['old']['niveau'] ?? '') === 'professionnel' ? 'selected' : '' ?>>Professionnel</option>
</select>
<?php if (!empty($_SESSION['errors'])) {
foreach ($_SESSION['errors'] as $error=>$e) {
echo '<div class="error-message">' . htmlspecialchars($e) . '</div>';
}
}
?>
<button class="btn btn-signin" type="submit">S'inscrire</button>
</form>
<p>Déjà inscrit ?<br><a href="<?= BASE_URL ?>login">Connectez-vous</a></p>
</section>
</main>
<script src="<?= BASE_URL ?>assets/js/signin-form-validation.js" defer></script>
Ces blocs enrichissent la page, renforcent le SEO grâce aux mots-clés (« compte », « progression », « exercices », etc.) et informent/rassurent l’utilisateur.

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 ?Faut-il indexer les pages de connexion et inscription ?
Non, ce n’est pas indispensable. Et dans la majorité des cas, il est même préférable de ne pas les indexer.
Objectif du SEO : attirer des visiteurs via Google
Les pages de connexion et d’inscription ont un rôle fonctionnel (accès au compte, création d’un profil), mais aucune valeur en termes de trafic organique. Ce ne sont pas des pages qui répondent à une intention de recherche du type :
- « apprendre le HTML gratuitement »
- « exercices de programmation interactifs »
- « cours de JavaScript pour débutant »
Ces intentions doivent pointer vers la page d’accueil, les pages de présentation, ou les articles de blog. Pas vers un formulaire.
Impact SEO négatif potentiel
Indexer ces pages peut même poser plusieurs problèmes :
- Contenu mince (thin content) : peu de texte unique, peu d’intérêt pour Google.
- Risques de duplication : si plusieurs URLs mènent à la même page de login (ex.
/login
,/connexion
,/account/login
, etc.). - Mauvaise expérience utilisateur : un visiteur qui arrive sur une page de connexion sans contexte peut être perdu, repartir aussitôt (hausse du taux de rebond).
- Spam & sécurité : certaines personnes malveillantes scrutent Google à la recherche d’URLs de connexion admin. Ce n’est pas dramatique mais mieux vaut limiter leur visibilité.
Pour les pages de connexion et inscription, la meilleure approche est :
<!-- À placer dans le <head> de la page -->
<meta name="robots" content="noindex, follow">
Cela indique aux moteurs de recherche :
- noindex : ne pas indexer la page dans les résultats de recherche.
- follow : mais suivre les liens internes présents sur cette page (ex. vers la page d’accueil, les CGU, le blog, etc.).
Tu peux aussi définir ça côté serveur (dans les en-têtes HTTP), ou via un fichier robots.txt
, mais la balise <meta>
est suffisante ici.
Tu peux utiliser les pages publiques (page d’accueil, blog, page “comment ça marche”, etc.) pour inciter les visiteurs à s’inscrire, tout en restant dans une logique SEO.
Par exemple :
« Inscrivez-vous gratuitement pour suivre votre progression, gagner des badges et débloquer les missions interactives. »
Ces pages-là ont un vrai potentiel SEO, contrairement à un simple formulaire.
Il va donc falloir afficher automatiquement la balise <meta name="robots" content="noindex, follow">
sur les pages login, inscription, mot de passe oublié, vérification du mail et erreur 404.
Ajouter une variable $meta_robots
dans le contrôleur
Dans le contrôleur app/Controller/LoginController.php :
public function index()
{
$meta_robots = 'noindex, follow';
View::render('login', compact('title', 'desc', 'errors', 'meta_robots'));
}
Pareil pour app/Controller/SigninController.php ou app/Controller/VerifyController.php.
Gérer dynamiquement la balise <meta>
dans le layout (vue globale)
Dans le fichier app/Views/layout.php
, entre les balises <head>
, on ajoute ceci :
<?php if (!empty($meta_robots)) : ?>
<meta name="robots" content="<?= htmlspecialchars($meta_robots) ?>">
<?php endif; ?>
Grâce à cette condition, la balise ne s’affiche que si elle est définie par le contrôleur.
Les valeurs possibles pour robots
Nous pourrons étendre cette logique plus tard à d’autres cas :
$meta_robots | Résultat |
---|---|
noindex, follow | Ne pas indexer, mais suivre les liens |
index, follow | Comportement par défaut |
noindex, nofollow | À éviter sauf cas extrêmes |
index, nofollow | Rarement utile |
La création d’un formulaire de connexion et d’inscription bien structuré ne se limite pas à l’esthétique : c’est un véritable enjeu d’ergonomie, de crédibilité et de performance web. En combinant une mise en page CSS moderne, responsive et accessible, avec une attention portée à l’optimisation SEO et à la clarté du contenu, nous améliorons à la fois l’expérience utilisateur et la qualité globale du site.
Ce jour 22 nous montre qu’un simple formulaire peut devenir un levier de confiance, un point d’entrée engageant, et un outil cohérent avec notre ambition d’un apprentissage web accessible à tous sur Créa-code.
La suite demain…