положение: исправлено, не работает на iPad и iPhone


132

Некоторое время я боролся с фиксированным позиционированием в iPad. Я знаю iScroll, и он не всегда работает (даже в их демонстрации). Я также знаю, что у Sencha есть исправление для этого, но я не мог Ctrl+ Fисходный код для этого исправления.

Я надеюсь, что у кого-то есть решение. Проблема в том, что фиксированные элементы не обновляются, когда пользователь перемещает вниз / вверх в мобильном Safari под управлением iOS.


2
Похоже, что jQuery Mobile 1.1 решил эту проблему: jquerymobile.com/blog/2012/04/13/announcing-jquery-mobile-1-1-0
Tower


Возможно дублирование нескольких вопросов SO. Смотрите gist.github.com/avesus/… для подробностей.
Брайан Хаак,

Ответы:


66

Многие мобильные браузеры намеренно не поддерживают их position:fixed;на том основании, что фиксированные элементы могут мешать на маленьком экране.

На сайте Quirksmode.org есть очень хорошее сообщение в блоге, объясняющее проблему: http://www.quirksmode.org/blog/archives/2010/12/the_fifth_posit.html

Также на этой странице представлена ​​диаграмма совместимости, показывающая, какие мобильные браузеры поддерживают position:fixed;: http://www.quirksmode.org/m/css.html

(но обратите внимание, что мир мобильных браузеров развивается очень быстро, поэтому такие таблицы могут не оставаться актуальными надолго!)

Обновление: как сообщается, iOS 5 и Android 4 имеют поддержку position: fixed.

Я сам протестировал iOS 5 сегодня в магазине Apple и могу подтвердить, что она работает с фиксированным положением. Однако есть проблемы с увеличением и панорамированием фиксированного элемента.

Я нашел эту таблицу совместимости гораздо более актуальной и полезной, чем таблица quirksmode: http://caniuse.com/#search=fixed

Он содержит актуальную информацию об Android, Opera (mini и mobile) и iOS.


position:device-fixedбыло бы излишним. position:fixedдолжен просто работать в соответствии со спецификациями W3C.
Talvi Watia

@TalviWatia - device-fixedрешение не было частью моего ответа. Это может быть, а может и не иметь заслуг в качестве предложения, но причиной ссылки было объяснение проблемы, а не предложенное им решение. В любом случае, с тех пор, как этот ответ был опубликован (как я уже сказал), многое изменилось, и многие новые устройства поддерживают fixed. Однако вам все еще нужно иметь дело со старыми устройствами, которые этого не делают.
Spudley

54
Мне любопытно, как именно вы решаете проблему? Ссылки, которые вы предоставили, хотя и могут быть полезны, не решают проблему. Чтобы не пресыщаться, люди склонны голосовать за ответы, которые на самом деле не являются ответами на SO.
Талви Ватия

1
@TalviWatia: В то время, когда я писал ответ, на самом деле не было хорошего решения вопроса. Ссылка, которую я дал, была лучшим обсуждением, которое я знал, чтобы объяснить, почему все было так, как есть, что в отсутствие решения было настолько хорошо, насколько я мог предложить. Ситуация изменилась за прошедший период, поэтому обсуждение в ссылке больше не актуально, и сейчас есть решения, но так было в то время.
Spudley

На самом деле position: fixed работает для масштаба 1, но когда пользователь увеличивает масштаб ipad, он не работает нормально. позиция: фиксированное устройство существует ?? Действителен ли атрибут css для сафари ios?
ccsakuweb

37

Фиксированное позиционирование не работает на iOS, как на компьютерах.

Представьте, что у вас есть лист бумаги (веб-страница) под увеличительным стеклом (окно просмотра). Если вы переместите увеличительное стекло и глаз, вы увидите другую часть страницы. Так работает iOS.

Теперь есть лист прозрачного пластика с надписью на нем, этот лист пластика остается неподвижным, несмотря ни на что (положение: фиксированные элементы). Таким образом, когда вы перемещаете увеличительное стекло, кажется, что неподвижный элемент движется.

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

