` и 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/snap-slider-drag-implementation-css-js","name":"Snap переключение слайдов в слайдере при drag: CSS/JS","position":1,"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/slider-peek-effect-swiper-slick-owl-responsive","name":"Слайдер с эффектом peek: Swiper, Slick, Owl адаптивно","position":2,"item":{"@type":"Article","@id":"https://xn--b1afbosiaouc3h.xn--p1ai/c/web/q/slider-peek-effect-swiper-slick-owl-responsive","mainEntityOfPage":{"@type":"WebPage","@id":"https://xn--b1afbosiaouc3h.xn--p1ai/c/web/q/slider-peek-effect-swiper-slick-owl-responsive"},"inLanguage":"ru","dateCreated":"2026-01-16T06:45:56.743Z","datePublished":"2026-01-16T06:45:56.743Z","dateModified":"2026-01-16T06:45:56.743Z","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":"Слайдер с эффектом peek: Swiper, Slick, Owl адаптивно","description":"Реализуйте адаптивный слайдер с эффектом peek на Swiper, Slick, Owl Carousel. Настройки slidesPerView, centeredSlides, spaceBetween, breakpoints для мобильных (3 слайда) и десктопов. Формулы расчета ширин и примеры кода.","keywords":["слайдер peek","swiper peek","slick slider peek","owl stagePadding","адаптивный слайдер","slidesPerView","centeredSlides","centerPadding","swiper breakpoints","слайдер html css","карусель с peek"],"image":[],"articleBody":""}},{"@type":"ListItem","@id":"https://xn--b1afbosiaouc3h.xn--p1ai/c/web/q/liquid-glass-effect-css-implementation","name":"Эффект жидкого стекла: реализация CSS и JS кодом","position":3,"item":{"@type":"Article","@id":"https://xn--b1afbosiaouc3h.xn--p1ai/c/web/q/liquid-glass-effect-css-implementation","mainEntityOfPage":{"@type":"WebPage","@id":"https://xn--b1afbosiaouc3h.xn--p1ai/c/web/q/liquid-glass-effect-css-implementation"},"inLanguage":"ru","dateCreated":"2025-12-18T11:42:10.029Z","datePublished":"2025-12-18T11:42:10.029Z","dateModified":"2026-01-14T19:07:21.664Z","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":"Эффект жидкого стекла: реализация CSS и JS кодом","description":"Как создать эффект жидкого стекла (liquid glass) в графическом интерфейсе с помощью CSS backdrop-filter, SVG-фильтров и JavaScript. Базовый код, продвинутые техники, совместимость браузеров и оптимизация производительности для UI.","keywords":["эффект жидкого стекла","стеклянный эффект","как сделать эффект жидкого стекла","backdrop-filter","liquid glass css","glassmorphism","svg фильтры","css стеклянный эффект"],"image":[],"articleBody":""}},{"@type":"ListItem","@id":"https://xn--b1afbosiaouc3h.xn--p1ai/c/web/q/ios-safari-keyboard-viewport-fix","name":"iOS: как заставить Safari менять viewport при фокусе","position":4,"item":{"@type":"Article","@id":"https://xn--b1afbosiaouc3h.xn--p1ai/c/web/q/ios-safari-keyboard-viewport-fix","mainEntityOfPage":{"@type":"WebPage","@id":"https://xn--b1afbosiaouc3h.xn--p1ai/c/web/q/ios-safari-keyboard-viewport-fix"},"inLanguage":"ru","dateCreated":"2026-01-03T09:28:44.223Z","datePublished":"2026-01-03T09:28:44.223Z","dateModified":"2026-01-03T09:28:44.223Z","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":"iOS: как заставить Safari менять viewport при фокусе","description":"Почему iOS‑клавиатура в Safari на iPhone не ресайзит layout‑viewport и как это исправить: Visual Viewport API, вычисление --vh, padding‑bottom, scrollIntoView и fallback‑паттерны.","keywords":["ios клавиатура","safari iphone","visual viewport api","visualViewport","--vh","100vh","fixed панель","scrollIntoView","высота клавиатуры","padding-bottom"],"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":5,"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":"@alekseyb","url":"https://xn--b1afbosiaouc3h.xn--p1ai/@alekseyb","jobTitle":"Разработчик","description":"Участник сообщества Stack Overflow на русском, отвечает на вопросы по HTML/CSS и верстке."},{"@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), разрабатывающий открытые стандарты и рекомендации по HTML, XHTML, CSS, доступности, приватности и безопасности веба.","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 по HTML/CSS и веб-разработке."},{"@type":"Organization","@id":"https://xn--b1afbosiaouc3h.xn--p1ai/@sky-pro","name":"Skypro","description":"Онлайн-университет Skypro для обучения IT-профессиям (разработка, дизайн, маркетинг, аналитика) с практическими курсами, вики-статьями и гарантией трудоустройства.","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-prevent-horizontal-scroll-mobile-menu","name":"Как запретить горизонтальный скроллинг в мобильном меню","position":6,"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/flexbox-block-sizes-40-percent-max-600px-legacy","name":"Flexbox: правый блок 40% (max 600px), левый — остаток","position":7,"item":{"@type":"Article","@id":"https://xn--b1afbosiaouc3h.xn--p1ai/c/web/q/flexbox-block-sizes-40-percent-max-600px-legacy","mainEntityOfPage":{"@type":"WebPage","@id":"https://xn--b1afbosiaouc3h.xn--p1ai/c/web/q/flexbox-block-sizes-40-percent-max-600px-legacy"},"inLanguage":"ru","dateCreated":"2025-11-03T00:55:20.878Z","datePublished":"2025-11-03T00:55:20.878Z","dateModified":"2026-01-11T13:23:48.640Z","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":"Flexbox: правый блок 40% (max 600px), левый — остаток","description":"Как задать размеры блоков в flexbox: правый — 40% ширины контейнера, но не более 600px, левый занимает остаток. Примеры кода с flex: 0 0 40%, max-width, flex-basis, поддержка IE10/Windows 7 и старых браузеров.","keywords":["flexbox","flexbox css","flexbox ширина","flexbox блоки","свойства flexbox","flex-basis","flex-grow","max-width flexbox","flexbox ie10","flexbox примеры"],"image":[],"articleBody":""}},{"@type":"ListItem","@id":"https://xn--b1afbosiaouc3h.xn--p1ai/c/web/q/align-multiple-charts-axes-highcharts","name":"Как выровнять оси нескольких графиков в Highcharts","position":8,"item":{"@type":"Article","@id":"https://xn--b1afbosiaouc3h.xn--p1ai/c/web/q/align-multiple-charts-axes-highcharts","mainEntityOfPage":{"@type":"WebPage","@id":"https://xn--b1afbosiaouc3h.xn--p1ai/c/web/q/align-multiple-charts-axes-highcharts"},"inLanguage":"ru","dateCreated":"2026-01-16T06:34:36.384Z","datePublished":"2026-01-16T06:34:36.384Z","dateModified":"2026-01-16T06:34:36.384Z","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":"Как выровнять оси нескольких графиков в Highcharts","description":"Синхронизация осей и выравнивание нескольких графиков в Highcharts: решение проблемы непредсказуемого рендера заголовков. Пошаговая инструкция с кодом, marginLeft, plotLeft и обработкой особых случаев как opposite yAxis.","keywords":["highcharts","выравнивание графиков","синхронизация осей","highcharts оси","выровнять графики highcharts","highcharts marginleft","plotleft highcharts","highcharts chart","график highcharts","highcharts js"],"image":[],"articleBody":""}},{"@type":"ListItem","@id":"https://xn--b1afbosiaouc3h.xn--p1ai/c/web/q/woocommerce-switch-product-cards-by-color-without-variations","name":"Переключение карточек товаров по цвету в WooCommerce без вариаций","position":9,"item":{"@type":"Article","@id":"https://xn--b1afbosiaouc3h.xn--p1ai/c/web/q/woocommerce-switch-product-cards-by-color-without-variations","mainEntityOfPage":{"@type":"WebPage","@id":"https://xn--b1afbosiaouc3h.xn--p1ai/c/web/q/woocommerce-switch-product-cards-by-color-without-variations"},"inLanguage":"ru","dateCreated":"2026-01-17T12:18:49.115Z","datePublished":"2026-01-17T12:18:49.115Z","dateModified":"2026-01-17T12:18:49.115Z","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":"Переключение карточек товаров по цвету в WooCommerce без вариаций","description":"Как реализовать свитчинг карточек товаров при выборе цвета обуви в WooCommerce без вариативных продуктов. Meta-поля, хуки, AJAX и JS для динамического каталога как на маркетплейсах. SEO-дружественный подход с примерами кода.","keywords":["woocommerce","переключение карточек товаров","цвет обуви","без вариативных продуктов","ajax woocommerce","хуки woocommerce","woocommerce товары","цвет товара","вариация woocommerce","woocommerce карточки товара","woocommerce variation"],"image":[],"articleBody":""}},{"@type":"ListItem","@id":"https://xn--b1afbosiaouc3h.xn--p1ai/c/web/q/vis-js-network-focus-node-by-url-id","name":"vis.js Network: фокус на узле по ID из URL","position":10,"item":{"@type":"Article","@id":"https://xn--b1afbosiaouc3h.xn--p1ai/c/web/q/vis-js-network-focus-node-by-url-id","mainEntityOfPage":{"@type":"WebPage","@id":"https://xn--b1afbosiaouc3h.xn--p1ai/c/web/q/vis-js-network-focus-node-by-url-id"},"inLanguage":"ru","dateCreated":"2026-01-03T14:17:31.203Z","datePublished":"2026-01-03T14:17:31.203Z","dateModified":"2026-01-03T14:17:31.203Z","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":"vis.js Network: фокус на узле по ID из URL","description":"Как в vis.js Network автоматически выделить узел по ID из URL (?node=123), отцентрировать и увеличить масштаб с помощью network.focus, selectNodes и stabilized. Полный пример кода на JavaScript для загрузки страницы.","keywords":["vis js","vis network","vis.js network","network focus","selectnodes","фокус на узле","url параметры","vis.js stabilized","network moveto"],"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 без резких переходов