Отключение прокрутки без скрытия: решение проблемы CSS

Пройдите тест, узнайте какой профессии подходите

Я предпочитаю
0%
Работать самостоятельно и не зависеть от других
Работать в команде и рассчитывать на помощь коллег
Организовывать и контролировать процесс работы

Быстрый ответ

Для отключения прокрутки страницы, не скрывая при этом полосу прокрутки, примените следующие CSS свойства. Задайте для overflow-y такое значение, которое сохранит полосу прокрутки видимой, и установите position так, чтобы фиксировать положение страницы. Корректируйте смещение контента с помощью padding-right и используйте top для сохранения текущего места прокрутки пользователя:

CSS
Скопировать код
body.no-scroll {
  overflow-y: scroll; /* Разрешает видимость полосы прокрутки */
  position: fixed; /* Запрещает прокрутку страницы */
  width: 100%; /* Фиксирует ширину страницы */
  top: calc(-1 * var(--scroll-position)); /* Запоминает место прокрутки */
}

Для блокировки прокрутки добавьте класс .no-scroll к тегу <body>.

Перед добавлением класса "no-scroll" запомните текущее положение прокрутки:

JS
Скопировать код
const scrollY = window.scrollY || document.documentElement.scrollTop;
document.documentElement.style.setProperty('--scroll-position', `${scrollY}px`);
document.body.classList.add('no-scroll'); /* Прокрутка ставится на паузу */

Чтобы возобновить прокрутку, удалите класс и восстановите положение прокрутки:

JS
Скопировать код
const scrollY = document.documentElement.style.getPropertyValue('--scroll-position');
document.documentElement.style.removeProperty('--scroll-position');
window.scrollTo(0, parseInt(scrollY || '0'));
document.body.classList.remove('no-scroll'); /* Прокрутка возобновляется */

В результате этих действий исключаются визуальные сдвиги и потеря текщего положения прокрутки, обеспечивая комфортный пользовательский опыт.

Кинга Идем в IT: пошаговый план для смены профессии

Предотвращение сдвигов макета

Чтобы устранить сдвиг контента при блокировке прокрутки, выполните следующие шаги:

plaintext
Скопировать код
1. Выставите для `<body>` ширину `width: 100%` при использовании `position: fixed`, чтобы макет оставался стабильным.
2. Воспользуйтесь свойством `inline-size` для обеспечения единообразия ширины в различных браузерах.
3. Подключите CSS переменные для возможности динамического изменения ширины.
4. Разберитесь с проблемой **двойной полосы прокрутки** и примените медиа-запросы и другие решения, предлагаемые сообществом.

Определите наличие вертикальной полосы прокрутки:

JS
Скопировать код
const hasVerticalScrollbar = document.body.scrollHeight > window.innerHeight;
if (hasVerticalScrollbar) {
  // Примените метод "no-scroll"
}

Повышение удобства использования

  • Запоминайте положение прокрутки перед блокировкой и восстанавливайте его после для гладкой навигации.
  • Настройте плавность прокрутки при помощи свойства scroll-behavior: smooth; в CSS или используйте методы JavaScript, описанные на SitePoint.

Советы для JQuery

Приоритетным для вас является использование jQuery? Ниже приведён код для управления прокруткой:

JS
Скопировать код
$.fn.disableScroll = function() {
  this.each(function() {
    const scrollTop = $(window).scrollTop();
    $(this).css({
      overflow: 'scroll',
      position: 'fixed',
      width: '100%',
      top: `-${scrollTop}px` /* Запоминаем положение прокрутки */
    });
  });
};

$.fn.enableScroll = function() {
    const scrollY = this.css('top');
    this.css({
      overflow: '',
      position: '',
      top: '',
      width: ''
    });
    $('html, body').scrollTop(-parseInt(scrollY || '0')); /* Возобновляем прокрутку */
};

$('body').disableScroll(); /* Приостанавливаем прокрутку */
$('body').enableScroll(); /* Возобновляем прокрутку */

Не забывайте про обработку событий и возможность их отключения с помощью метода .off() в jQuery.

Визуализация

Представьте, что ваш сайт это галерея 🖼️, а стекло – это элемент, прокручиваемый пользователем.

  • Посетители могут ВИДЕТЬ экспонаты (🖼️1️⃣ 🖼️2️⃣ 🖼️3️⃣), но из-за стекла они не могут их передвинуть.
  • Полоса прокрутки, в свою очередь, – это ручка, с помощью которой можно двигать обзор вверх и вниз.
plaintext
Скопировать код
Когда вы отключаете прокрутку, оставляя ее видимой:
- Оставляйте стекло **ЦЕЛЫМ** и **ПРОЗРАЧНЫМ**, но сделайте его **НЕПОДВИЖНЫМ** (🔒🖼️).
- Таким образом, посетители могут **ВИДЕТЬ** ручку (полосу прокрутки), но не могут ее использовать.

Данная метафора помогает понять, как работает блокировка прокрутки без убирания полосы прокрутки.

Markdown
Скопировать код
| Действие                     | Виртуальная галерея 🖼️ |
| ---------------------------- | ----------------------- |
| Видимость полосы прокрутки   | Стекло прозрачное ✅    |
| Возможность прокрутки        | Стекло закрыто 🔒       |

Обратите внимание на удачные примеры, например, оверлеи в библиотеке Fancyapp. Опирайтесь на опыт сообщества и адаптируйте его под специфику различных браузеров.

Полезные материалы

  1. css – How to programmatically disable page scrolling with jQuery – Stack Overflow — дискуссия на Stack Overflow об остановке прокрутки.
  2. overflow – CSS: Cascading Style Sheets | MDN — MDN руководство по свойству CSS overflow.
  3. pointer-events | CSS-Tricks — статья о контроле взаимодействий с элементами через pointer-events.
  4. CSS Layout – The position Property — удобное пояснение по свойству position: fixed и его использования для блокировки прокрутки на W3Schools.
  5. Styling Scrollbars | WebKit — настройка дизайна полос прокрутки в браузерах на движке WebKit.
  6. Prevent Page Scrolling When a Modal is Open | CSS-Tricks — методика от CSS-Tricks по остановке прокрутки во время работы с модальными окнами.
  7. How to Implement Smooth Scrolling in Vanilla JavaScript — SitePoint — советы и техники SitePoint для реализации плавной прокрутки страниц на JavaScript.