Итак, в iOS область просмотра перемещается, в традиционном браузере перемещается веб-страница. В обоих случаях фиксированные элементы остаются в реальности; хотя в iOS кажется, что фиксированные элементы движутся.


Способ обойти это - следовать нескольким последним абзацам в этой статье.

(в основном полностью отключите прокрутку, поместите содержимое в отдельный прокручиваемый div (см. синее поле в верхней части связанной статьи), а фиксированный элемент расположен абсолютно)


"position: fixed" теперь работает, как и следовало ожидать в iOS5.


Есть некоторые странные вещи, которые происходят с положением: исправлено при увеличении масштаба на IOS. См. Stackoverflow.com/questions/52085998/…
Питер Холлингсворт,

23

position: fixed работает на android / iphone для вертикальной прокрутки. Но вам нужно убедиться, что ваши метатеги полностью настроены. например

<meta name="viewport" content="width=device-width, height=device-height, initial-scale=1.0, user-scalable=0, minimum-scale=1.0, maximum-scale=1.0">

Кроме того, если вы планируете использовать ту же страницу на Android до 4.0, вам также необходимо установить верхнюю позицию, иначе по какой-то причине будет добавлен небольшой запас.


Это на самом деле работает для меня. Раньше position: fixed на скрытом элементе ввода (см. Чистый CSS вне экранной навигации) вызывало сбой браузера на iphone ios 8.3, но не на планшете. После работает нормально.
Стивен Смит

Не работало на iPad iOS 10.3, горизонтально на квадратной подставке. Допустимый автор утверждает, что этот подход предназначен для «телефонов».
SushiGuy

2
Отключение функции масштабирования пользователя user-scalable=0, minimum-scale=1.0, maximum-scale=1.0может сделать страницу менее доступной для многих пользователей. Было бы полезно добавить предупреждение об этом в свой ответ
neiya

22

теперь Apple поддерживает это

overflow:hidden;
-webkit-overflow-scrolling:touch;

Это именно то , что я был после того, как решить мою background-size: coverи fixedпроблемы на IPad
andyb

Это работает в Mobile Safari в iOS 7. Примечание. Это не будет работать для пользователей, которые еще не обновились до этой версии.
Нил Монро,

Тогда должны быть другие переменные в работе. Я тестировал на iOS 6, и он не работал, затем на iOS 7, и это было.
Нил Монро,

@NeilMonroe хм, может быть. Я уверен, что сделал это на iOS 6 без проблем, но, возможно, я использовал другую переменную. не помню
Угур Озпынар

это было действительно полезно, но, похоже, overflowдолжно быть установлено наscroll

19

У меня была эта проблема в Safari (iOS 10.3.3) - браузер не перерисовывал, пока не сработало событие touchend. Неподвижные элементы не появлялись или были обрезаны.

Уловкой для меня было добавление transform: translate3d (0,0,0); к моему элементу фиксированной позиции.

.fixed-position-on-mobile {
  position: fixed;
  transform: translate3d(0,0,0);
}

РЕДАКТИРОВАТЬ - теперь я знаю, почему преобразование устраняет проблему: аппаратное ускорение. Добавление трехмерного преобразования запускает ускорение графического процессора, обеспечивая плавный переход. Подробнее об аппаратном ускорении читайте в этой статье: http://blog.teamtreehouse.com/increase-your-sites-performance-with-hardware-accelerated-css .


Это фактически устранило мою проблему с прокруткой, она подпрыгивала на устройствах iOS при использовании fixed, добавила, transformи это было исправлено.
vonUbisch

17

Фиксированный нижний колонтитул (здесь с jQuery):

if (navigator.platform == 'iPad' || navigator.platform == 'iPhone' || navigator.platform == 'iPod' || navigator.platform == 'Linux armv6l') 
{
    window.ontouchstart = function () 
    {
        $("#fixedDiv").css("display", "none");
    }

    window.onscroll = function() 
    { 
        var iPadPosition = window.innerHeight + window.pageYOffset-45; // 45 is the height of the Footer
         $("#fixedDiv").css("position", "absolute");
         $("#fixedDiv").css("top", iPadPosition);
         $("#fixedDiv").css("display", "block");
    }
}

