Вход на сайт

Просмотр новости

Найдите то, что Вас интересует

Кнопка «наверх» в Django: почему в проде это уже не три строки JavaScript

Дата публикации: 01-07-2026 16:01:00

Как добавить кнопку «наверх» в Django-сайт и Django Admin: настройка, CSP, доступность, мобильная версия и работа рядом с cookie-баннерами.— Читать дальше «Кнопка «наверх» в Django: почему в проде это уже не три строки JavaScript»

Основное содержимое страницы с новостью.

Как сделать scroll-to-top для сайта и Django Admin, не забыв про мобильные устройства, CSP, доступность, плавающие виджеты и нормальную настройку без правки шаблонов.

На первый взгляд кнопка «наверх» — задача на пять минут. Добавил position: fixed, обработчик window.scrollTo() — готово.

Но стоит этой кнопке появиться в живом проекте, как выясняется, что она пересекается с cookie-баннером, мешает чату поддержки, выглядит иначе в мобильной версии, не дружит со строгим CSP или пропадает из Django Admin.

В итоге маленькая UI-деталь начинает обрастать условиями. Я решил собрать их в отдельный Django-пакет — django-scroll-to-top

Пример кнопки "Наверх" на демо сайте

Пример кнопки "Наверх" на демо сайте

Для небольшого сайта, где нет сложной верстки, админки, CSP и требований к повторному использованию, самый простой вариант действительно выглядит примерно так:

			<button id="back-to-top" type="button">↑</button>

<script>
  document.querySelector("#back-to-top").addEventListener("click", () => {
    window.scrollTo({ top: 0, behavior: "smooth" });
  });
</script>
		

Это нормальное решение. Не всегда стоит тянуть пакет ради одной кнопки.

Но в реальном Django-проекте быстро появляются дополнительные вопросы:

  • когда именно показывать кнопку: после 300 пикселей, одного экрана или только при прокрутке вверх;
  • что делать на коротких страницах;
  • как не перекрыть cookie-баннер, чат, toast-уведомления или нижнюю мобильную навигацию;
  • как дать пользователю закрыть кнопку;
  • как не сломать клавиатурную навигацию и режим reduced motion;
  • как сделать отдельное оформление для сайта и Django Admin;
  • как не заставлять проект добавлять unsafe-inline в Content Security Policy;
  • как позволить редактору или администратору изменить цвет, положение и иконку без нового деплоя.

Именно в этот момент «три строки JavaScript» превращаются в отдельный компонент.

Что я хотел получить

Цель была не в том, чтобы сделать ещё одну стрелку в правом нижнем углу. Хотелось собрать переиспользуемый компонент со следующими свойствами:

  1. Подключение сайта одной template-тегом.
  2. Отдельная поддержка обычных страниц и стандартного Django Admin.
  3. Настройка внешнего вида через админку, а не через постоянную правку CSS.
  4. Без jQuery, CDN, фронтенд-фреймворка и обязательной сборки.
  5. Безопасная работа при строгой CSP.
  6. Прогрессивное улучшение: без JavaScript остаётся обычная ссылка в начало страницы.
  7. Возможность жить рядом с другими фиксированными элементами интерфейса.

Пакет в итоге хранит обычные настройки установки в settings.py, а визуальное поведение — в базе данных. Это позволяет менять кнопку через Django Admin, публиковать новую версию настроек и при необходимости откатываться на предыдущую. В проекте есть отдельные профили для публичного сайта и Django Admin, а ревизии могут быть черновыми, опубликованными или архивными.

Быстрое подключение

Базовый сценарий начинается с установки:

			python -m pip install django-scroll-to-top
python manage.py migrate
		

В settings.py добавляем приложение. Если нужна поддержка стандартной админки, пакет должен идти раньше django.contrib.admin:

			INSTALLED_APPS = [
    "django_scroll_to_top",
    "django.contrib.admin",
    "django.contrib.auth",
    "django.contrib.contenttypes",
    "django.contrib.sessions",
    "django.contrib.messages",
    "django.contrib.staticfiles",
]
		

Включаем области, где должна работать кнопка:

			DJANGO_SCROLL_TO_TOP = {
    "SITE_ENABLED": True,
    "ADMIN_ENABLED": True,
}
		

Для публичной части добавляем URLConf пакета:

			from django.urls import include, path

urlpatterns = [
    path(
        "scroll-to-top/",
        include(
            ("django_scroll_to_top.urls", "django_scroll_to_top"),
            namespace="django_scroll_to_top",
        ),
    ),
]
		

А в общий шаблон сайта — один тег:

			{% load scroll_to_top %}

<!doctype html>
<html lang="ru">
<head>
    ...
</head>
<body>
    {% block content %}{% endblock %}

    {% scroll_to_top %}
</body>
</html>
		

На стандартном Django Admin ничего дополнительно вставлять не нужно: пакет использует обычный механизм разрешения шаблонов Django. Если же в проекте переопределён admin/base_site.html тег можно добавить вручную в блок footer

			{% extends "admin/base.html" %}
{% load scroll_to_top %}

{% block footer %}
  {{ block.super }}
  {% scroll_to_top scope="admin" %}
{% endblock %}
		

Настройка без превращения админки в редактор CSS

Мне не хотелось хранить в базе шаблоны, произвольный CSS или JavaScript. Это неудобно для сопровождения и создаёт лишнюю поверхность для ошибок.

Поэтому визуальная часть собрана из контролируемых вариантов:

  • круг, квадрат, скруглённый квадрат или pill;
  • заливка solid, outline, soft, ghost, glass или gradient;
  • положение в любом углу экрана;
  • отдельные размеры для desktop и mobile;
  • светлая и тёмная тема;
  • встроенные иконки, иконки от разработчика или загружаемые SVG;
  • настройки тени, границы, opacity и focus ring.

