background:cover не масштабируется в мобильных браузерах

Проект, над которым я работаю, представляет собой одностраничный веб-сайт, разделенный на разделы, первый раздел — это заголовок с нанесенным на него фоновым изображением. Моя цель — сделать так, чтобы это изображение реагировало на изменение размера, поэтому я установил для свойства background-size значение cover.

При масштабировании области просмотра в настольном браузере изображение соответственно масштабируется. Однако на мобильных клиентах (протестировано на iOS 7 и Andriod Froyo/Kitkat) изображение, кажется, остается на своей полной ширине/высоте, становясь очень пикселизированным и искаженным.

пример: http://www.bardiadost.ca

Сначала я подумал, что проблема была с отступом -500% и отступом 500%, который у меня был слева/справа от каждого раздела (я использую это для создания разделов полной ширины, сохраняя содержимое внутри моей сетки). Я вынул этот код и все еще получал тот же результат. Если у кого-то есть какие-либо подсказки относительно того, что я делаю неправильно, это было бы здорово.

Обновить

Я провел дополнительное расследование и подумал, что это может быть проблема iOS из-за ограничений на размер изображения (Подробнее здесь) и заменил мое довольно большое изображение размером 1,2 МБ на GIF размером 500 КБ. Однако проблема остается.

Обновление 2

Полного решения пока не нашел, но нашел исправление, которым доволен.

В моих глобальных стилях эти свойства фона установлены в разделе .masthead:

background: $tangerine;

background:
  linear-gradient(
    rgba(232,85,4, .84),
    rgba(232,85,4, .84)
),

url("../images/pano2.png") no-repeat center center;
   -webkit-background-attachment: fixed;
   -moz-background-attachment: fixed;
   -o-background-attachment: fixed;
   -ms-backgroudn-attachment: fixed;
   background-attachment: fixed;

   -webkit-background-size: cover;
   -moz-background-size: cover;
   -o-background-size: cover;
   background-size: cover;

В моей первой контрольной точке медиа-запроса я применяю эти стили к .masthead:

@media only screen and (max-width: 959px){
    -webkit-background-attachment: scroll;
    -moz-background-attachment: scroll;
    -o-background-attachment: scroll;
    -ms-backgroudn-attachment: scroll;
    background-attachment: scroll;
    -webkit-background-size: contain;
    -moz-background-size: contain;
    -o-background-size: contain;
    background-size: contain;
}

contain, кажется, дает мне результат на мобильном устройстве, который я ищу, но только если для свойства background-attachment не установлено значение fixed. Для меня это не было слишком большим компромиссом, поскольку фиксированные фоны в любом случае не работают должным образом на мобильных устройствах.


person BardiaD    schedule 26.05.2014    source источник


Ответы (2)


Вы настроили так, чтобы ваши селекторы CSS вызывали каждый браузер? Некоторым из новых атрибутов и селекторов CSS3 требуются префиксы для работы в разных браузерах:

-webkit-background-size: cover;
-moz-background-size: cover;
-o-background-size: cover;
background-size: cover;
-ms-filter: "progid:DXImageTransform.Microsoft.AlphaImageLoader(src='/images/post_bg.jpg',    sizingMethod='scale')";

Если это не сработает, я думаю, вы сможете исправить это, используя background-size contain; в окнах просмотра для экранов меньшего размера.

person looseleaf    schedule 27.05.2014
comment
К сожалению, ни один из них, похоже, не работал. У меня уже были префиксы поставщиков для background-size (хотя я забыл добавить IE). Я также пробовал использовать contain вместо обложки, которая, казалось, масштабировалась только в Firefox для Android на мобильных устройствах, но на iPad 4 и iPhone 5S тот же пиксельный результат. Также contain масштабирует изображение до наименьшего размера и больше не заполняет весь фон элемента раздела. Голосование за упоминание фильтра MS. - person BardiaD; 27.05.2014

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

Хотя я изначально думал, что моя проблема заключается в том, что background-size не масштабируется должным образом, похоже, проблема была больше связана с background-attachment: fixed. Наличие обоих этих свойств приводило к плохому масштабированию фона, а также не фиксировало изображение на месте во время прокрутки пользователем (Вид ситуации проигрыша/проигрыша).

