Habille enfin les liens du menu : NavLink échappe à l'isolation CSS
Les six entrées restaient en bleu souligné par défaut : l'isolation CSS de Blazor ne pose son attribut de portée que sur le balisage du composant courant, jamais sur ce que rend un composant enfant. NavLink étant un composant, `.menu-lien` déclaré dans MainLayout.razor.css ne correspondait à aucun élément — alors que `.menu` et `.bandeau`, du balisage propre, étaient bien habillés. Les règles du menu passent en feuille globale plutôt qu'en `::deep` : la navigation ne dépend plus du bundle d'isolation ni de son cache, qui est précisément le fichier déjà vu servi périmé ou absent. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This commit is contained in:
@@ -2184,6 +2184,47 @@ un clic sur « Auteurs » laissait les six entrées empilées au-dessus de la li
|
|||||||
Conséquence sur `app.css` : `--mb-onglets-hauteur` **a disparu**, et `.actions-flottantes`
|
Conséquence sur `app.css` : `--mb-onglets-hauteur` **a disparu**, et `.actions-flottantes`
|
||||||
se pose directement en `bottom: 0`. Plus rien ne l'accompagne en bas de l'écran.
|
se pose directement en `bottom: 0`. Plus rien ne l'accompagne en bas de l'écran.
|
||||||
|
|
||||||
|
### ⚠️ Les liens du menu n'étaient atteints par AUCUNE règle — `NavLink` est un composant
|
||||||
|
|
||||||
|
Symptôme remonté deux fois, la seconde capture d'écran à l'appui : « toujours les liens trop
|
||||||
|
moches et pas ressemblant à un menu ». Le `<nav>` prenait bien son fond bleu sombre, et les six
|
||||||
|
entrées restaient en **bleu Bootstrap souligné**, empilées sans marge — l'aspect exact d'un
|
||||||
|
`<a>` sans style.
|
||||||
|
|
||||||
|
**Ce n'était pas un cache, contrairement aux deux défauts précédents** (lot A1, icône du
|
||||||
|
bandeau), et c'est ce qui a fait perdre du temps : la feuille scopée était bien chargée, elle
|
||||||
|
habillait le bandeau juste au-dessus.
|
||||||
|
|
||||||
|
La cause est une règle de l'isolation CSS de Blazor :
|
||||||
|
|
||||||
|
> l'attribut de portée (`b-xxxx`) n'est posé que sur les éléments écrits dans le balisage du
|
||||||
|
> composant courant — **jamais sur ce que rend un composant enfant**.
|
||||||
|
|
||||||
|
`NavLink` **est un composant**. `.menu-lien` déclaré dans `MainLayout.razor.css` devenait
|
||||||
|
`.menu-lien[b-xxxx]`, et l'`<a>` rendu par `NavLink` ne porte pas cet attribut : la règle ne
|
||||||
|
correspondait à rien. `.menu` et `.bandeau`, eux, sont du balisage propre au composant, d'où le
|
||||||
|
fond sombre présent et les liens nus. C'est précisément pour cela que le gabarit Blazor par
|
||||||
|
défaut écrit ses règles de navigation avec `::deep`.
|
||||||
|
|
||||||
|
**Correction retenue : les règles du menu passent en feuille GLOBALE** (`wwwroot/css/app.css`),
|
||||||
|
plutôt que `::deep`. Les deux corrigent le bug ; la feuille globale corrige en plus une
|
||||||
|
fragilité connue — la navigation ne dépend alors ni du bundle `MaBibli.Client.styles.css` ni de
|
||||||
|
son cache, c'est-à-dire du fichier même qu'un appareil a déjà servi périmé ou pas du tout. **La
|
||||||
|
navigation est ce qui doit le moins pouvoir tomber.**
|
||||||
|
|
||||||
|
⚠️ Le point de rupture de **40 rem** est désormais écrit à **deux endroits** : `app.css` (le
|
||||||
|
menu passe en rangée) et `MainLayout.razor.css` (la bascule se masque — elle, c'est du balisage
|
||||||
|
propre, donc scopable). Les deux doivent rester identiques.
|
||||||
|
|
||||||
|
**Règle à retenir au-delà de ce cas** : toute règle scopée visant un élément rendu par un
|
||||||
|
composant enfant (`NavLink`, et tout composant du projet) est morte-née. Soit `::deep`, soit la
|
||||||
|
feuille globale.
|
||||||
|
|
||||||
|
Vérifié en exécution, styles calculés à l'appui : à 375 px, menu déployé, liens en `#e8edf3`,
|
||||||
|
`text-decoration: none`, 45 px de haut, l'entrée active en blanc gras avec sa bordure jaune ; à
|
||||||
|
1280 px, rangée horizontale centrée (six liens sur la même ligne à y = 55) et bascule
|
||||||
|
`display: none`, sans débordement horizontal.
|
||||||
|
|
||||||
### Un retour explicite dans le bandeau
|
### Un retour explicite dans le bandeau
|
||||||
|
|
||||||
« Le déplacement est foireux » : d'un écran profond (bibliographie, fiche de tome, ajout
|
« Le déplacement est foireux » : d'un écran profond (bibliographie, fiche de tome, ajout
|
||||||
|
|||||||
@@ -109,81 +109,29 @@
|
|||||||
padding: 1rem 1rem 6rem;
|
padding: 1rem 1rem 6rem;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* --- Menu principal --- */
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
Repli du gabarit Blazor par défaut : sur téléphone, la liste est masquée et se déploie
|
⚠️ Les styles du MENU ne sont PAS ici, mais dans `wwwroot/css/app.css`.
|
||||||
au clic sur la bascule ; sur PC elle devient une rangée sous le bandeau.
|
|
||||||
|
|
||||||
⚠️ Le défaut de la version précédente (six onglets en `flex: 1 1 0` sur une barre fixe)
|
Deux raisons, la première étant un vrai bug corrigé le 2026-08-20 :
|
||||||
était qu'elle n'avait AUCUN état de repli : dès que la place manquait — ou que la feuille
|
|
||||||
de style scopée n'était pas celle attendue — les six libellés se retrouvaient collés,
|
1. `NavLink` est un COMPOSANT. L'isolation CSS ne pose son attribut de portée (`b-xxxx`)
|
||||||
tronqués ou empilés sans mise en forme. Ici, l'état sans style est une liste de liens.
|
que sur les éléments écrits dans le balisage du composant courant — jamais sur ce que
|
||||||
|
rend un composant enfant. `.menu-lien` déclaré ici ne pouvait donc atteindre AUCUN des
|
||||||
|
six liens : le `<nav>` recevait bien son fond sombre, et les liens restaient en bleu
|
||||||
|
souligné par défaut. C'est exactement ce que l'utilisateur voyait (« toujours les liens
|
||||||
|
trop moches et pas ressemblant à un menu »). Le gabarit Blazor par défaut contourne cela
|
||||||
|
avec `::deep`.
|
||||||
|
2. Une feuille globale ne dépend pas du bundle `MaBibli.Client.styles.css`, qui est
|
||||||
|
précisément le fichier qu'un cache a déjà servi périmé ou pas du tout (voir « lot A1 »
|
||||||
|
et « L'icône cassée du bandeau » dans CLAUDE.md). La navigation est ce qui doit le moins
|
||||||
|
pouvoir tomber.
|
||||||
*/
|
*/
|
||||||
.menu {
|
|
||||||
display: none;
|
|
||||||
flex-direction: column;
|
|
||||||
background: #16304c;
|
|
||||||
border-bottom: 1px solid rgba(255, 255, 255, 0.15);
|
|
||||||
}
|
|
||||||
|
|
||||||
.menu-ouvert {
|
|
||||||
display: flex;
|
|
||||||
}
|
|
||||||
|
|
||||||
.menu-lien {
|
|
||||||
display: block;
|
|
||||||
padding: 0.7rem 1rem;
|
|
||||||
color: #e8edf3;
|
|
||||||
text-decoration: none;
|
|
||||||
font-size: 0.95rem;
|
|
||||||
border-left: 4px solid transparent;
|
|
||||||
}
|
|
||||||
|
|
||||||
.menu-lien:hover,
|
|
||||||
.menu-lien:focus-visible {
|
|
||||||
background: rgba(255, 255, 255, 0.1);
|
|
||||||
color: #fff;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* NavLink pose « active » tout seul ; « Catalogue » utilise NavLinkMatch.All, sans quoi
|
|
||||||
il resterait allumé sur toutes les pages — son href est la racine. */
|
|
||||||
.menu-lien.active {
|
|
||||||
color: #fff;
|
|
||||||
font-weight: 600;
|
|
||||||
background: rgba(255, 255, 255, 0.16);
|
|
||||||
border-left-color: #f5d76e;
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
|
||||||
À partir de 40rem la rangée tient sans se comprimer, et la bascule n'a plus de raison
|
|
||||||
d'être : le menu est toujours visible, l'état déployé n'a plus d'effet.
|
|
||||||
|
|
||||||
Le point de rupture est à 40rem plutôt qu'aux 48rem du reste de la feuille : six libellés
|
|
||||||
courts tiennent bien avant que la grille de cartes ne s'élargisse, et les garder cachés
|
|
||||||
derrière une bascule sur une tablette serait un clic de trop.
|
|
||||||
*/
|
|
||||||
@media (min-width: 40rem) {
|
@media (min-width: 40rem) {
|
||||||
.menu {
|
/* La rangée du menu est visible en permanence à partir de cette largeur : la bascule
|
||||||
display: flex;
|
n'a plus rien à déployer. Le point de rupture est répété dans `app.css` — les deux
|
||||||
flex-direction: row;
|
doivent rester identiques. */
|
||||||
justify-content: center;
|
|
||||||
gap: 0.25rem;
|
|
||||||
padding: 0 0.5rem;
|
|
||||||
}
|
|
||||||
|
|
||||||
.bandeau-bascule {
|
.bandeau-bascule {
|
||||||
display: none;
|
display: none;
|
||||||
}
|
}
|
||||||
|
|
||||||
.menu-lien {
|
|
||||||
padding: 0.6rem 0.9rem;
|
|
||||||
border-left: 0;
|
|
||||||
border-bottom: 3px solid transparent;
|
|
||||||
}
|
|
||||||
|
|
||||||
.menu-lien.active {
|
|
||||||
background: rgba(255, 255, 255, 0.12);
|
|
||||||
border-bottom-color: #f5d76e;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1302,3 +1302,84 @@ body {
|
|||||||
font-weight: 600;
|
font-weight: 600;
|
||||||
font-size: 0.9rem;
|
font-size: 0.9rem;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* ------------------------------------------------------------------
|
||||||
|
Menu principal (bandeau)
|
||||||
|
|
||||||
|
⚠️ Ces règles sont ICI, en feuille GLOBALE, et non dans
|
||||||
|
`Layout/MainLayout.razor.css`. Deux raisons :
|
||||||
|
|
||||||
|
1. `NavLink` est un composant : l'isolation CSS ne pose son attribut de
|
||||||
|
portée que sur le balisage du composant courant, jamais sur ce que rend
|
||||||
|
un composant enfant. Déclarés en feuille scopée, `.menu-lien` n'atteignait
|
||||||
|
AUCUN des six liens — le `<nav>` prenait son fond sombre, les liens
|
||||||
|
restaient en bleu souligné par défaut.
|
||||||
|
2. La navigation ne doit dépendre ni du bundle d'isolation ni de son cache.
|
||||||
|
|
||||||
|
Le repli sans style reste une suite de liens lisibles les uns sous les
|
||||||
|
autres : c'est tout l'intérêt du gabarit retenu le 2026-08-20.
|
||||||
|
------------------------------------------------------------------ */
|
||||||
|
|
||||||
|
.menu {
|
||||||
|
display: none;
|
||||||
|
flex-direction: column;
|
||||||
|
background: #16304c;
|
||||||
|
border-bottom: 1px solid rgba(255, 255, 255, 0.15);
|
||||||
|
}
|
||||||
|
|
||||||
|
.menu-ouvert {
|
||||||
|
display: flex;
|
||||||
|
}
|
||||||
|
|
||||||
|
.menu-lien {
|
||||||
|
display: block;
|
||||||
|
padding: 0.7rem 1rem;
|
||||||
|
color: #e8edf3;
|
||||||
|
text-decoration: none;
|
||||||
|
font-size: 0.95rem;
|
||||||
|
font-weight: 500;
|
||||||
|
border-left: 4px solid transparent;
|
||||||
|
}
|
||||||
|
|
||||||
|
.menu-lien:hover,
|
||||||
|
.menu-lien:focus-visible {
|
||||||
|
background: rgba(255, 255, 255, 0.1);
|
||||||
|
color: #fff;
|
||||||
|
text-decoration: none;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* NavLink pose « active » tout seul ; « Catalogue » utilise NavLinkMatch.All,
|
||||||
|
sans quoi il resterait allumé sur toutes les pages — son href est la racine. */
|
||||||
|
.menu-lien.active {
|
||||||
|
color: #fff;
|
||||||
|
font-weight: 600;
|
||||||
|
background: rgba(255, 255, 255, 0.16);
|
||||||
|
border-left-color: #f5d76e;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
À partir de 40rem la rangée tient sans se comprimer, et la bascule n'a plus
|
||||||
|
de raison d'être. Le point de rupture est répété dans `MainLayout.razor.css`
|
||||||
|
(qui y masque la bascule) — les deux doivent rester identiques.
|
||||||
|
*/
|
||||||
|
@media (min-width: 40rem) {
|
||||||
|
.menu {
|
||||||
|
display: flex;
|
||||||
|
flex-direction: row;
|
||||||
|
justify-content: center;
|
||||||
|
flex-wrap: wrap;
|
||||||
|
gap: 0.25rem;
|
||||||
|
padding: 0 0.5rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
.menu-lien {
|
||||||
|
padding: 0.6rem 0.9rem;
|
||||||
|
border-left: 0;
|
||||||
|
border-bottom: 3px solid transparent;
|
||||||
|
}
|
||||||
|
|
||||||
|
.menu-lien.active {
|
||||||
|
background: rgba(255, 255, 255, 0.12);
|
||||||
|
border-bottom-color: #f5d76e;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user