Настройки кнопки

Настройки кнопки

Что происходит, когда рядом есть cookie-баннер или чат

Нижний правый угол страницы редко бывает свободен. Там часто живут:

  • cookie-баннер;
  • компактная кнопка после закрытия баннера;
  • чат поддержки;
  • кнопка обратного звонка;
  • мобильная навигация;
  • toast-уведомления.

Пакет умеет рассматривать такие элементы как препятствия. Для этого можно пометить элемент атрибутом:

			<div data-scroll-top-obstacle>
    <!-- Cookie banner, chat launcher или другой фиксированный элемент -->
</div>
		

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

Для сложных виджетов есть отдельный адаптер: он может отслеживать появление и исчезновение элементов, например компактного launcher после закрытия cookie-баннера. При этом ни cookie-пакет, ни чат не становятся зависимостями django-scroll-to-top

Доступность — не отдельная галочка в конце

У кнопки есть понятное имя для screen reader, поддержка клавиатуры, видимый focus-visible, минимальный размер области нажатия и режим prefers-reduced-motion.

Если пользователь отключил анимации на уровне системы, плавная прокрутка не будет навязываться. Если JavaScript не загрузился, кнопка остаётся обычной ссылкой на начало документа.

Полный независимый аудит WCAG 2.2 AA и тестирование масштабирования 200% и 400% пока находятся в roadmap, поэтому называть компонент полностью сертифицированным по WCAG было бы неправильно. Но структурные требования — клавиатурная доступность, фокус, reduced motion, forced-colors и безопасная работа без JavaScript — уже заложены в компонент и покрываются тестами.

CSP и загружаемые SVG

В корпоративных проектах часто нельзя просто добавить inline-скрипт и включить unsafe-inline ради одной кнопки.

По умолчанию компонент использует same-origin CSS и JavaScript. Для него подходит политика такого вида:

			Content-Security-Policy:
  default-src 'self';
  style-src 'self';
  script-src 'self';
		

Настраиваемые цвета и размеры отдаются не через inline-стили, а через версионированный stylesheet endpoint. Это позволяет сохранить простой контракт с одним template-тегом и не ослаблять CSP.

Отдельно пришлось подумать о загружаемых SVG. Админ не рендерит исходный файл как есть: SVG проходит санитарную обработку. Скрипты, обработчики событий, внешние ресурсы, встроенные документы и небезопасные namespace отклоняются. Для загружаемых иконок также хранится информация об авторе, источнике и лицензии.

Ревизии, публикация и откат

Одна из самых полезных вещей в пакете — не сама кнопка, а жизненный цикл её настроек.

Можно создать черновик, посмотреть результат в live preview, опубликовать изменения или вернуться к предыдущей версии. Это особенно удобно, когда кнопку настраивает не разработчик, а контент-менеджер или дизайнер.

Живой предпросмотр

Живой предпросмотр

У ревизий есть три состояния:

  • draft — редактируемый черновик;
  • published — текущая активная конфигурация;
  • archived — сохранённая версия для отката.

настройки ревизий профиля кнопки

настройки ревизий профиля кнопки

Где пакет уместен, а где нет

django-scroll-to-top имеет смысл, когда кнопка нужна в нескольких проектах, должна работать в Django Admin, настраиваться без деплоя или жить в окружении со строгими требованиями к CSP и интерфейсу.

Для лендинга на одну страницу проще и правильнее написать несколько строк самостоятельно. Это будет быстрее, понятнее и дешевле в сопровождении.

Но если такая маленькая деталь начинает повторяться в нескольких продуктах, появляется необходимость поддерживать мобильную версию, доступность, независимые настройки для сайтов и админки, то отдельный компонент уже перестаёт быть избыточным.

Сейчас пакет выпущен как beta-версия 0.2.0, требует Python 3.10+ и поддерживает Django 4.2 LTS, 5.x и 6.0. Лицензия — MIT.

Исходный код, документация и примеры использования доступны в GitHub-репозитории проекта.

Пакет опубликован в PyPI под именем django-scroll-to-top.

Обратная связь, баг-репорты и предложения по интеграции с кастомными Django Admin-темами приветствуются в Issues.

Схожие новости

#Наименование новостиТональностьИнформативностьДата публикации
1Git в Telegram: как я избавился от JSON, победил Markdown и получил security by design5702-07-2026
2Как усыпить Python: полный гид по time.sleep(), asyncio.sleep() и паузам в потоках0725-06-2026
3Как ограничить расходы на OpenAI API, чтобы ИИ-агенты не сожгли бюджет0804-07-2026
4Аварийное восстановление до аварии: как настроить DRaaS, пока ничего не упал5802-07-2026
5Deckhouse Conf 2026: зачем инженерам самописный SDN и виртуалки в Kubernetes0502-07-2026
6Нейросеть для генерации изображений: ТОП-7 ИИ генераторов картинок в 20260703-07-2026
7Как оживить фото нейросетью бесплатно: пошаговый гайд 2026 года5703-07-2026
8Нейросеть для генерации видео: ТОП-6 ИИ для создания видео в 2026 году0803-07-2026
9AI-агенты сломали управление жизненным циклом идентификации. Что с этим делать0704-07-2026
10Как мы нашли баг в HTTP-библиотеке hyper0525-06-2026

Классификация: Мнения. Схожих патентов: 0. Схожих новостей: 10. Тональность: 0. Информативность: 7. Источник: tproger.ru.