CSS: позиция: фиксированная внутри позиции: абсолютная
Я сталкиваюсь с некоторыми чрезвычайно странными поведениями и непоследовательными в каждом браузере, который я тестировал.
У меня довольно сложный макет, но главная проблема здесь:
<div id="drop">
<div id="header"></div>
</div>
#drop
имеет position:absolute
и z-index:100
#header
имеет position:fixed; top:60px;
Когда я начинаю прокручивать Chrome, игнорирует правило position:fixed
. Если я удалю один из двух стилей выше #drop
, то Chrome начнет соблюдать правило position:fixed
.
не может заставить его работать с Ubuntu Chrome 23.0.1271.97 и видеть то же поведение на Mac Chrome 25.0.1364.99. Мой друг использует бета-версию Ubuntu Chrome 25.0.1364.68, и он работает правильно для него. Я тестировал его на firefox, и это работает (с другими симптомами).
Кто-нибудь слышал об этой ошибке? или кто-нибудь может воспроизвести его?
Изменить
Я использую openlayers map как еще один div с position:fixed
, если я удалю этот слой или, по крайней мере, измените его на display:none
, тогда эта странная ошибка исчезнет.
Изменить
Отмечено, что во время присутствия этой ошибки, если я изменил уровень масштабирования взад и вперед, позиция будет соответствовать правильному поведению. Для меня это указывает на проблему webkit, которая не выполняет какую-либо внутреннюю функцию обратного вызова в прокрутке.
Еще одна странная вещь: у меня есть несколько ссылок внутри #header
, и они работают, если я просто нажимаю на ожидаемое местоположение, даже если div там не отображается. В целом Я заметил, что это только рендеринг, который сломался. Если в любой момент времени я заставляю браузер повторно визуализировать, изменяя размер окна или изменяя масштаб, или просто делая Select-All, тогда панель заголовка переходит в правильное положение, но не остается фиксированной.
Ответы
Ответ 1
В комментариях вы упомянули, что OpenLayers использует CSS-преобразования. В таком случае:
элемент с фиксированным позиционированием станет относительно элемента с преобразованием, а не относительно области просмотра
Посмотрите на спецификацию: Модель рендеринга трансформации
Указание значения, отличного от ‘none, для свойства form transform устанавливает новую локальную систему координат в элементе, применительно к.
.wpr
{
width: 200px;
height:1000px;
background: pink;
position:relative;
margin: 0 200px;
-webkit-transform: translateX(0);
transform: translateX(0);
}
.fixed
{
width: 200px;
height:200px;
margin: 50px;
position: fixed;
top:0;
left:0;
background: aqua;
}
<div class="wpr">
<div class="fixed"></div>
</div>
Ответ 2
Как говорится в принятом ответе, это предполагаемое поведение и соответствует спецификации. Другим важным компонентом этого является то, что означает использование CSS-преобразований.
В вашем случае это было связано с OpenLayers, но это относится и к любому, кто использует will-change: transform
(возможно, многие люди посещают этот вопрос). Это было показано на chromium bug tracker здесь и отмечено как WontFix
, потому что (как я сказал) это предполагаемое поведение. Официальный комментарий таков:
Это поведение требуется спецификацией (http://dev.w3.org/csswg/css-will-change/): "Если какое-либо не начальное значение свойства заставит элемент генерировать содержащий блок для элементов фиксированной позиции, указав, что свойство в изменении должен заставить элемент генерировать содержащий блок для элементы фиксированной позиции."
Идея заключается в том, что однажды изменится: будет указано преобразование, вы должны иметь возможность добавлять/удалять/изменять преобразования дешево, без необходимости потомки с фиксированной позицией для повторной укладки.
Обратите внимание, что использование других значений изменения воли (например, opacity, top) будет не изменяйте положение потомков фиксированной позиции.
Насколько мне известно, единственное решение состоит в том, чтобы сделать дочерний элемент из элемента will-change
родным, а не для каскадирования атрибута.
В качестве побочного примечания, в моем конкретном случае, я смог исправить его, уточнив атрибут will-change
. Вместо того, чтобы использовать его в div
, содержащем элемент jarring, который требовал разгрузки GPU, я использовал его непосредственно на оскорбительном элементе. Это произошло из-за моего исходного кода, но в большинстве случаев он не будет работать.
Ответ 3
Вам нужно разместить header
вне родительского контейнера drop
, чтобы он работал.
У меня были несколько похожие проблемы дней назад. Например, если вы установите z-индекс header
, он будет достигнут z-index родительского контейнера drop
. Z-индекс header
будет быть бесполезным, потому что он уже находится внутри контейнера с другим z-индексом.
Та же логика z-индекса применяется к позиции.
Ответ 4
Я хочу добавить еще одно возможное решение, потому что я боролся с хромированием игнорирования позиции: исправлено довольно долго, пока я, наконец, не нашел виновника:
-webkit-perspective: 1000;
Это происходило из плагина, который я использовал, и вызывает ВСЕ положение: фиксированные элементы игнорируются.
Надеюсь, это поможет кому-то.
Ответ 5
Прежде всего, поместите что-то в свой div
, поскольку пустые ведут себя действительно странно. Затем, что вы ожидаете, поставив fixed
в absolute
? Очевидно, никто не знает, что является точкой отсчета вашего div fixed
. Должна ли быть его родительская позиция? который не меняется с помощью прокрутки или позиции страницы, которая изменяется? Попытайтесь использовать вещи, которые являются полностью значимыми и имеют четкое определение, потому что, если вы исправите его в хроме, что произойдет с другим браузером? Вы действительно предпочитаете тестировать на всех из них?
Я предполагаю небольшое изменение в div
, чтобы вытащить fixed
div из absolute
или переместить div absolute
где-то еще.