` и ScrollTrigger.\n\nУстановка: `gsap.registerPlugin(ScrollTrigger);`\n\nКод для вашей страницы:\n\n```js\ngsap.registerPlugin(ScrollTrigger);\n\ngsap.timeline({\n scrollTrigger: {\n trigger: \"#main\",\n start: \"top bottom\",\n end: \"#scills_box bottom\",\n scrub: 1, // Привязка к скорости скролла\n ease: \"power2.inOut\"\n }\n})\n.to(\"#back1\", {opacity: 0, duration: 1})\n.to(\"#back2\", {opacity: 1, duration: 1}, 0);\n\ngsap.timeline({\n scrollTrigger: {\n trigger: \"#about\",\n start: \"top bottom\",\n end: \"bottom bottom\",\n scrub: 1\n }\n})\n.to(\"#back2\", {opacity: 0, duration: 1})\n.to(\"#back3\", {opacity: 1, duration: 1}, 0);\n```\n\nScrub делает переход пропорциональным скроллу — скроллишь медленно, анимация растягивается. Для трех изображений используйте одну timeline с позициями: `.to(\"#back2\", {}, 0.5).to(\"#back3\", {}, 1)`. Примеры в [GSAP форуме](https://gsap.com/community/forums/topic/37887-background-image-change-on-scroll/) показывают, как это бьет vanilla на headless.\n\n---\n\n## IntersectionObserver и альтернативы вроде AOS {#alternatives}\n\nЕсли GSAP overkill, попробуйте IntersectionObserver — нативный API для [появления элементов при скролле](https://webgolovolomki.com/poyavlenie-elementov-pri-skrolle/). Добавьте `data-bg` к блокам:\n\n```js\nconst observer = new IntersectionObserver((entries) => {\n entries.forEach(entry => {\n if (entry.isIntersecting) {\n const nextBg = entry.target.dataset.bg;\n const current = document.querySelector('.back-current');\n const next = document.querySelector('.back-next');\n next.style.backgroundImage = `url(${nextBg})`;\n next.style.opacity = 1;\n current.style.opacity = 0;\n current.classList.remove('back-current');\n next.classList.add('back-current');\n }\n });\n}, { threshold: 0.5 });\n\nobserver.observe(document.getElementById('main'));\nobserver.observe(document.getElementById('scills_box'));\n```\n\nAOS (Animate On Scroll) проще: подключите CDN, добавьте `data-aos=\"fade-up\"` к блокам, но для фона комбинируйте с opacity. jQuery-вариант из [gravitsapa](https://gravitsapa.info/delaem-plavnuyu-smenu-tsveta-fona-pri-skrole-stranitsyi-na-jquery/) подойдет для legacy: `$(window).scroll(function(){ if(scroll >= 500) $('.back-next').animate({opacity:1},400); });`.\n\n---\n\n## Оптимизация и производительность {#performance}\n\nНе забывайте: preload изображений (``), чтобы fade не ждал загрузки. Тестируйте на мобильных — fixed backgrounds иногда глючат в iOS. Для parallax добавьте `transform: translateY` в GSAP.\n\nЕсли страницы длинные, комбинируйте с `will-change: opacity` в CSS. И да, throttle спасет от 1000+ вызовов scroll в секунду на тач-устройствах.\n\n---\n\n## Источники {#sources}\n\n1. [qna.habr.com/q/309680](https://qna.habr.com/q/309680) \n2. [ru.stackoverflow.com/questions/717611](https://ru.stackoverflow.com/questions/717611/%D0%98%D0%B7%D0%BC%D0%B5%D0%BD%D0%B5%D0%BD%D0%B8%D0%B5-%D1%84%D0%BE%D0%BD%D0%B0-%D0%BF%D1%80%D0%B8-%D1%81%D0%BA%D1%80%D0%BE%D0%BB%D0%BB%D0%B5) \n3. [gravitsapa.info/...jquery](https://gravitsapa.info/delaem-plavnuyu-smenu-tsveta-fona-pri-skrole-stranitsyi-na-jquery/) \n4. [gsap.com/...scroll](https://gsap.com/community/forums/topic/21625-how-to-change-the-background-image-when-scroll/) \n5. [webgolovolomki.com/...skrolle](https://webgolovolomki.com/poyavlenie-elementov-pri-skrolle/) \n6. [ru.stackoverflow.com/...prokrutke](https://ru.stackoverflow.com/questions/623601/%D0%9F%D0%BB%D0%B0%D0%B2%D0%BD%D0%B0%D1%8F-%D0%B0%D0%BD%D0%B8%D0%BC%D0%B0%D1%86%D0%B8%D1%8F-%D1%86%D0%B2%D0%B5%D1%82%D0%B0-%D0%BF%D1%80%D0%B8-%D0%BF%D1%80%D0%BE%D0%BA%D1%80%D1%83%D1%82%D0%BA%D0%B5) \n7. [dejurka.ru/...pure-css](https://www.dejurka.ru/css/background-reveal-scroll-in-pure-css/) \n8. [gsap.com/...on-scroll](https://gsap.com/community/forums/topic/37887-background-image-change-on-scroll/)\n\n---\n\n## Заключение {#conclusion}\n\nПлавная смена фона при скролле достигается opacity-слоями с transitions или GSAP ScrollTrigger — забудьте про резкие if. Начните с vanilla JS для простоты, перейдите на GSAP для wow-эффекта. Тестируйте на реальных устройствах, и ваша страница полетит. Готовый код сэкономит часы — копируйте и адаптируйте под свои пороги."},{"name":"Плавная смена фона при скролле в JavaScript","step":[{"name":"Определите проблемы резкой смены фона и создайте слои с opacity","@type":"HowToStep","@id":"https://xn--b1afbosiaouc3h.xn--p1ai/c/web/q/smooth-background-change-on-scroll-javascript","position":1},{"name":"Реализуйте базовый подход с CSS transitions на opacity","@type":"HowToStep","@id":"https://xn--b1afbosiaouc3h.xn--p1ai/c/web/q/smooth-background-change-on-scroll-javascript","position":2},{"name":"Добавьте Vanilla JS с requestAnimationFrame для плавного прогресса","@type":"HowToStep","@id":"https://xn--b1afbosiaouc3h.xn--p1ai/c/web/q/smooth-background-change-on-scroll-javascript","position":3},{"name":"Используйте GSAP ScrollTrigger для профессиональной анимации","@type":"HowToStep","@id":"https://xn--b1afbosiaouc3h.xn--p1ai/c/web/q/smooth-background-change-on-scroll-javascript","position":4},{"name":"Оптимизируйте с IntersectionObserver и preload изображений","@type":"HowToStep","@id":"https://xn--b1afbosiaouc3h.xn--p1ai/c/web/q/smooth-background-change-on-scroll-javascript","position":5}],"@type":"HowTo","@context":"https://schema.org","description":"Руководство по созданию плавной анимации смены фонового изображения при прокрутке страницы без резких переходов с использованием CSS, Vanilla JS и GSAP.","mainEntityOfPage":{"@type":"WebPage","@id":"https://xn--b1afbosiaouc3h.xn--p1ai/c/web/q/smooth-background-change-on-scroll-javascript"},"inLanguage":"ru","dateCreated":"2026-01-02T13:45:04.795Z","datePublished":"2026-01-02T13:45:04.795Z","dateModified":"2026-01-02T13:45:04.795Z","author":[{"@type":"Organization","@id":"https://xn--b1afbosiaouc3h.xn--p1ai/about","name":"НейроОтветы","url":"https://xn--b1afbosiaouc3h.xn--p1ai/about","logo":{"@type":"ImageObject","url":"https://xn--b1afbosiaouc3h.xn--p1ai/logo.png","width":"512","height":"512"}}],"publisher":{"@type":"Organization","@id":"https://xn--b1afbosiaouc3h.xn--p1ai/about","name":"НейроОтветы","url":"https://xn--b1afbosiaouc3h.xn--p1ai/about","logo":{"@type":"ImageObject","url":"https://xn--b1afbosiaouc3h.xn--p1ai/logo.png","width":"512","height":"512"}},"@id":"https://xn--b1afbosiaouc3h.xn--p1ai/c/web/q/smooth-background-change-on-scroll-javascript","url":"https://xn--b1afbosiaouc3h.xn--p1ai/c/web/q/smooth-background-change-on-scroll-javascript"},{"@type":"CollectionPage","@id":"https://xn--b1afbosiaouc3h.xn--p1ai/c/web/q/smooth-background-change-on-scroll-javascript/#related-questions","name":"Плавная смена фона при скролле в JavaScript без резких переходов","description":"Как сделать плавную анимацию смены статичного фонового изображения при скролле: используйте слои с opacity, CSS transitions, Vanilla JS с requestAnimationFrame или GSAP ScrollTrigger. Примеры кода для fade-эффекта без лагов.","url":"https://xn--b1afbosiaouc3h.xn--p1ai/c/web/q/smooth-background-change-on-scroll-javascript","inLanguage":"ru","mainEntity":{"@type":"ItemList","@id":"https://xn--b1afbosiaouc3h.xn--p1ai/c/web/q/smooth-background-change-on-scroll-javascript/#related-questions","itemListElement":[{"@type":"ListItem","@id":"https://xn--b1afbosiaouc3h.xn--p1ai/c/web/q/motion-blur-slide-transitions-web","name":"Motion blur при переключении слайдов: реализация в вебе","position":1,"item":{"@type":"Article","@id":"https://xn--b1afbosiaouc3h.xn--p1ai/c/web/q/motion-blur-slide-transitions-web","mainEntityOfPage":{"@type":"WebPage","@id":"https://xn--b1afbosiaouc3h.xn--p1ai/c/web/q/motion-blur-slide-transitions-web"},"inLanguage":"ru","dateCreated":"2026-03-19T12:13:09.563Z","datePublished":"2026-03-19T12:13:09.563Z","dateModified":"2026-03-19T13:52:00.259Z","author":[{"@type":"Person","@id":"https://xn--b1afbosiaouc3h.xn--p1ai/@andyadams","name":"Andy Adams","givenName":"Andy","familyName":"Adams","url":"https://xn--b1afbosiaouc3h.xn--p1ai/@andyadams","image":{"@type":"ImageObject","url":"https://xn--b1afbosiaouc3h.xn--p1ai/api/v1/person/andyadams/avatar.png","width":"72","height":"72"},"jobTitle":"Технический писатель","description":"Технический писатель, автор статей на CSS-Tricks, специализирующийся на веб-разработке и CSS"},{"@type":"Person","@id":"https://xn--b1afbosiaouc3h.xn--p1ai/@gabrielshoyombo","name":"Gabriel Shoyombo","givenName":"Gabriel","familyName":"Shoyombo","url":"https://xn--b1afbosiaouc3h.xn--p1ai/@gabrielshoyombo","image":{"@type":"ImageObject","url":"https://xn--b1afbosiaouc3h.xn--p1ai/api/v1/person/gabrielshoyombo/avatar.png","width":"72","height":"72"},"jobTitle":"Технический писатель","description":"Технический писатель, автор статей на CSS-Tricks, специализирующийся на веб-разработке и CSS"},{"@type":"Organization","@id":"https://xn--b1afbosiaouc3h.xn--p1ai/@css-tricks-com","name":"CSS-Tricks","description":"Веб-сайт о создании сайтов, посвященный CSS и веб-разработке","url":"https://xn--b1afbosiaouc3h.xn--p1ai/@css-tricks-com","logo":{"@type":"ImageObject","url":"https://xn--b1afbosiaouc3h.xn--p1ai/api/v1/source/css-tricks-com/icon.png","width":"72","height":"72"}},{"@type":"Organization","@id":"https://xn--b1afbosiaouc3h.xn--p1ai/@developer-mozilla-org","name":"MDN Web Docs","description":"MDN Web Docs - это бесплатная многоязычная онлайн-документация для веб-разработчиков, предоставляющая информацию об открытых веб-технологиях включая HTML, CSS и API для веб-сайтов и прогрессивных веб-приложений.","url":"https://xn--b1afbosiaouc3h.xn--p1ai/@developer-mozilla-org","logo":{"@type":"ImageObject","url":"https://xn--b1afbosiaouc3h.xn--p1ai/api/v1/source/developer-mozilla-org/logo.png","width":"72","height":"72"}},{"@type":"Organization","@id":"https://xn--b1afbosiaouc3h.xn--p1ai/@greensock-com","name":"GSAP","description":"Платформа для создания профессиональных веб-анимаций, предоставляющая мощные инструменты для анимации JavaScript","url":"https://xn--b1afbosiaouc3h.xn--p1ai/@greensock-com"}],"publisher":{"@type":"Organization","@id":"https://xn--b1afbosiaouc3h.xn--p1ai/about","name":"НейроОтветы","url":"https://xn--b1afbosiaouc3h.xn--p1ai/about","logo":{"@type":"ImageObject","url":"https://xn--b1afbosiaouc3h.xn--p1ai/logo.png","width":"512","height":"512"}},"headline":"Motion blur при переключении слайдов: реализация в вебе","description":"Пошаговое руководство по реализации motion blur при переключении слайдов. Примеры кода на HTML, CSS и JavaScript для создания плавных переходов.","keywords":["motion blur","анимация слайдов","размытие в движении","анимация перехода слайдов","эффект motion blur","CSS transition","javascript animations","css transitions transform","real motion blur","video motion blur"],"image":[],"articleBody":""}},{"@type":"ListItem","@id":"https://xn--b1afbosiaouc3h.xn--p1ai/c/web/q/optimize-javascript-tabs-event-delegation","name":"Оптимизация вкладок JS: делегирование и data-атрибуты","position":2,"item":{"@type":"Article","@id":"https://xn--b1afbosiaouc3h.xn--p1ai/c/web/q/optimize-javascript-tabs-event-delegation","mainEntityOfPage":{"@type":"WebPage","@id":"https://xn--b1afbosiaouc3h.xn--p1ai/c/web/q/optimize-javascript-tabs-event-delegation"},"inLanguage":"ru","dateCreated":"2026-03-04T13:18:51.727Z","datePublished":"2026-03-04T13:18:51.727Z","dateModified":"2026-03-04T13:18:51.727Z","author":[{"@type":"Person","@id":"https://xn--b1afbosiaouc3h.xn--p1ai/@ramy-nasr","name":"Ramy Nasr","givenName":"Ramy","familyName":"Nasr","url":"https://xn--b1afbosiaouc3h.xn--p1ai/@ramy-nasr","jobTitle":"Разработчик JavaScript","description":"Активный участник Stack Overflow с репутацией 2,567, специализируется на PHP, Symfony, Doctrine ORM, JavaScript и jQuery. Имеет вклад в 79 ответов и участие в нескольких сетях Stack Exchange."},{"@type":"Person","@id":"https://xn--b1afbosiaouc3h.xn--p1ai/@orenrocco","name":"@orenrocco","url":"https://xn--b1afbosiaouc3h.xn--p1ai/@orenrocco","jobTitle":"Веб-разработчик","description":"Участник Stack Overflow с репутацией 21, активен в темах HTML, jQuery, JavaScript. Участвует также в Code Review и других сетях Stack Exchange."},{"@type":"Person","@id":"https://xn--b1afbosiaouc3h.xn--p1ai/@mulan","name":"@mulan","url":"https://xn--b1afbosiaouc3h.xn--p1ai/@mulan","jobTitle":"Разработчик jQuery-плагинов","description":"Участник Stack Overflow, специализируется на разработке jQuery-плагинов и оптимизации интерфейсов."},{"@type":"Person","@id":"https://xn--b1afbosiaouc3h.xn--p1ai/@user863","name":"@user863","url":"https://xn--b1afbosiaouc3h.xn--p1ai/@user863","jobTitle":"Разработчик интерфейсов","description":"Участник Stack Overflow, фокусируется на интерфейсах и jQuery-решениях для вкладок."},{"@type":"Person","@id":"https://xn--b1afbosiaouc3h.xn--p1ai/@gwer","name":"Владлен Грачев","givenName":"Владлен","familyName":"Грачев","url":"https://xn--b1afbosiaouc3h.xn--p1ai/@gwer","image":{"@type":"ImageObject","url":"https://xn--b1afbosiaouc3h.xn--p1ai/api/v1/person/gwer/avatar.png","width":"72","height":"72"},"jobTitle":"JavaScript-разработчик","description":"Опытный разработчик с вкладом в 291 ответ и 2 вопроса на Хабр Q&A. Активен в тегах JavaScript, PHP, CSS, HTML, программирование, Python."},{"@type":"Person","@id":"https://xn--b1afbosiaouc3h.xn--p1ai/@stalker-red","name":"@stalker-red","url":"https://xn--b1afbosiaouc3h.xn--p1ai/@stalker-red","jobTitle":"Веб-разработчик","description":"Активный участник Хабр Q&A по веб-разработке и JavaScript."},{"@type":"Person","@id":"https://xn--b1afbosiaouc3h.xn--p1ai/@diithitech","name":"Dmitriy Mozgovoy","givenName":"Dmitriy","familyName":"Mozgovoy","url":"https://xn--b1afbosiaouc3h.xn--p1ai/@diithitech","image":{"@type":"ImageObject","url":"https://xn--b1afbosiaouc3h.xn--p1ai/api/v1/person/diithitech/avatar.png","width":"72","height":"72"},"jobTitle":"Fullstack JavaScript-разработчик","description":"Fullstack-разработчик на Хабр Q&A, специализируется на JS и архитектуре кода."},{"@type":"Person","@id":"https://xn--b1afbosiaouc3h.xn--p1ai/@sageptr","name":"@sageptr","url":"https://xn--b1afbosiaouc3h.xn--p1ai/@sageptr","image":{"@type":"ImageObject","url":"https://xn--b1afbosiaouc3h.xn--p1ai/api/v1/person/sageptr/avatar.png","width":"72","height":"72"},"jobTitle":"Разработчик","description":"Разработчик на Хабр Q&A, участвует в обсуждениях JS и DOM."},{"@type":"Person","@id":"https://xn--b1afbosiaouc3h.xn--p1ai/@inkvizitor","name":"Инквизитор","givenName":"Инквизитор","url":"https://xn--b1afbosiaouc3h.xn--p1ai/@inkvizitor","jobTitle":"Фронтенд-разработчик","description":"Профессиональный разработчик, отвечающий на вопросы на Stack Overflow"},{"@type":"Person","@id":"https://xn--b1afbosiaouc3h.xn--p1ai/@itchief","name":"Александр Мальцев","givenName":"Александр","familyName":"Мальцев","url":"https://xn--b1afbosiaouc3h.xn--p1ai/@itchief","jobTitle":"Автор туториалов по JavaScript","description":"Автор сайта ИТ Шеф, создает туториалы по веб-разработке, фокус на JS, HTML/CSS для начинающих."}],"publisher":{"@type":"Organization","@id":"https://xn--b1afbosiaouc3h.xn--p1ai/about","name":"НейроОтветы","url":"https://xn--b1afbosiaouc3h.xn--p1ai/about","logo":{"@type":"ImageObject","url":"https://xn--b1afbosiaouc3h.xn--p1ai/logo.png","width":"512","height":"512"}},"headline":"Оптимизация вкладок JS: делегирование и data-атрибуты","description":"Как оптимизировать JavaScript-код для переключения вкладок (табов) без дублирования: делегирование событий, data-атрибуты, jQuery-плагины, CSS-only, LocalStorage. Масштабируемо для сотен tabs js с медиа-контентом.","keywords":["вкладки js","tabs js","переключение вкладок","tab вкладки","вкладка javascript","css переключение вкладок","js табы","делегирование событий","data-атрибуты"],"image":["https://xn--b1afbosiaouc3h.xn--p1ai/api/v1/question/15833/preview/1x1.png","https://xn--b1afbosiaouc3h.xn--p1ai/api/v1/question/15833/preview/4x3.png","https://xn--b1afbosiaouc3h.xn--p1ai/api/v1/question/15833/preview/16x9.png"],"articleBody":""}},{"@type":"ListItem","@id":"https://xn--b1afbosiaouc3h.xn--p1ai/c/web/q/snap-slider-drag-implementation-css-js","name":"Snap переключение слайдов в слайдере при drag: CSS/JS","position":3,"item":{"@type":"Article","@id":"https://xn--b1afbosiaouc3h.xn--p1ai/c/web/q/snap-slider-drag-implementation-css-js","mainEntityOfPage":{"@type":"WebPage","@id":"https://xn--b1afbosiaouc3h.xn--p1ai/c/web/q/snap-slider-drag-implementation-css-js"},"inLanguage":"ru","dateCreated":"2026-01-01T07:06:52.684Z","datePublished":"2026-01-01T07:06:52.684Z","dateModified":"2026-01-01T07:06:52.684Z","author":[{"@type":"Organization","@id":"https://xn--b1afbosiaouc3h.xn--p1ai/about","name":"НейроОтветы","url":"https://xn--b1afbosiaouc3h.xn--p1ai/about","logo":{"@type":"ImageObject","url":"https://xn--b1afbosiaouc3h.xn--p1ai/logo.png","width":"512","height":"512"}}],"publisher":{"@type":"Organization","@id":"https://xn--b1afbosiaouc3h.xn--p1ai/about","name":"НейроОтветы","url":"https://xn--b1afbosiaouc3h.xn--p1ai/about","logo":{"@type":"ImageObject","url":"https://xn--b1afbosiaouc3h.xn--p1ai/logo.png","width":"512","height":"512"}},"headline":"Snap переключение слайдов в слайдере при drag: CSS/JS","description":"Реализуйте резкое (snap) переключение слайдов в слайдере при перетаскивании мышью или касанием. Подходы: CSS scroll-snap, JS с pointer-событиями, порог срабатывания, отключение transition. Примеры кода HTML/CSS/JS.","keywords":["слайдер","snap переключение","перетаскивание слайдов","слайдер на js","css scroll-snap","pointer события","drag слайдер","карусель js","как сделать слайдер","touch слайдер","swiper js","слайдер html css js"],"image":[],"articleBody":""}},{"@type":"ListItem","@id":"https://xn--b1afbosiaouc3h.xn--p1ai/c/web/q/how-to-make-div-clickable-link-xhtml11","name":"Как сделать div блок кликабельной ссылкой в XHTML 1.1","position":4,"item":{"@type":"Article","@id":"https://xn--b1afbosiaouc3h.xn--p1ai/c/web/q/how-to-make-div-clickable-link-xhtml11","mainEntityOfPage":{"@type":"WebPage","@id":"https://xn--b1afbosiaouc3h.xn--p1ai/c/web/q/how-to-make-div-clickable-link-xhtml11"},"inLanguage":"ru","dateCreated":"2026-02-24T10:27:15.569Z","datePublished":"2026-02-24T10:27:15.569Z","dateModified":"2026-02-24T10:27:15.569Z","author":[{"@type":"Person","@id":"https://xn--b1afbosiaouc3h.xn--p1ai/@vlad-merzhevich","name":"Влад Мержевич","givenName":"Влад","familyName":"Мержевич","url":"https://xn--b1afbosiaouc3h.xn--p1ai/@vlad-merzhevich","jobTitle":"Автор справочника","description":"Автор и владелец сайта htmlbook.ru, занимается разработкой и поддержкой справочника по веб-технологиям с 2002 года."},{"@type":"Organization","@id":"https://xn--b1afbosiaouc3h.xn--p1ai/@htmlbook-ru","name":"htmlbook.ru","description":"Онлайн-справочник по HTML, CSS, JavaScript и смежным веб-технологиям с примерами и правилами использования тегов. Авторский проект Влада Мержевича с 2002 года.","url":"https://xn--b1afbosiaouc3h.xn--p1ai/@htmlbook-ru","logo":{"@type":"ImageObject","url":"https://xn--b1afbosiaouc3h.xn--p1ai/api/v1/source/htmlbook-ru/icon.png","width":"72","height":"72"}},{"@type":"Person","@id":"https://xn--b1afbosiaouc3h.xn--p1ai/@palmervan","name":"@palmervan","url":"https://xn--b1afbosiaouc3h.xn--p1ai/@palmervan","jobTitle":"Разработчик","description":"Участник сообщества Stack Overflow на русском, отвечает на вопросы по HTML/CSS и верстке."},{"@type":"Person","@id":"https://xn--b1afbosiaouc3h.xn--p1ai/@alekseyb","name":"Aleksey B","givenName":"Aleksey","familyName":"B","url":"https://xn--b1afbosiaouc3h.xn--p1ai/@alekseyb","jobTitle":"Разработчик","description":"Разработчик, участник русскоязычного Stack Overflow"},{"@type":"Organization","@id":"https://xn--b1afbosiaouc3h.xn--p1ai/@ru-stackoverflow-com","name":"Stack Overflow на русском","description":"Вопросы и ответы для программистов","url":"https://xn--b1afbosiaouc3h.xn--p1ai/@ru-stackoverflow-com","logo":{"@type":"ImageObject","url":"https://xn--b1afbosiaouc3h.xn--p1ai/api/v1/source/ru-stackoverflow-com/logo.png","width":"72","height":"72"}},{"@type":"Organization","@id":"https://xn--b1afbosiaouc3h.xn--p1ai/@www-w3-org","name":"W3C","description":"Всемирное консорциум веб-технологий (World Wide Web Consortium), разрабатывающий стандарты и рекомендации по веб-технологиям на основе принципов доступности, интернационализации, приватности и безопасности.","url":"https://xn--b1afbosiaouc3h.xn--p1ai/@www-w3-org","logo":{"@type":"ImageObject","url":"https://xn--b1afbosiaouc3h.xn--p1ai/api/v1/source/www-w3-org/icon.png","width":"72","height":"72"}},{"@type":"Person","@id":"https://xn--b1afbosiaouc3h.xn--p1ai/@aleksey-kodov","name":"Алексей Кодов","givenName":"Алексей","familyName":"Кодов","url":"https://xn--b1afbosiaouc3h.xn--p1ai/@aleksey-kodov","jobTitle":"Автор статей","description":"Автор вики-статей Skypro по лайфстайлу и финансам"},{"@type":"Organization","@id":"https://xn--b1afbosiaouc3h.xn--p1ai/@sky-pro","name":"Skypro","description":"Образовательная платформа, предлагающая курсы и материалы по профессиональным навыкам, включая редактирование текстов","url":"https://xn--b1afbosiaouc3h.xn--p1ai/@sky-pro","logo":{"@type":"ImageObject","url":"https://xn--b1afbosiaouc3h.xn--p1ai/api/v1/source/sky-pro/logo.png","width":"72","height":"72"}}],"publisher":{"@type":"Organization","@id":"https://xn--b1afbosiaouc3h.xn--p1ai/about","name":"НейроОтветы","url":"https://xn--b1afbosiaouc3h.xn--p1ai/about","logo":{"@type":"ImageObject","url":"https://xn--b1afbosiaouc3h.xn--p1ai/logo.png","width":"512","height":"512"}},"headline":"Как сделать div блок кликабельной ссылкой в XHTML 1.1","description":"Узнайте, почему нельзя использовать
в XHTML 1.1 для div ссылка. Валидные альтернативы: блочный с CSS, JS onclick. Примеры кода, правила W3C и лучшие практики для всего блока ссылка без изменений визуала.","keywords":["сделать блок ссылкой","div ссылка","блок ссылки","весь блок ссылка","html div ссылки","xhtml 1.1","css div ссылка","html блок ссылка"],"image":[],"articleBody":""}},{"@type":"ListItem","@id":"https://xn--b1afbosiaouc3h.xn--p1ai/c/web/q/how-to-create-popup-menu-image-hover","name":"Как создать всплывающее меню на изображении при наведении курсора","position":5,"item":{"@type":"Article","@id":"https://xn--b1afbosiaouc3h.xn--p1ai/c/web/q/how-to-create-popup-menu-image-hover","mainEntityOfPage":{"@type":"WebPage","@id":"https://xn--b1afbosiaouc3h.xn--p1ai/c/web/q/how-to-create-popup-menu-image-hover"},"inLanguage":"ru","dateCreated":"2026-03-15T14:25:31.133Z","datePublished":"2026-03-15T14:25:31.133Z","dateModified":"2026-03-15T14:25:31.133Z","author":[{"@type":"Person","@id":"https://xn--b1afbosiaouc3h.xn--p1ai/@mdn-contributors","name":"MDN contributors","givenName":"MDN","familyName":"contributors","url":"https://xn--b1afbosiaouc3h.xn--p1ai/@mdn-contributors","image":{"@type":"ImageObject","url":"https://xn--b1afbosiaouc3h.xn--p1ai/api/v1/person/mdn-contributors/avatar.png","width":"72","height":"72"},"jobTitle":"Технические писатели","description":"Коллектив участников сообщества MDN, которые разрабатывают и поддерживают документационный контент по веб-технологиям"},{"@type":"Person","@id":"https://xn--b1afbosiaouc3h.xn--p1ai/@bootstrap-contributors","name":"@bootstrap-contributors","url":"https://xn--b1afbosiaouc3h.xn--p1ai/@bootstrap-contributors","jobTitle":"Framework Developer","description":"Основатели и разработчики фреймворка Bootstrap. Mark Otto и Jacob Thornton создали Bootstrap как внутренний инструмент в Twitter, который позже был открыт для сообщества. Они руководят развитием фреймворка вместе с командой contributors."},{"@type":"Person","@id":"https://xn--b1afbosiaouc3h.xn--p1ai/@atomiks","name":"@atomiks","url":"https://xn--b1afbosiaouc3h.xn--p1ai/@atomiks","image":{"@type":"ImageObject","url":"https://xn--b1afbosiaouc3h.xn--p1ai/api/v1/person/atomiks/avatar.png","width":"72","height":"72"},"jobTitle":"Library Developer","description":"Разработчик JavaScript-библиотеки Tippy.js, создатель проекта Floating UI. Работает на Gold Coast, Australia. Активный участник open source сообщества с несколькими популярными проектами, включая floating-ui, mui/base-ui и другие."},{"@type":"Person","@id":"https://xn--b1afbosiaouc3h.xn--p1ai/@lokesh-dhakar","name":"Lokesh Dhakar","givenName":"Lokesh","familyName":"Dhakar","url":"https://xn--b1afbosiaouc3h.xn--p1ai/@lokesh-dhakar","jobTitle":"Independent Developer","description":"Независимый разработчик, создатель проекта Lightbox2. Специализируется на создании JavaScript-библиотек для веб-разработки, уделяя внимание доступности и кросс-браузерной совместимости."}],"publisher":{"@type":"Organization","@id":"https://xn--b1afbosiaouc3h.xn--p1ai/about","name":"НейроОтветы","url":"https://xn--b1afbosiaouc3h.xn--p1ai/about","logo":{"@type":"ImageObject","url":"https://xn--b1afbosiaouc3h.xn--p1ai/logo.png","width":"512","height":"512"}},"headline":"Как создать всплывающее меню на изображении при наведении курсора","description":"Пошаговые инструкции по реализации всплывающих меню на изображениях. Обзор плагинов, CSS и JavaScript решений для создания интерактивных изображений.","keywords":["интерактивное изображение","меню на изображении","изображение с меню","всплывающее окно изображение","меню при наведении","всплывающее меню изображение","popup изображение","tooltip изображение","меню при наведении курсора","как сделать меню при наведении","всплывающее меню при наведении","при наведении выпадает меню","при наведении открывается меню"],"image":[],"articleBody":""}},{"@type":"ListItem","@id":"https://xn--b1afbosiaouc3h.xn--p1ai/c/web/q/how-to-change-styles-vk-iframe-elements","name":"Как изменить стили элементов iframe с видео ВКонтакте","position":6,"item":{"@type":"Article","@id":"https://xn--b1afbosiaouc3h.xn--p1ai/c/web/q/how-to-change-styles-vk-iframe-elements","mainEntityOfPage":{"@type":"WebPage","@id":"https://xn--b1afbosiaouc3h.xn--p1ai/c/web/q/how-to-change-styles-vk-iframe-elements"},"inLanguage":"ru","dateCreated":"2026-03-08T06:48:13.494Z","datePublished":"2026-03-08T06:48:13.494Z","dateModified":"2026-03-08T07:19:41.273Z","author":[{"@type":"Person","@id":"https://xn--b1afbosiaouc3h.xn--p1ai/@inkvizitor","name":"Инквизитор","givenName":"Инквизитор","url":"https://xn--b1afbosiaouc3h.xn--p1ai/@inkvizitor","jobTitle":"Фронтенд-разработчик","description":"Профессиональный разработчик, отвечающий на вопросы на Stack Overflow"},{"@type":"Person","@id":"https://xn--b1afbosiaouc3h.xn--p1ai/@duddeniska","name":"duddeniska","givenName":"duddeniska","url":"https://xn--b1afbosiaouc3h.xn--p1ai/@duddeniska","jobTitle":"Разработчик","description":"Профессиональный разработчик, участвующий в обсуждениях на Stack Overflow"},{"@type":"Organization","@id":"https://xn--b1afbosiaouc3h.xn--p1ai/@ru-stackoverflow-com","name":"Stack Overflow на русском","description":"Вопросы и ответы для программистов","url":"https://xn--b1afbosiaouc3h.xn--p1ai/@ru-stackoverflow-com","logo":{"@type":"ImageObject","url":"https://xn--b1afbosiaouc3h.xn--p1ai/api/v1/source/ru-stackoverflow-com/logo.png","width":"72","height":"72"}},{"@type":"Organization","@id":"https://xn--b1afbosiaouc3h.xn--p1ai/@toster-ru","name":"Toster","description":"Вопросы и ответы для разработчиков и IT-специалистов","url":"https://xn--b1afbosiaouc3h.xn--p1ai/@toster-ru"},{"@type":"Organization","@id":"https://xn--b1afbosiaouc3h.xn--p1ai/@qna-habr-com","name":"Habr Q&A","description":"Российская платформа вопросов и ответов для IT-специалистов и энтузиастов технологий","url":"https://xn--b1afbosiaouc3h.xn--p1ai/@qna-habr-com","logo":{"@type":"ImageObject","url":"https://xn--b1afbosiaouc3h.xn--p1ai/api/v1/source/qna-habr-com/logo.png","width":"72","height":"72"}},{"@type":"Organization","@id":"https://xn--b1afbosiaouc3h.xn--p1ai/@searchengines-guru","name":"Searchengines.guru","description":"Крупнейший русскоязычный форум и новостной сайт, посвященный SEO, интернет-маркетингу и сайтостроению","url":"https://xn--b1afbosiaouc3h.xn--p1ai/@searchengines-guru","logo":{"@type":"ImageObject","url":"https://xn--b1afbosiaouc3h.xn--p1ai/api/v1/source/searchengines-guru/icon.png","width":"72","height":"72"}},{"@type":"Organization","@id":"https://xn--b1afbosiaouc3h.xn--p1ai/@vk-com","name":"VK","description":"Крупнейшая русскоязычная социальная сеть с более чем 500 миллионами пользователей","url":"https://xn--b1afbosiaouc3h.xn--p1ai/@vk-com","logo":{"@type":"ImageObject","url":"https://xn--b1afbosiaouc3h.xn--p1ai/api/v1/source/vk-com/logo.png","width":"72","height":"72"}}],"publisher":{"@type":"Organization","@id":"https://xn--b1afbosiaouc3h.xn--p1ai/about","name":"НейроОтветы","url":"https://xn--b1afbosiaouc3h.xn--p1ai/about","logo":{"@type":"ImageObject","url":"https://xn--b1afbosiaouc3h.xn--p1ai/logo.png","width":"512","height":"512"}},"headline":"Как изменить стили элементов iframe с видео ВКонтакте","description":"Объяснение, почему невозможно изменить стили элементов управления внутри iframe с видео ВКонтакте из-за ограничений безопасности браузеров и альтернативные решения.","keywords":["iframe стили","iframe стиль","iframe вконтакте","вконтакте iframe","iframe css","стилизация iframe","доступ к элементам iframe","изменение стилей во внешнем фрейме","встраивание видео вконтакте","кастомные стили iframe","same-origin policy","ограничения iframe","css iframe","javascript iframe","видео вконтакте"],"image":[],"articleBody":""}},{"@type":"ListItem","@id":"https://xn--b1afbosiaouc3h.xn--p1ai/c/web/q/how-to-fix-block-not-displaying-chrome-yandex-browser","name":"Как исправить отсутствие блока в Chrome и Яндекс.Браузере","position":7,"item":{"@type":"Article","@id":"https://xn--b1afbosiaouc3h.xn--p1ai/c/web/q/how-to-fix-block-not-displaying-chrome-yandex-browser","mainEntityOfPage":{"@type":"WebPage","@id":"https://xn--b1afbosiaouc3h.xn--p1ai/c/web/q/how-to-fix-block-not-displaying-chrome-yandex-browser"},"inLanguage":"ru","dateCreated":"2026-03-07T14:03:18.601Z","datePublished":"2026-03-07T14:03:18.601Z","dateModified":"2026-03-07T14:03:18.601Z","author":[{"@type":"Person","@id":"https://xn--b1afbosiaouc3h.xn--p1ai/@johndoe","name":"John Doe","givenName":"John","familyName":"Doe","url":"https://xn--b1afbosiaouc3h.xn--p1ai/@johndoe","image":{"@type":"ImageObject","url":"https://xn--b1afbosiaouc3h.xn--p1ai/api/v1/person/johndoe/avatar.png","width":"72","height":"72"},"jobTitle":"Senior Machine Learning Engineer","description":"Опытный инженер машинного обучения с 10-летним опытом разработки алгоритмов и структур данных для промышленных приложений"}],"publisher":{"@type":"Organization","@id":"https://xn--b1afbosiaouc3h.xn--p1ai/about","name":"НейроОтветы","url":"https://xn--b1afbosiaouc3h.xn--p1ai/about","logo":{"@type":"ImageObject","url":"https://xn--b1afbosiaouc3h.xn--p1ai/logo.png","width":"512","height":"512"}},"headline":"Как исправить отсутствие блока в Chrome и Яндекс.Браузере","description":"Решение проблемы с отображением элементов на сайте в Chrome и Яндекс.Браузере. Проверка консоли разработчика, CSS-префиксов, расширений и серверного кэширования. Пошаговые рекомендации для веб-разработчиков.","keywords":["Chrome","Яндекс.Браузер","Opera","Safari","CSS","JavaScript","кэширование","консоль разработчика","баги браузеров","совместимость CSS"],"image":[],"articleBody":""}},{"@type":"ListItem","@id":"https://xn--b1afbosiaouc3h.xn--p1ai/c/web/q/how-to-prevent-horizontal-scroll-mobile-menu","name":"Как запретить горизонтальный скроллинг в мобильном меню","position":8,"item":{"@type":"Article","@id":"https://xn--b1afbosiaouc3h.xn--p1ai/c/web/q/how-to-prevent-horizontal-scroll-mobile-menu","mainEntityOfPage":{"@type":"WebPage","@id":"https://xn--b1afbosiaouc3h.xn--p1ai/c/web/q/how-to-prevent-horizontal-scroll-mobile-menu"},"inLanguage":"ru","dateCreated":"2026-01-24T07:39:07.620Z","datePublished":"2026-01-24T07:39:07.620Z","dateModified":"2026-01-24T07:39:07.620Z","author":[{"@type":"Organization","@id":"https://xn--b1afbosiaouc3h.xn--p1ai/about","name":"НейроОтветы","url":"https://xn--b1afbosiaouc3h.xn--p1ai/about","logo":{"@type":"ImageObject","url":"https://xn--b1afbosiaouc3h.xn--p1ai/logo.png","width":"512","height":"512"}}],"publisher":{"@type":"Organization","@id":"https://xn--b1afbosiaouc3h.xn--p1ai/about","name":"НейроОтветы","url":"https://xn--b1afbosiaouc3h.xn--p1ai/about","logo":{"@type":"ImageObject","url":"https://xn--b1afbosiaouc3h.xn--p1ai/logo.png","width":"512","height":"512"}},"headline":"Как запретить горизонтальный скроллинг в мобильном меню","description":"Решения для запрета горизонтальной прокрутки при открытии мобильного меню. CSS overflow-x hidden, body fixed position и JavaScript методы.","keywords":["мобильное меню","горизонтальная прокрутка","overflow hidden","CSS overflow-x","body fixed","burger menu","мобильная версия","CSS решения"],"image":[],"articleBody":""}},{"@type":"ListItem","@id":"https://xn--b1afbosiaouc3h.xn--p1ai/c/web/q/how-to-create-interactive-slider-smooth-transitions","name":"Как создать интерактивный слайдер с плавными эффектами перехода","position":9,"item":{"@type":"Article","@id":"https://xn--b1afbosiaouc3h.xn--p1ai/c/web/q/how-to-create-interactive-slider-smooth-transitions","mainEntityOfPage":{"@type":"WebPage","@id":"https://xn--b1afbosiaouc3h.xn--p1ai/c/web/q/how-to-create-interactive-slider-smooth-transitions"},"inLanguage":"ru","dateCreated":"2026-04-24T18:19:36.520Z","datePublished":"2026-04-24T18:19:36.520Z","dateModified":"2026-04-24T18:19:36.520Z","author":[{"@type":"Person","@id":"https://xn--b1afbosiaouc3h.xn--p1ai/@mdn-team","name":"MDN Team contributors","givenName":"MDN Team","familyName":"contributors","url":"https://xn--b1afbosiaouc3h.xn--p1ai/@mdn-team","jobTitle":"Technical Writers","description":"Команда технических писателей MDN, отвечающая за создание и поддержку документации веб-технологий. Команда состоит из профессиональных авторов, специализирующихся на документации веб-стандартов и API."},{"@type":"Person","@id":"https://xn--b1afbosiaouc3h.xn--p1ai/@mdn-contributors","name":"MDN contributors","givenName":"MDN","familyName":"contributors","url":"https://xn--b1afbosiaouc3h.xn--p1ai/@mdn-contributors","image":{"@type":"ImageObject","url":"https://xn--b1afbosiaouc3h.xn--p1ai/api/v1/person/mdn-contributors/avatar.png","width":"72","height":"72"},"jobTitle":"Технические писатели","description":"Коллектив участников сообщества MDN, которые разрабатывают и поддерживают документационный контент по веб-технологиям"},{"@type":"Organization","@id":"https://xn--b1afbosiaouc3h.xn--p1ai/@w3schools-tutorial-team","name":"@w3schools-tutorial-team","url":"https://xn--b1afbosiaouc3h.xn--p1ai/@w3schools-tutorial-team"}],"publisher":{"@type":"Organization","@id":"https://xn--b1afbosiaouc3h.xn--p1ai/about","name":"НейроОтветы","url":"https://xn--b1afbosiaouc3h.xn--p1ai/about","logo":{"@type":"ImageObject","url":"https://xn--b1afbosiaouc3h.xn--p1ai/logo.png","width":"512","height":"512"}},"headline":"Как создать интерактивный слайдер с плавными эффектами перехода","description":"Пошаговое руководство по созданию профессионального слайдера с CSS-анимациями и JavaScript-методами для различных эффектов переключения.","keywords":["слайдер","плавный переход","галерея","карусель","css анимации","javascript слайдер","эффекты перехода","профессиональный слайдер"],"image":[],"articleBody":""}},{"@type":"ListItem","@id":"https://xn--b1afbosiaouc3h.xn--p1ai/c/web/q/problems-loading-site-old-ios-version","name":"Проблемы загрузки сайта на старых iOS: диагностика и решения","position":10,"item":{"@type":"Article","@id":"https://xn--b1afbosiaouc3h.xn--p1ai/c/web/q/problems-loading-site-old-ios-version","mainEntityOfPage":{"@type":"WebPage","@id":"https://xn--b1afbosiaouc3h.xn--p1ai/c/web/q/problems-loading-site-old-ios-version"},"inLanguage":"ru","dateCreated":"2026-04-06T13:19:53.054Z","datePublished":"2026-04-06T13:19:53.054Z","dateModified":"2026-04-08T08:01:47.880Z","author":[{"@type":"Person","@id":"https://xn--b1afbosiaouc3h.xn--p1ai/@apple-dev-team","name":"Apple Developer Team","givenName":"Apple","familyName":"Developer Team","url":"https://xn--b1afbosiaouc3h.xn--p1ai/@apple-dev-team","jobTitle":"Команда разработчиков документации","description":"Команда инженеров и технических писателей Apple, ответственных за создание и поддержание документации для разработчиков экосистемы Apple."},{"@type":"Person","@id":"https://xn--b1afbosiaouc3h.xn--p1ai/@alexis","name":"Alexis Deveria","givenName":"Alexis","familyName":"Deveria","url":"https://xn--b1afbosiaouc3h.xn--p1ai/@alexis","jobTitle":"Веб-разработчик","description":"Веб-разработчик и создатель сервиса Can I use, специализирующийся на тестировании совместимости веб-технологий и создании инструментов для веб-разработчиков."},{"@type":"Person","@id":"https://xn--b1afbosiaouc3h.xn--p1ai/@mdn-team","name":"MDN Team contributors","givenName":"MDN Team","familyName":"contributors","url":"https://xn--b1afbosiaouc3h.xn--p1ai/@mdn-team","jobTitle":"Technical Writers","description":"Команда технических писателей MDN, отвечающая за создание и поддержку документации веб-технологий. Команда состоит из профессиональных авторов, специализирующихся на документации веб-стандартов и API."},{"@type":"Person","@id":"https://xn--b1afbosiaouc3h.xn--p1ai/@react-core","name":"React Team","givenName":"React","familyName":"Team","url":"https://xn--b1afbosiaouc3h.xn--p1ai/@react-core","jobTitle":"Разработчики библиотек","description":"Команда инженеров Facebook (Meta), ответственных за разработку и поддержку React - JavaScript-библиотеки для создания пользовательских интерфейсов."}],"publisher":{"@type":"Organization","@id":"https://xn--b1afbosiaouc3h.xn--p1ai/about","name":"НейроОтветы","url":"https://xn--b1afbosiaouc3h.xn--p1ai/about","logo":{"@type":"ImageObject","url":"https://xn--b1afbosiaouc3h.xn--p1ai/logo.png","width":"512","height":"512"}},"headline":"Проблемы загрузки сайта на старых iOS: диагностика и решения","description":"Причины сбоев загрузки Django+React сайта на iOS ниже версии 26. Совместимость mobile safari 537.36, JavaScript/CSS проблемы и решения для старых версий iOS.","keywords":["mobile safari 537.36","старую версию ios","совместимость ios","ios 26 safari","react ios","safari проблемы","старые версии ios iphone","django react","веб-совместимость","ios safari"],"image":[],"articleBody":""}}]}}]}

Как сделать плавную смену статичного фонового изображения при скролле в JavaScript без резких переходов?

Текущий код меняет фон резко при достижении определенных позиций скролла:

js
// Смена фона при скролле
const back = document.getElementById('back');
const pathImg_1 = "/img/back/back.avif";
const pathImg_2 = "/img/back/back_2.jpg";
const pathImg_3 = "/img/back/back.avif";

window.addEventListener('scroll', ()=>{
 const windowHight = window.innerHeight;
 const hight_1box = document.getElementById('main').offsetHeight;
 const header = document.getElementById('header').offsetHeight;
 const mainBox = document.getElementById('main');
 const hight_2box = document.getElementById('scills_box').offsetHeight;
 const hight_3box = document.getElementById('about').offsetHeight;
 let scrollPosition = window.scrollY;

 const firstShift = hight_1box - header - (header*0.2);
 const secondShift = hight_1box+hight_2box+hight_3box + header;

 if(firstShift<=scrollPosition){
 back.style.backgroundImage = `url(${pathImg_2})`;
 mainBox.style.backgroundColor = 'black';
 }
 if(secondShift<=scrollPosition){
 back.style.backgroundImage = `url(${pathImg_3})`;
 }
 if(secondShift>=scrollPosition){
 back.style.backgroundImage = `url(${pathImg_2})`;
 }
 if(firstShift>=scrollPosition){
 back.style.backgroundImage = `url(${pathImg_1})`;
 mainBox.style.backgroundColor = 'rgba(0, 0, 0, 0.26)';
 }

})

Логика: блоки пролистываются поверх статичного фона. После черного блока фон должен плавно смениться на новый, видимый через прозрачный блок. Рекомендуйте библиотеки (например, GSAP, AOS) или варианты кода с CSS transitions/opacity для smooth background change on scroll.

Для плавной смены статичного фонового изображения при скролле замените резкую установку backgroundImage на два наложенных слоя с плавным изменением opacity через CSS transitions. В вашем коде просто добавьте второй и третий div с position: fixed, transition: opacity 0.6s ease и меняйте их прозрачность по прогрессу скролла — это создаст fade-effect без скачков. Лучший вариант — библиотека GSAP с ScrollTrigger, где анимация привязана к позиции прокрутки: gsap.to('#back2', {opacity: 1, scrollTrigger: {trigger: '#main', scrub: true}}).


Содержание


Проблемы вашего кода и почему фон меняется резко

Ваш скрипт работает по принципу if-условий: как только scrollPosition пересекает порог вроде firstShift, фон мгновенно переключается на pathImg_2. Это создает резкий скачок, потому что backgroundImage не анимируется по умолчанию — браузер просто подставляет новое изображение. Плюс, логика с if(secondShift>=scrollPosition) конфликтует: она может перезаписывать предыдущие изменения хаотично.

А что если трафик на сайт вырастет, и на мобильных скролл будет дерганым? Такие простые слушатели window.scroll вызываются 60+ раз в секунду, жрут CPU и не дают плавности. Блоки вроде #main с прозрачным backgroundColor: rgba(0,0,0,0.26) пролистываются поверх фиксированного #back, но без перехода это выглядит как обрезка фото ножницами.

Решение простое: не меняйте изображение напрямую. Используйте наложение слоев — нижний фон статичный, верхний fade-in’ится. Это стандарт для анимации при скролле, где opacity анимируется от 0 до 1 за 0.5-0.6s.


Базовый подход: два слоя с CSS opacity

Начните с HTML: добавьте несколько фиксированных фонов.

html
<div id="back-wrapper" style="position: fixed; top:0; left:0; width:100%; height:100%; z-index: -1; overflow: hidden;">
 <div id="back1" style="position: absolute; top:0; left:0; width:100%; height:100%; background-image: url('/img/back/back.avif'); background-size: cover; opacity: 1; transition: opacity 0.6s ease;"></div>
 <div id="back2" style="position: absolute; top:0; left:0; width:100%; height:100%; background-image: url('/img/back/back_2.jpg'); background-size: cover; opacity: 0; transition: opacity 0.6s ease;"></div>
 <div id="back3" style="position: absolute; top:0; left:0; width:100%; height:100%; background-image: url('/img/back/back.avif'); background-size: cover; opacity: 0; transition: opacity 0.6s ease;"></div>
</div>

CSS transition на opacity сделает fade плавным — браузер сам интерполирует. В JS просто:

js
const back1 = document.getElementById('back1');
const back2 = document.getElementById('back2');
const back3 = document.getElementById('back3');
// ... ваши расчеты firstShift, secondShift

window.addEventListener('scroll', () => {
 let scrollPosition = window.scrollY;
 if (scrollPosition >= firstShift) {
 back1.style.opacity = 0;
 back2.style.opacity = 1;
 }
 if (scrollPosition >= secondShift) {
 back2.style.opacity = 0;
 back3.style.opacity = 1;
 }
});

Почему это работает лучше? Opacity — анимируемое свойство, в отличие от backgroundImage. Но на длинных страницах scroll-событие все равно тормозит. Переходим к оптимизации.


Vanilla JS решение с requestAnimationFrame

Чтобы избежать лагов, добавьте throttle через requestAnimationFrame — он синхронизирует с 60fps браузера. Плюс, вычисляйте прогресс плавно: не бинарный if, а progress = Math.min(scrollY / диапазон, 1) для градиентного fade.

Вот полный рефакторинг вашего кода:

js
let ticking = false;
const backs = {
 1: document.getElementById('back1'),
 2: document.getElementById('back2'),
 3: document.getElementById('back3')
};

function updateBackground() {
 const scrollY = window.scrollY;
 const windowHeight = window.innerHeight;
 // ... ваши hight_1box и т.д.
 const firstShift = hight_1box - header - (header * 0.2);
 const secondShift = hight_1box + hight_2box + hight_3box + header;
 
 // Плавный прогресс для первого перехода
 const progress1 = Math.max(0, Math.min(1, (scrollY - firstShift + windowHeight * 0.2) / (windowHeight * 0.5)));
 backs[1].style.opacity = 1 - progress1;
 backs[2].style.opacity = progress1;
 
 // Второй переход
 const progress2 = Math.max(0, Math.min(1, (scrollY - secondShift + windowHeight * 0.2) / (windowHeight * 0.5)));
 backs[2].style.opacity = progress2 * (1 - progress2); // Кросс-фейд
 backs[3].style.opacity = progress2;

 ticking = false;
}

window.addEventListener('scroll', () => {
 if (!ticking) {
 requestAnimationFrame(updateBackground);
 ticking = true;
 }
});

Этот код из ru.stackoverflow дает настоящий плавный скролл без библиотек. Прозрачные блоки вроде #main теперь идеально показывают новый фон сквозь fade.


GSAP ScrollTrigger для идеальной анимации при скролле

Хотите профессиональный уровень? GSAP — король анимации смены фона. Подключите <script src="https://cdnjs.cloudflare.com/ajax/libs/gsap/3.12.2/gsap.min.js"></script> и ScrollTrigger.

Установка: gsap.registerPlugin(ScrollTrigger);

Код для вашей страницы:

js
gsap.registerPlugin(ScrollTrigger);

gsap.timeline({
 scrollTrigger: {
 trigger: "#main",
 start: "top bottom",
 end: "#scills_box bottom",
 scrub: 1, // Привязка к скорости скролла
 ease: "power2.inOut"
 }
})
.to("#back1", {opacity: 0, duration: 1})
.to("#back2", {opacity: 1, duration: 1}, 0);

gsap.timeline({
 scrollTrigger: {
 trigger: "#about",
 start: "top bottom",
 end: "bottom bottom",
 scrub: 1
 }
})
.to("#back2", {opacity: 0, duration: 1})
.to("#back3", {opacity: 1, duration: 1}, 0);

Scrub делает переход пропорциональным скроллу — скроллишь медленно, анимация растягивается. Для трех изображений используйте одну timeline с позициями: .to("#back2", {}, 0.5).to("#back3", {}, 1). Примеры в GSAP форуме показывают, как это бьет vanilla на headless.


IntersectionObserver и альтернативы вроде AOS

Если GSAP overkill, попробуйте IntersectionObserver — нативный API для появления элементов при скролле. Добавьте data-bg к блокам:

js
const observer = new IntersectionObserver((entries) => {
 entries.forEach(entry => {
 if (entry.isIntersecting) {
 const nextBg = entry.target.dataset.bg;
 const current = document.querySelector('.back-current');
 const next = document.querySelector('.back-next');
 next.style.backgroundImage = `url(${nextBg})`;
 next.style.opacity = 1;
 current.style.opacity = 0;
 current.classList.remove('back-current');
 next.classList.add('back-current');
 }
 });
}, { threshold: 0.5 });

observer.observe(document.getElementById('main'));
observer.observe(document.getElementById('scills_box'));

AOS (Animate On Scroll) проще: подключите CDN, добавьте data-aos="fade-up" к блокам, но для фона комбинируйте с opacity. jQuery-вариант из gravitsapa подойдет для legacy: $(window).scroll(function(){ if(scroll >= 500) $('.back-next').animate({opacity:1},400); });.


Оптимизация и производительность

Не забывайте: preload изображений (<link rel="preload" as="image" href="/img/back/back_2.jpg">), чтобы fade не ждал загрузки. Тестируйте на мобильных — fixed backgrounds иногда глючат в iOS. Для parallax добавьте transform: translateY в GSAP.

Если страницы длинные, комбинируйте с will-change: opacity в CSS. И да, throttle спасет от 1000+ вызовов scroll в секунду на тач-устройствах.


Источники

  1. qna.habr.com/q/309680
  2. ru.stackoverflow.com/questions/717611
  3. gravitsapa.info/…jquery
  4. gsap.com/…scroll
  5. webgolovolomki.com/…skrolle
  6. ru.stackoverflow.com/…prokrutke
  7. dejurka.ru/…pure-css
  8. gsap.com/…on-scroll

Заключение

Плавная смена фона при скролле достигается opacity-слоями с transitions или GSAP ScrollTrigger — забудьте про резкие if. Начните с vanilla JS для простоты, перейдите на GSAP для wow-эффекта. Тестируйте на реальных устройствах, и ваша страница полетит. Готовый код сэкономит часы — копируйте и адаптируйте под свои пороги.

Авторы
Проверено модерацией
НейроОтветы
Модерация
Плавная смена фона при скролле в JavaScript без резких переходов