Постраничная навигация — ряд номеров под списком: «1 2 3 … Дальше». Устроена она просто, а ошибаются в ней обычно не в разметке, а в адресах страниц: именно из-за них сайт потом плохо выглядит в поиске.

Номера, «Показать ещё» или бесконечная лента

Три способа показать длинный список
Способ Когда подходит Чем плох
Номера страниц Каталог, архив, список статей: к записи возвращаются Лишний щелчок на каждой странице
Кнопка «Показать ещё» Список, который просматривают подряд На нужное место не вернуться по ссылке
Бесконечная лента Почти никогда: подвал сайта становится недостижим Ни закладки, ни поиска, ни подвала

Для сайта, который должен находиться в поиске, номера надёжнее всего: у каждой страницы свой адрес, и робот дойдёт до последней записи.

Разметка: список ссылок с отметкой текущей

Это навигация, значит <nav> с названием. Номера — список ссылок; текущий номер ссылкой не делается и помечается атрибутом aria-current="page".

Ряд номеров
<nav class="pager" aria-label="Страницы списка">
  <ul class="pager__list">
    <li><a class="pager__link" href="/novosti/" aria-label="Страница 1">1</a></li>
    <li>
      <span class="pager__link pager__link--current" aria-current="page">2</span>
    </li>
    <li><a class="pager__link" href="/novosti/?page=3" aria-label="Страница 3">3</a></li>
    <li aria-hidden="true">…</li>
    <li><a class="pager__link" href="/novosti/?page=9" aria-label="Страница 9">9</a></li>
  </ul>
</nav>

Атрибут aria-label у номеров нужен потому, что голая цифра ничего не сообщает: в списке ссылок страницы диктор прочитает «три, ссылка». А многоточие между номерами от программ чтения экрана прячется — оно оформление, а не содержание.

Размер кнопки — не меньше 44 пикселей

Номера обычно делают маленькими, и на телефоне в них невозможно попасть пальцем. Считается по площади нажатия целиком, вместе с внутренними отступами: 44×44 — общепринятый минимум.

Адреса страниц и поисковик

Первая страница списка обязана быть доступна по одному адресу, а не по двум. Если работают и /novosti/, и /novosti/?page=1, поисковик видит две одинаковые страницы и не знает, какую показывать.

  • Первая страница — /novosti/, без параметра.
  • На каждой странице — <link rel="canonical"> на саму себя, а не на первую: вторая страница списка не копия первой, у неё другие записи.
  • В sitemap.xml достаточно первой страницы списка: до остальных робот дойдёт по ссылкам.

Заголовок страницы должен отличаться

У всех страниц списка одинаковый <title> — частая ошибка. Добавляйте номер: «Новости — страница 2». Иначе в поиске девять одинаковых строк, и ни по одной не понять, куда она ведёт.

Что попросить у нейросети

Мой запрос

Нужен CSS для постраничной навигации. Разметка: тег nav, внутри список, в пунктах ссылки с номерами, текущая страница — span с aria-current="page", между далёкими номерами многоточие.

Вид: ряд по центру, каждая кнопка не меньше 44×44 пикселей, скруглённые углы, текущая выделена заливкой, наведение — только смена подложки и рамки. Цвета и отступы через CSS-переменные.

На узком экране ряд из девяти номеров не помещается. Предложи решение, которое не требует JavaScript, и объясни, почему выбрал именно его.

Ответ нейросети

Про узкий экран. Самое простое — прятать дальние номера медиавыражением, оставляя первую, последнюю, текущую и соседние. Разметка не меняется, JavaScript не нужен, а скрытые номера всё равно остаются в коде и достаются роботу.

Почему не перенос строки. Ряд номеров, переносящийся на три строки, читается как список ссылок, а не как переключатель страниц, и занимает пол-экрана.

Про размер. Задавайте min-width и min-height по 44 пикселя вместе с display: inline-flex и центрированием — тогда однозначная и двузначная кнопки одного размера, и ряд не дёргается при переходе с девятой страницы на десятую.

В Evolution CMS: страницы считает сниппет

Резать список на страницы руками не придётся: DocLister умеет это сам. Ему указывают, сколько записей на странице, и просят вывести ряд номеров — разметку ряда задаёт ваш чанк.

Список с постраничной навигацией
[[DocLister?
  &parents=`5`
  &display=`10`
  &tpl=`newsCard`
  &paginate=`pages`
  &TplPage=`pagerLink`
  &TplCurrentPage=`pagerCurrent`
]]

Чанки pagerLink и pagerCurrent — это один пункт ряда: обычный и текущий. Вёрстка снова ваша, сниппет только считает, сколько всего страниц и какая сейчас открыта.

Частые ошибки

Чем чаще всего ломают постраничную навигацию
Ошибка Чем плохо Как правильно
Первая страница доступна по двум адресам Поисковик видит две одинаковые страницы Первая — без параметра в адресе
Одинаковый заголовок у всех страниц В выдаче девять неразличимых строк Номер страницы в title
Текущий номер — ссылка на себя Переход в никуда и лишняя остановка при обходе span с aria-current="page"
Кнопки по 24 пикселя На телефоне в них не попасть пальцем Площадь нажатия не меньше 44×44
Номера подставляются скриптом в браузере Робот не видит ссылок и не доходит до записей Ряд номеров приходит с сервера, готовым

Что должно получиться

  • Под списком ряд номеров, текущий выделен и не является ссылкой
  • У каждой страницы списка свой адрес, первая — без параметра
  • Заголовок страницы содержит её номер
  • На телефоне ряд помещается в одну строку и кнопки нажимаются пальцем
  • По ссылкам можно дойти до последней записи без JavaScript