После того как шрифт и заглушки блоков были исправлены, страница на айфоне всё равно сдвигалась — на 1–2 пикселя, но на каждой товарной строке, по мере их загрузки. Двадцать строк — и главная уезжает на десятки пикселей рывками. Причина оказалась в четверти пикселя ширины.

Это вторая часть цикла «Вёрстка без сюрпризов». Как вообще ловить сдвиги, которых не видит Chrome, — в первой части.

Как это выглядело

Двигался не блок целиком, а текст под картинкой — ровно на 1–2 пикселя и ровно в момент, когда запускался слайдер. Пользователь описал это точнее любого зонда: «раз движется заголовок, значит что-то с главным изображением».

Причина

Рамка картинки была задана через aspect-ratio — то есть её высота вычисляется от ширины. А ширина у заглушки и у запущенного слайдера разная: слайдер (swiper) округляет ширину слайда до целого пикселя.

заглушка:            ширина 341.25px → высота 191.70px
запущенный слайдер:  ширина 341.00px → высота 191.56px

Четверть пикселя по ширине — 0,14 пикселя по высоте. Браузер округляет к пикселям устройства, и на айфоне с плотностью экрана 3 это около 2 пикселей. На каждой строке, в момент её загрузки.

Без дробных значений этот сдвиг не увидеть: Math.round в замере даёт «0 → 0». Мерить высоту рамки до и после запуска слайдера с toFixed(2).

Лечение: высота напрямую, а не от ширины

Там, где высоту обязан задавать контейнер, её надо задавать прямо — в тех же единицах, в которых задана ширина, — а не выводить из ширины через пропорцию:

/* было: высота зависит от ширины, а ширину меняет слайдер */
.productImage {
  aspect-ratio: 16 / 9;
}

/* стало: ширина контента 87.5vw, пропорция 1.78 → высота 49.16vw */
.productImage {
  aspect-ratio: auto;
  height: 49.16vw;
}

Теперь высота не зависит от того, как слайдер округлит ширину. После правки изменение высоты картинки при загрузке — 0,000 пикселя на всех двадцати строках.

Когда aspect-ratio безопасен

  • когда ширину элемента никто не меняет после первой отрисовки;
  • когда элемент не внутри слайдера, карусели или другого скрипта, который пересчитывает размеры;
  • когда сдвиг на доли пикселя не важен — например, элемент внизу страницы и выше экрана никогда не оказывается.

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

Блоки на странице «подпрыгивают» на пиксель-два при загрузке?

Пришлите адрес — найду, какая рамка зависит от ширины, которую потом меняет скрипт.

· полезно?
АЧ
Алексей Чикун веб-разработчик, команда TRIOHEAD

Делаю сайты и сервисы целиком: от вёрстки до сервера. Пишу о том, что проверил на своих проектах.

Комментарии

// загружаю комментарии…

Комментарии публикуются после проверки. Ссылки и HTML не принимаются.