У этого метода есть некоторые законные недостатки. Впервые я узнал об этом в блоге Four Kitchens, и заслуга Криса Руппеля в том, что он объяснил эту технику. (Исходная статья)

Почему это не работает

Крис более подробно рассказывает о том, почему position: fixed не работает с фоновыми элементами в мобильных браузерах, что связано с количеством перерисовок, которые потребуется сделать браузеру, и как это негативно влияет на производительность. Из-за этого свойство background-attachment не работает должным образом в мобильных браузерах.

Решение

Основная идея этого метода состоит в том, чтобы установить фоновое изображение, как обычно, но вместо того, чтобы установить для свойства вложения значение fixed, вы добавляете position:fixed к самому div, фактически закрепляя его сверху/слева от элемента body.

По сути, сочетание этого со свойством will-change создает новый слой рисования для мобильных устройств, чтобы отрисовывать фон (по сути, делает то же самое, что и translateZ(0)), без пыхтения/прыжков (результат, который вы часто получаете, когда пытаясь сделать это с помощью Javascript). Пожалуйста, прочитайте связанную статью для получения дополнительной информации об этой технике.

HTML:

<section class="masthead">
   ...
</section>

CSS:

.masthead {
   overflow: hidden; // added for pseudo-element
   position: relative; // added for pseudo-element

// Fixed-position background image
   &::before {
      content: ' ';
      position: fixed; // instead of background-attachment
      width: 100%;
      height: 100%;
      top: 0;
      left: 0;
      background: url('/img/front/strategy.jpg') no-repeat center center;
      background-size: cover;
      will-change: transform; // creates a new paint layer
      z-index: -1; //ensures image is behind everything else
   }
}

Я должен упомянуть, что, хотя Крис установил свойства overflow и position для родительского элемента, по моим исследованиям они не действуют. Относительное позиционирование не применяется к фиксированным элементам, равно как и переполнение.

Недостатки

Этот метод работает правильно в моем тестировании, но есть несколько причин, по которым вы можете не захотеть его использовать:

  • Без контроля переполнения: поскольку этот элемент div фиксирован относительно области просмотра, overflow:hidden не действует. Это означает, что вы не можете «обрезать» изображение, чтобы оно поместилось внутри его контейнера div, оно всегда будет заполнять весь фон. На практике это обычно не будет проблемой, так как любой другой контент под <section class="masthead"> будет поверх изображения (фактически скрывая его под остальным контентом). Однако, если по какой-то причине вам нужно вырезать фоновое изображение, чтобы не занимать весь фон, вы можете попробовать использовать свойство clip. см. второй ответ на этот вопрос

  • Видимость при прокрутке (Safari). Это чисто эстетическая вещь, но из-за «прыгучей» прокрутки в Safari, если вы прокручиваете страницу за верхнюю или нижнюю часть страницы, фон будет проглядывать. Это не происходит в Chrome, только в Safari.

  • Одно изображение на странице: кто-то другой мог это понять, но поскольку div, к которому прикреплено это фоновое изображение, фиксировано относительно области просмотра (в точках x:0, y:0), я не могу' не найти способ добавить несколько фиксированных изображений как часть 1 страницы. Проблема в том, что он будет просто располагаться поверх (или позади, в зависимости от его z-индекса) предыдущего изображения. Установка его значения top на жестко закодированное значение pixel/rem/em сместит его вниз, но нет никакого способа точно узнать, насколько далеко он должен сместиться вниз, чтобы выровняться с ассоциированным содержимым (особенно на адаптивном сайте, где содержимое высота не фиксирована).

  • Что-то вроде хака: хотя это полностью работает, и я даже использую его в текущем проекте, над которым работаю. Это кажется хакерским. background-attachment: fixed считает, что это должно быть лучшим решением, если оно работает.

person BardiaD    schedule 13.11.2015
comment
Я согласен, что background-attachment: fixed было бы намного проще! На самом деле, когда я писал эту статью, у FF не было таких проблем с производительностью, как у Chrome. Тем не менее, псевдо работает везде, где я тестировал (мобильный или настольный), и работает хорошо. - person Chris Ruppel; 02.12.2015