// in the CSS file should stand:
#fixedDiv {position: fixed; bottom: 0; height: 45px;  whatever else}

Надеюсь, поможет.


7

Избегайте использования одного и того же блока с помощью transform: --- и position: fixed. Элемент останется в позиции: статический, если есть какое-либо преобразование.


6

В итоге я использовал новый jQuery Mobile v1.1: http://jquerymobile.com/blog/2012/04/13/announcing-jquery-mobile-1-1-0/

Теперь у нас есть основательная переработка, которая предоставляет действительно фиксированные панели инструментов на многих популярных платформах и безопасно возвращается к статическому позиционированию панелей инструментов в других браузерах.

Самым крутым в этом подходе является то, что, в отличие от решений на основе JS, которые накладывают неестественную физику прокрутки на все платформы, наша прокрутка кажется на 100% естественной, потому что это так . Это означает, что прокрутка ощущается везде и работает с сенсорным вводом, колесом мыши и клавиатурой. В качестве бонуса наше решение на основе CSS очень легкое и не влияет на совместимость или доступность.


Также довольно элегантен (но определенно обходной путь) этот метод разрешения фиксированных объектов на iOS без использования jQuery или JavaScript (использует только CSS). Это довольно универсально. Если вы хотите, position:fixedчтобы перед вашей прокручиваемой страницей появлялся «плавающий» элемент, вам просто нужно присвоить ему более высокое z-indexзначение, чтобы он оставался впереди.
Slink

это определенно не отвечает на вопрос.
Густаво Сикейра

1

используя jquery, я могу это придумать. он не прокручивается плавно, но он помогает. вы можете прокрутить вниз, и фиксированный div появится вверху.

CSS

<style type="text/css">
    .btn_cardDetailsPg {height:5px !important;margin-top:-20px;}
    html, body {overflow-x:hidden;overflow-y:auto;}
    #lockDiv {
  background-color: #fff;
  color: #000;
  float:left;
  -moz-box-shadow: 0px 4px 2px 2px #ccc;-webkit-box-shadow: 0px 4px 2px 2px #ccc;box-shadow:0px 4px 2px 2px #ccc;
  }
#lockDiv.stick {
  position: fixed;
  top: 0;
  z-index: 10000;
  margin-left:0px;
  }
</style>

HTML

<div id="lockSticky"></div>
<div id="lockDiv">fooo</div>

ЗАКАЗ

<script type="text/javascript">
    function sticky_relocate() {
        var window_top = $(window).scrollTop();
        var div_top = $('#lockSticky').offset().top;
        if (window_top > div_top)
            $('#lockDiv').addClass('stick')
        else
            $('#lockDiv').removeClass('stick');
    }
    $(function() {
        $(window).scroll(sticky_relocate);
        sticky_relocate();
    });
</script>

Наконец, мы хотим определить, будет ли ipod touch в альбомном или портретном режиме отображаться соответственно.

<script type="text/javascript">
    if (navigator.userAgent.match(/like Mac OS X/i)) {
        window.onscroll = function() {

        if (window.innerWidth > window.innerHeight) {
            //alert("landscape [ ]");
            document.getElementById('lockDiv').style.top =
            (window.pageYOffset + window.innerHeight - 268) + 'px';
        }

        if (window.innerHeight > window.innerWidth) {
            //alert("portrait ||");
            document.getElementById('lockDiv').style.top =
            (window.pageYOffset + window.innerHeight - 418) + 'px';
        }
        };
    }
</script>

1

Несмотря на то, что атрибут CSS {position:fixed;}кажется (в основном) работает на новых устройствах iOS, возможна ошибка устройства и откат к{position:relative;} от времени и без причины или причины. Обычно очистка кеша помогает, пока что-то не произойдет и причуда не повторится снова.

В частности, от самой Apple Подготовка вашего веб-контента для iPad :

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

Как это ни парадоксально, у устройств Android, похоже, нет этой проблемы. Также вполне возможно использовать{position:absolute;} при обращении к тегу body и не иметь никаких проблем.

