Katsuro
Проверенные
- Сообщения
- 144
- Решения
- 1
- Реакции
- 47
- Баллы
- 1,730
Инструкция взята с Хабр'а и не является моим, я лишь изменил классы под XF и опубликовал сюда из-за распространённости проблемы: https://habr.com/ru/post/282079/
Решил я тут недавно на одном из своих сайтов сделать легкий редизайн. И дошло дело до фона. Показался он мне каким-то скучным. Захотелось его немного «оживить». Подобрал подходящую картинку небольшого размера, загнал ее в свойство фона:
CSS:
.p-pageWrapper {
background: url("../images/bg.jpg") no-repeat center center / cover fixed;
}
и довольный нажал F5. Красота, да и только!
Начал скроллить страничку вниз и чувствую, что-то не то…
Сначала я погрешил на свойство
cover
, но дело оказалось не в нем. Отключив фиксированное положение фона (убрав fixed
), мой «Crysis» выдал мне больше 30 FPS! «Во дела...», подумал я. Как же так? Почему? Почему я не замечал этого раньше? Возможно, это не очень заметно на легковесных сайтах, где не так много html элементов.А дело оказалось вот в чем. Использование
background-attachment : fixed
каждый раз при прокрутке вызывает операцию перерисовки. Страница должна переместить свое содержимое. И когда дело доходит до фиксированного фона, браузер должен заново прорисовать картинку в новом месте, относительно существующих DOM-элементов.Чтобы решить эту проблему, нашему фоновому изображению нужен свой элемент, чтобы оно могло двигаться независимо от других. А также нам понадобится CSS3-свойство
will-changed
. О нем речь пойдет ниже.Как только мы решим проблему с прорисовкой, скроллинг уже не будет проходить у нас рывками. Так как фон будет лежать на своем собственном слое, больше не потребуется перерисовывать страницу каждый раз при прокрутке.
Давайте я покажу все на примере.
Это наш изначальный код (я развернул свойства для наглядности):
CSS:
.p-pageWrapper {
background: url("../images/bg.jpg") no-repeat center center;
background-attachment: fixed;
background-size: cover;
}
А вот, что нам необходимо сделать для решения проблемы:
CSS:
.p-pageWrapper{
position: relative;
}
.p-pageWrapper::before {
background: url("../images/bg.jpg") no-repeat center center;
background-size: cover;
content: ' ';
height: 100%;
left: 0;
position: fixed;
top: 0;
width: 100%;
will-change: transform;
z-index: -1;
}
Мы добавили
position: relative
для элемента p-pageWrapper
, чтобы затем спозиционировать псевдо-элемент, который будет отдельным слоем для нашего фона. Остальные свойства, касательно фона, мы перенесли в ::before
. У псевдо-элемента мы теперь используем position: fixed
, вместо прежнего background-attachment: fixed
у p-pageWrapper
. Ну и самое важное, без чего вся затея потерпит крах — это свойство
У Вас недостаточно прав для просмотра ссылок.
Вход или Регистрация
.Свойство will-change предписывает браузеру отображать элемент, независимо от окружающих его других элементов. Оно как бы говорит браузеру: «Эй, друг, этот элемент изменится когда-нибудь потом, в будущем, так что прорисуй его только один раз на его собственном слое. И не нужно учитывать остальные элементы — он сам по себе».
Такие вот дела.
Данный билд я протестировал в разных браузерах, и вот небольшое резюме:
- Google Chrome. Все ОК, работает как часы.
- Mozilla Firefox. Все ОК, работает как часы.
- Opera. Все ОК, работает как часы.
- Safari. Все ОК, работает как часы. За проверку спасибо
У Вас недостаточно прав для просмотра ссылок. Вход или Регистрация
- Microsoft Edge. Метод работает, но есть один косяк. Если крутить колесиком, то дергается верх и низ страницы, но потом приходят в норму. Если же крутить с помощью скроллбара, то все ОК.
- Internet Explorer. Та же проблема, что и у Edge.
Последнее редактирование: