mirror of
https://codeberg.org/PostERG/xamxam.git
synced 2026-05-06 19:19:19 +02:00
Semantic HTML: home page card grid — <ul>/<li>/<figure>/<nav> refactor
Replace presentational divs in index.php and main.css with elements that carry correct semantic meaning, fixing multiple WCAG 2.1 AA issues: index.php: - <div class="cards-container"> → <ul class="cards-container"> (list of navigable items) - <a class="card-link"><div class="card">…</div></a> → <li class="card"><a> (block link is the <a>, <li> is the container; removes the redundant .card div wrapper) - <div class="card__media"> → <figure class="card__media"> when wrapping an <img>; gradient placeholder stays as <div> (presentational, aria-hidden) - Improved alt text: "Couverture — [title] par [authors]" instead of bare title - Removed <div class="card__info"> wrapper; caption is now a bare <p class="card__caption"> directly inside the <a> - <div class="filter-info"> → <p class="filter-info" role="status"> (live-region semantics; announces filter state to screen readers) - ✕ symbol in clear-filter link wrapped in <span aria-hidden="true"> - Gradient placeholder div gets aria-hidden="true" (decorative; caption below carries text) - Empty-state <p style="…"> → <li class="cards-empty"> (removes inline style) - <div class="pagination-wrap"> → <nav class="pagination-wrap" aria-label="Pagination"> with <ul>/<li> children; page-info <span> → <li aria-current="page"> main.css: - .cards-container: add list-style:none; margin:0; padding:0 (reset <ul> defaults) - Remove .card-link rule; replace with .card > a (block flex link, no separate class) - .card__media: add margin:0 to reset <figure> default margin - Remove .card__info rules; rename .authors to .card__caption with same styles - Add .cards-empty rule (removes last inline style from index.php) - .pagination-wrap: restructured for <nav>/<ul>; inner <ul> carries the flex layout - prefers-reduced-motion: add .card__media--gradient guard WCAG criteria addressed: 1.1.1 (alt text), 1.3.1 (info & relationships via semantic list/figure), 2.4.1 (filter-info now live region), role="status" on filter banner.
This commit is contained in:
137
public/index.php
137
public/index.php
@@ -69,89 +69,98 @@ $extraCss = ['assets/main.css'];
|
||||
<?php include APP_ROOT . '/templates/search-bar.php'; ?>
|
||||
|
||||
<?php if ($year): ?>
|
||||
<div class="filter-info">
|
||||
<p class="filter-info" role="status">
|
||||
Année : <?= htmlspecialchars($year) ?>
|
||||
<a href="index.php" class="clear-filter">✕ Réinitialiser</a>
|
||||
</div>
|
||||
<a href="index.php" class="clear-filter"><span aria-hidden="true">✕</span> Réinitialiser</a>
|
||||
</p>
|
||||
<?php elseif ($isDefaultView && !empty($latestYear)): ?>
|
||||
<div class="filter-info home-latest-label">
|
||||
<p class="filter-info home-latest-label" role="status">
|
||||
Découvrez les TFE de <?= (int)$latestYear ?> — sélection aléatoire
|
||||
</div>
|
||||
</p>
|
||||
<?php endif; ?>
|
||||
|
||||
<main class="home-main" id="main-content">
|
||||
<div class="cards-container">
|
||||
<ul class="cards-container">
|
||||
<?php foreach ($itemsToLoad as $item): ?>
|
||||
<a href="tfe.php?id=<?= (int)$item["id"] ?>" class="card-link">
|
||||
<div class="card">
|
||||
<div class="card__media">
|
||||
<?php
|
||||
// Resolve thumbnail: banner_path → cover file → gradient placeholder
|
||||
$thumb = null;
|
||||
<li class="card">
|
||||
<a href="tfe.php?id=<?= (int)$item["id"] ?>">
|
||||
<?php
|
||||
// Resolve thumbnail: banner_path → cover file → gradient placeholder
|
||||
$thumb = null;
|
||||
|
||||
// 1. Banner path (dedicated home thumbnail)
|
||||
if (!empty($item['banner_path'])) {
|
||||
$thumb = $item['banner_path'];
|
||||
}
|
||||
// 1. Banner path (dedicated home thumbnail)
|
||||
if (!empty($item['banner_path'])) {
|
||||
$thumb = $item['banner_path'];
|
||||
}
|
||||
|
||||
// 2. Cover image from thesis_files (batch-loaded above)
|
||||
if (!$thumb && isset($coverMap[$item['id']])) {
|
||||
$thumb = $coverMap[$item['id']];
|
||||
}
|
||||
// 2. Cover image from thesis_files (batch-loaded above)
|
||||
if (!$thumb && isset($coverMap[$item['id']])) {
|
||||
$thumb = $coverMap[$item['id']];
|
||||
}
|
||||
|
||||
// 3. Fall through to gradient
|
||||
?>
|
||||
<?php if ($thumb): ?>
|
||||
// 3. Fall through to gradient
|
||||
?>
|
||||
<?php if ($thumb): ?>
|
||||
<figure class="card__media">
|
||||
<img src="/media.php?path=<?= urlencode($thumb) ?>"
|
||||
alt="<?= htmlspecialchars($item['title']) ?>"
|
||||
alt="Couverture — <?= htmlspecialchars($item['title']) ?> par <?= htmlspecialchars($item['authors'] ?? '') ?>"
|
||||
loading="lazy">
|
||||
<?php else: ?>
|
||||
<?php
|
||||
$hue = ($item['id'] * 47 + 160) % 360;
|
||||
$hue2 = ($hue + 40) % 360;
|
||||
?>
|
||||
<div class="card__media--gradient"
|
||||
style="background:linear-gradient(135deg,hsl(<?= $hue ?>,55%,40%),hsl(<?= $hue2 ?>,50%,28%));">
|
||||
<span class="card__gradient-author"><?= htmlspecialchars($item['authors'] ?? '') ?></span>
|
||||
<span class="card__gradient-title"><?= htmlspecialchars($item['title']) ?></span>
|
||||
</div>
|
||||
<?php endif; ?>
|
||||
</div>
|
||||
<div class="card__info">
|
||||
<p class="authors"><?= htmlspecialchars($item["authors"] ?? '') ?><?php if (!empty($item['authors']) && !empty($item['title'])): ?> – <?php endif; ?><?= htmlspecialchars($item["title"]) ?></p>
|
||||
</div>
|
||||
</div>
|
||||
</a>
|
||||
</figure>
|
||||
<?php else: ?>
|
||||
<?php
|
||||
$hue = ($item['id'] * 47 + 160) % 360;
|
||||
$hue2 = ($hue + 40) % 360;
|
||||
?>
|
||||
<div class="card__media card__media--gradient"
|
||||
style="background:linear-gradient(135deg,hsl(<?= $hue ?>,55%,40%),hsl(<?= $hue2 ?>,50%,28%));"
|
||||
aria-hidden="true">
|
||||
<span class="card__gradient-author"><?= htmlspecialchars($item['authors'] ?? '') ?></span>
|
||||
<span class="card__gradient-title"><?= htmlspecialchars($item['title']) ?></span>
|
||||
</div>
|
||||
<?php endif; ?>
|
||||
<p class="card__caption"><?= htmlspecialchars($item["authors"] ?? '') ?><?php if (!empty($item['authors']) && !empty($item['title'])): ?> – <?php endif; ?><?= htmlspecialchars($item["title"]) ?></p>
|
||||
</a>
|
||||
</li>
|
||||
<?php endforeach; ?>
|
||||
|
||||
<?php if (empty($itemsToLoad)): ?>
|
||||
<p style="padding:2rem;color:#666;">Aucun mémoire trouvé.</p>
|
||||
<li class="cards-empty">Aucun mémoire trouvé.</li>
|
||||
<?php endif; ?>
|
||||
</div>
|
||||
</ul>
|
||||
|
||||
<?php if ($totalPages > 1): ?>
|
||||
<div class="pagination-wrap">
|
||||
<nav class="pagination-wrap" aria-label="Pagination">
|
||||
<?php $yearParam = $year ? '&year=' . (int)$year : ''; ?>
|
||||
<a href="?page=1<?= $yearParam ?>"
|
||||
class="pagination-btn <?= $page <= 1 ? 'disabled' : '' ?>"
|
||||
<?= $page <= 1 ? 'aria-disabled="true" tabindex="-1"' : '' ?>
|
||||
aria-label="Première page">«</a>
|
||||
<a href="?page=<?= max(1, $page - 1) . $yearParam ?>"
|
||||
class="pagination-btn <?= $page <= 1 ? 'disabled' : '' ?>"
|
||||
<?= $page <= 1 ? 'aria-disabled="true" tabindex="-1"' : '' ?>
|
||||
aria-label="Page précédente">‹</a>
|
||||
<span class="pagination-info">
|
||||
<span class="page-current"><?= $page ?></span> / <?= $totalPages ?>
|
||||
</span>
|
||||
<a href="?page=<?= min($totalPages, $page + 1) . $yearParam ?>"
|
||||
class="pagination-btn <?= $page >= $totalPages ? 'disabled' : '' ?>"
|
||||
<?= $page >= $totalPages ? 'aria-disabled="true" tabindex="-1"' : '' ?>
|
||||
aria-label="Page suivante">›</a>
|
||||
<a href="?page=<?= $totalPages . $yearParam ?>"
|
||||
class="pagination-btn <?= $page >= $totalPages ? 'disabled' : '' ?>"
|
||||
<?= $page >= $totalPages ? 'aria-disabled="true" tabindex="-1"' : '' ?>
|
||||
aria-label="Dernière page">»</a>
|
||||
</div>
|
||||
<ul>
|
||||
<li>
|
||||
<a href="?page=1<?= $yearParam ?>"
|
||||
class="pagination-btn <?= $page <= 1 ? 'disabled' : '' ?>"
|
||||
<?= $page <= 1 ? 'aria-disabled="true" tabindex="-1"' : '' ?>
|
||||
aria-label="Première page">«</a>
|
||||
</li>
|
||||
<li>
|
||||
<a href="?page=<?= max(1, $page - 1) . $yearParam ?>"
|
||||
class="pagination-btn <?= $page <= 1 ? 'disabled' : '' ?>"
|
||||
<?= $page <= 1 ? 'aria-disabled="true" tabindex="-1"' : '' ?>
|
||||
aria-label="Page précédente">‹</a>
|
||||
</li>
|
||||
<li class="pagination-info" aria-current="page">
|
||||
<span class="page-current"><?= $page ?></span> / <?= $totalPages ?>
|
||||
</li>
|
||||
<li>
|
||||
<a href="?page=<?= min($totalPages, $page + 1) . $yearParam ?>"
|
||||
class="pagination-btn <?= $page >= $totalPages ? 'disabled' : '' ?>"
|
||||
<?= $page >= $totalPages ? 'aria-disabled="true" tabindex="-1"' : '' ?>
|
||||
aria-label="Page suivante">›</a>
|
||||
</li>
|
||||
<li>
|
||||
<a href="?page=<?= $totalPages . $yearParam ?>"
|
||||
class="pagination-btn <?= $page >= $totalPages ? 'disabled' : '' ?>"
|
||||
<?= $page >= $totalPages ? 'aria-disabled="true" tabindex="-1"' : '' ?>
|
||||
aria-label="Dernière page">»</a>
|
||||
</li>
|
||||
</ul>
|
||||
</nav>
|
||||
<?php endif; ?>
|
||||
</main>
|
||||
|
||||
|
||||
Reference in New Issue
Block a user