Я нашел первопричину этой причуды; что это событие прокрутки плохо воспроизводится при использовании вместе с тегами HTML или BODY. Иногда ему не нравится запускать событие, или вам придется дождаться завершения события прокрутки, чтобы получить событие. В частности, область просмотра перерисовывается в конце этого события, и фиксированные элементы могут быть перемещены в другое место в области просмотра.

Вот что я делаю: ( избегайте использования области просмотра и придерживайтесь DOM! )

<html>
  <style>
    .fixed{
      position:fixed;
      /*you can set your other static attributes here too*/
      /*like height and width, margin, etc.*/
      }
    .scrollableDiv{
      position:relative;
      overflow-y:scroll;
      /*all children will scroll within this like the body normally would.*/
      } 
    .viewportSizedBody{
      position:relative;
      overflow:hidden;
      /*this will prevent the body page itself from scrolling.*/
      } 
  </style>
  <body class="viewportSizedBody">
    <div id="myFixedContainer" class="fixed">
       This part is fixed.
    </div>
    <div id="myScrollableBody" class="scrollableDiv">
       This part is scrollable.
    </div>
  </body>
  <script type="text/javascript" src="{your path to jquery}/jquery-1.7.2.min.js"></script>
  <script>
    var theViewportHeight=$(window).height();
    $('.viewportSizedBody').css('height',theViewportHeight);
    $('#myScrollableBody').css('height',theViewportHeight);
  </script>
</html>

По сути, это приведет к тому, что BODY будет иметь размер области просмотра и не прокручивается. Прокручиваемый DIV, вложенный внутрь, будет прокручиваться, как обычно, BODY (без эффекта поворота, поэтому прокрутка останавливается при касании). Фиксированный DIV остается фиксированным без помех.

В качестве примечания: высокое z-indexзначение фиксированного DIV важно, чтобы прокручиваемый DIV оставался позади него. Я обычно добавляю события изменения размера окна и прокрутки также для кроссбраузерности и совместимости с альтернативным разрешением экрана.

Если ничего не помогает, приведенный выше код также будет работать с фиксированными и прокручиваемыми DIV, установленными в {position:absolute;}.


1

Простой способ решить эту проблему - просто ввести свойство transform для вашего элемента. и это будет исправлено. Удачного кодирования :-)

.classname{
  position: fixed;
  transform: translate3d(0,0,0);
}

Также вы можете попробовать его способ, это тоже нормально.

.classname{
      position: -webkit-sticky;
    }

0

Это может быть применимо не ко всем сценариям, но я обнаружил, что position: sticky(то же самое с position: fixed) работает только на старых iPhone, когда контейнер для прокрутки не в теле, а внутри чего-то другого.

Пример псевдо HTML:

body                         <- scrollbar
   relative div
       sticky div

Прикрепленный div будет липким в настольных браузерах, но с некоторыми устройствами, протестированными с помощью: Chromium: dev tools: эмуляция устройства: iPhone 6/7/8, а с Android 4 Firefox - нет.

Однако что будет работать, так это

body
    div overflow=auto       <- scrollbar
        relative div
            sticky div

0

В моем случае это произошло потому, что фиксированный элемент отображался с помощью анимации. Как указано в этой ссылке :

в Safari 9.1 наличие position: fixed-element внутри анимированного элемента может привести к тому, что position: fixed-element не появится.


-2

вот мое решение этого ...

CSS

#bgimg_top {
    background: url(images/bg.jpg) no-repeat 50% 0%; 
    position: fixed; 
    top:0; 
    left: 0; 
    right:0 ; 
    bottom:0;
}

HTML

<body>
<div id="bgimg_top"></div>
....
</body>

Объяснение заключается в том, что фиксированная позиция для div будет держать div на заднем плане все время, затем мы растягиваем div, чтобы перейти во все углы браузера (при условии, что поле тела = 0), используя (left, right, top, bottom ) одновременно.

Убедитесь, что вы не используете ширину и высоту, так как это переопределит параметры вверху, слева, справа и снизу.

Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.