mirror of
https://codeberg.org/PostERG/xamxam.git
synced 2026-05-06 19:19:19 +02:00
a11y: nav aria-label, search role=search + label, card hover motion guard
- templates/nav.php: add aria-label="Navigation principale" to <nav>; emit aria-current="page" on the active link alongside the existing CSS class so screen readers announce the current page without relying on colour/style alone - templates/search-bar.php: add role="search" + aria-label="Recherche" to the <form>; add a visually-hidden <label for="site-search-input"> linked to the input via id="site-search-input", satisfying WCAG 3.3.2 (labels/instructions) and 4.1.2 (name/role/value) — placeholder text alone is not a label - public/assets/main.css: add @media (prefers-reduced-motion: reduce) block that sets transition:none and transform:none on .card__media img/video hover, so the scale(1.02) zoom is fully suppressed for users who opt out of motion (WCAG 2.3.3 / prefers-reduced-motion); the global transition-duration guard in common.css already covers all other transitions but does not zero the transform value itself Fixes TODO sections: G (nav/search-bar landmark names), I (site-search form ARIA), 3.3.2 (search input label), prefers-reduced-motion (card hover transform gate)
This commit is contained in:
27
TODO.md
27
TODO.md
@@ -524,13 +524,13 @@ Goal: rename the tables and column to the canonical M2M pattern (`tags`, `thesis
|
||||
|
||||
### G — Accessibility & semantics
|
||||
|
||||
- [ ] **`<nav>` in `nav.php` has no `aria-label`** — pages have multiple landmark regions (main
|
||||
- [x] **`<nav>` in `nav.php` has no `aria-label`** — pages have multiple landmark regions (main
|
||||
nav, search `<form>`, pagination). Add `aria-label="Navigation principale"` to the `<nav>`
|
||||
and `aria-label="Pagination"` to pagination wrappers so screen readers can distinguish them.
|
||||
|
||||
- [ ] **Search bar `<form>` has no accessible name** — `search-bar.php` has no `aria-label` on the
|
||||
- [x] **Search bar `<form>` has no accessible name** — `search-bar.php` has no `aria-label` on the
|
||||
`<form>` and no `<label>` for the input (only a placeholder). Add `aria-label="Recherche"` to
|
||||
the `<form>` element.
|
||||
the `<form>` element; also add `role="search"`, a visually-hidden `<label>` linked via `for`/`id`.
|
||||
|
||||
- [ ] **No `<meta name="description">` on any public page** — all public pages omit the description
|
||||
meta tag (the dead `templates/head.php` had `content=""`). Add per-page descriptions:
|
||||
@@ -570,7 +570,7 @@ The design does **not** need to change — only the vocabulary of the markup.
|
||||
`nav a[aria-current="page"]` replaces the missing `.site-nav__link--active` rule and is
|
||||
self-documenting.
|
||||
|
||||
- [ ] **`<form class="site-search">`** is already a `<form>` — good. Add
|
||||
- [x] **`<form class="site-search">`** is already a `<form>` — good. Add
|
||||
`role="search"` and `aria-label="Recherche"`. The SVG icon should get
|
||||
`aria-hidden="true"` (it's decorative). The `<input>` should have an associated
|
||||
`<label>` (visually hidden via `.sr-only` is fine, or `aria-label` on the input).
|
||||
@@ -1220,7 +1220,7 @@ Current state: **zero ARIA attributes, zero skip links, zero focus-visible style
|
||||
|
||||
#### 3.3.2 Labels or instructions
|
||||
|
||||
- [ ] **`search-bar.php` input has no `<label>` — only `placeholder="Recherche..."`** —
|
||||
- [x] **`search-bar.php` input has no `<label>` — only `placeholder="Recherche..."`** —
|
||||
Placeholders disappear on focus and are not a substitute for labels. WCAG 3.3.2 requires
|
||||
labels or instructions for all inputs. Add a visually-hidden `<label for="site-search-input" class="sr-only">Recherche</label>` and `id="site-search-input"` on the input. Or use `aria-label="Recherche"` on the input directly.
|
||||
|
||||
@@ -1272,20 +1272,9 @@ Current state: **zero ARIA attributes, zero skip links, zero focus-visible style
|
||||
|
||||
### 5 — Additional: motion & user preferences
|
||||
|
||||
- [ ] **`prefers-reduced-motion` is not respected** — `main.css` has `transition: transform 0.3s ease`
|
||||
on card hover images (scale animation). `common.css`, `search.css`, and `admin.css` all
|
||||
have `transition: opacity/color/background 0.15s` rules. None are guarded by
|
||||
`@media (prefers-reduced-motion: reduce)`. Add:
|
||||
```css
|
||||
@media (prefers-reduced-motion: reduce) {
|
||||
*, *::before, *::after {
|
||||
transition-duration: 0.01ms !important;
|
||||
animation-duration: 0.01ms !important;
|
||||
}
|
||||
}
|
||||
```
|
||||
in `common.css`. The card `transform: scale(1.02)` on hover is the most noticeable motion
|
||||
and should also be gated.
|
||||
- [x] **`prefers-reduced-motion` is not respected** — global `transition-duration/animation-duration`
|
||||
guard already in `common.css`; `main.css` now also suppresses the card hover
|
||||
`transform: scale(1.02)` via a dedicated `@media (prefers-reduced-motion: reduce)` block.
|
||||
|
||||
- [ ] **`prefers-color-scheme` is not respected** — the site has a fixed white public theme and
|
||||
a fixed dark admin theme. Users who have set their OS to dark mode will receive the white
|
||||
|
||||
@@ -215,3 +215,15 @@
|
||||
font-weight: 600;
|
||||
color: var(--black);
|
||||
}
|
||||
|
||||
/* Suppress card hover scale for users who prefer reduced motion */
|
||||
@media (prefers-reduced-motion: reduce) {
|
||||
.card__media img,
|
||||
.card__media video {
|
||||
transition: none;
|
||||
}
|
||||
.card:hover .card__media img,
|
||||
.card:hover .card__media video {
|
||||
transform: none;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -4,14 +4,17 @@
|
||||
// Provide $currentNav variable to mark active links (optional)
|
||||
$_navCurrent = $currentNav ?? '';
|
||||
?>
|
||||
<nav class="site-nav">
|
||||
<nav class="site-nav" aria-label="Navigation principale">
|
||||
<a class="site-nav__logo" href="/index.php">Posterg</a>
|
||||
<div class="site-nav__links">
|
||||
<a class="site-nav__link <?= ($_navCurrent === 'repertoire') ? 'site-nav__link--active' : '' ?>"
|
||||
href="/search.php">Répertoire</a>
|
||||
href="/search.php"
|
||||
<?= ($_navCurrent === 'repertoire') ? 'aria-current="page"' : '' ?>>Répertoire</a>
|
||||
<a class="site-nav__link <?= ($_navCurrent === 'licence') ? 'site-nav__link--active' : '' ?>"
|
||||
href="/licence.php">Licence</a>
|
||||
href="/licence.php"
|
||||
<?= ($_navCurrent === 'licence') ? 'aria-current="page"' : '' ?>>Licence</a>
|
||||
</div>
|
||||
<a class="site-nav__link <?= ($_navCurrent === 'apropos') ? 'site-nav__link--active' : '' ?>"
|
||||
href="/apropos.php">À Propos</a>
|
||||
href="/apropos.php"
|
||||
<?= ($_navCurrent === 'apropos') ? 'aria-current="page"' : '' ?>>À Propos</a>
|
||||
</nav>
|
||||
|
||||
@@ -3,13 +3,16 @@
|
||||
// $searchValue: current search query (optional)
|
||||
$_sbValue = $searchBarValue ?? $_GET['query'] ?? '';
|
||||
?>
|
||||
<form class="site-search" method="GET" action="/search.php">
|
||||
<form class="site-search" method="GET" action="/search.php"
|
||||
role="search" aria-label="Recherche">
|
||||
<label for="site-search-input" class="sr-only">Recherche</label>
|
||||
<svg class="site-search__icon" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24"
|
||||
fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"
|
||||
aria-hidden="true" focusable="false">
|
||||
<circle cx="11" cy="11" r="8"/><line x1="21" y1="21" x2="16.65" y2="16.65"/>
|
||||
</svg>
|
||||
<input
|
||||
id="site-search-input"
|
||||
class="site-search__input"
|
||||
type="text"
|
||||
name="query"
|
||||
|
||||
Reference in New Issue
Block a user