Фиксированное положение, но относительно контейнера

Я пытаюсь исправить div, чтобы он всегда оставался в верхней части экрана, используя:

position: fixed;
top: 0px;
right: 0px;

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

Я знаю, что position:absolute можно использовать для исправления элемента относительно div, но когда вы прокручиваете страницу вниз, этот элемент исчезает и не закрепляется наверху, как в случае с position:fixed.

Есть ли способ или обходной путь для этого?


person Zach Nicodemous    schedule 22.07.2011    source источник
comment
Tether - это библиотека пользовательского интерфейса низкого уровня, которую можно использовать для размещения любого элемента на странице рядом с любым другим элементом. github.com/shipshapecode/tether + демонстрации / документы на tether.io   -  person Avatar    schedule 16.10.2019


Ответы (25)


Краткий ответ: нет (теперь это возможно с помощью преобразования CSS. См. Правку ниже)

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

#fixedContainer {
  position: fixed;
  width: 600px;
  height: 200px;
  left: 50%;
  top: 0%;
  margin-left: -300px; /*half the width*/
}

http://jsfiddle.net/HFjU6/1/

Изменить (03/2015):

Это устаревшая информация. Теперь можно центрировать контент динамического размера (по горизонтали и вертикали) с помощью магии преобразования CSS3. Применяется тот же принцип, но вместо использования поля для смещения вашего контейнера вы можете использовать translateX(-50%). Это не работает с указанным выше трюком с полями, потому что вы не знаете, насколько его смещать, если ширина не фиксирована, и вы не можете использовать относительные значения (например, 50%), потому что они будут относиться к родительскому, а не к элементу это применяется к. transform ведет себя иначе. Его значения относятся к элементу, к которому они применяются. Таким образом, 50% для transform означает половину ширины элемента, а 50% для поля - половину ширины родительского элемента. Это решение IE9 +

Используя код, аналогичный приведенному выше, я воссоздал тот же сценарий, используя полностью динамическую ширину и высоту:

.fixedContainer {
    background-color:#ddd;
    position: fixed;
    padding: 2em;
    left: 50%;
    top: 0%;
    transform: translateX(-50%);
}

Если вы хотите, чтобы он был по центру, вы тоже можете это сделать:

.fixedContainer {
    background-color:#ddd;
    position: fixed;
    padding: 2em;
    left: 50%;
    top: 50%;
    transform: translate(-50%, -50%);
}

Демо:

jsFiddle: только по центру по горизонтали
jsFiddle: центрировано как по горизонтали, так и по вертикали
Первоначальный кредит принадлежит пользователю aaronk6 за то, что указал мне на это в этом ответе

person Joseph Marikle    schedule 22.07.2011
comment
У меня прекрасно сработало. Хотя мне нужен был мой слева от и уже центрированный, нефиксированный div, поэтому просто пришлось уменьшить левое поле, пока оно не будет выровнено. Никаких остатков выровненных, независимо от ширины окон. Спасибо. +1 - person Iain M Norman; 02.02.2012
comment
@Joseph есть идеи, почему position:fixed без указания top или left иногда работает? Некоторые браузеры, по-видимому, по умолчанию устанавливают элемент в том месте, где он обычно находился бы, если бы у него было нормальное расположение. stackoverflow.com/questions/8712047/ - person Flash; 30.08.2012
comment
как насчет без фиксированной высоты и ширины? В моем случае я не указал ширину сигнала ни одному контейнеру, даже до тега body. Какое решение вы мне скажете. - person mfq; 21.02.2013
comment
@mfq К сожалению, этот метод вообще не будет работать без известной высоты и ширины. То, что вы выберете, во многом будет зависеть от того, что вы пытаетесь сосредоточить. Если это изображение, просто используйте его как фон для контейнера 100% x 100%. Если это реальный полностью динамический элемент, вам, вероятно, придется изучить его с помощью решения javascript, чтобы получить размеры. - person Joseph Marikle; 21.02.2013
comment
@JosephMarikle Я думаю, вам стоит попробовать мой ответ ниже и, возможно, обновить короткий ответ, потому что этот небольшой хак отлично работает для webkit, и во многих случаях это все, что нужно. - person Francesco Frapporti; 11.12.2013
comment
@FrancescoFrapporti Это хороший CSS-хакер, но я думаю, что оставлю свой ответ как есть по нескольким причинам. Во-первых, преобразование не является стандартом w3c (только черновик) и, следовательно, может быть изменено. Поскольку поведение не определено и это (насколько я понимаю) побочный эффект предполагаемого стиля, в какой-то момент это может сломаться. Вторая причина в том, что это решение только для webkit. Спасибо, что добавили свой ответ. Множественность решений - вот что делает такие вопросы такими полезными для будущих разработчиков, пытающихся найти решение своих текущих ошибок и проблем разработки. - person Joseph Marikle; 12.12.2013
comment
Я обнаружил, что добавление left:inherit к элементу с фиксированной позицией может заставить браузер уважать смещение родителя. - person Willster; 24.12.2014
comment
@Willster очаровательный! Очень бы хотелось увидеть рабочий пример. У вас есть скрипка, демонстрирующая этот метод? - person Joseph Marikle; 24.12.2014
comment
У меня все еще проблема с уменьшением ширины, когда я задаю элементу position: fixed ;. Без жесткой ширины 1140 пикселей; (что работает, но если размер экрана изменен, ширина слишком велика), как я могу вернуть исходную ширину (1140 пикселей) моему фиксированному элементу и по-прежнему сохранять отзывчивую ширину? - person Kyle Vassella; 19.01.2018

На самом деле это возможно, и принятый ответ касается только централизации, что достаточно просто. Также вам действительно не нужно использовать JavaScript.

Это позволит вам справиться с любым сценарием:

Настройте все, как если бы вы хотели position: absolute внутри контейнера position: relative, а затем создать новый div с фиксированной позицией внутри div с помощью position: absolute, но не устанавливайте его свойства top и left. . Затем он будет зафиксирован в любом месте относительно контейнера.

Например:

/* Main site body */
.wrapper {
    width: 940px;
    margin: 0 auto;
    position: relative; /* Ensure absolute positioned child elements are relative to this*/
}

/* Absolute positioned wrapper for the element you want to fix position */
.fixed-wrapper {
    width: 220px;
    position: absolute;
    top: 0;
    left: -240px; /* Move this out to the left of the site body, leaving a 20px gutter */
}

/* The element you want to fix the position of */
.fixed {
    width: 220px;
    position: fixed;
    /* Do not set top / left! */
}
<div class="wrapper">
    <div class="fixed-wrapper">
        <div class="fixed">
            Content in here will be fixed position, but 240px to the left of the site body.
        </div>
    </div>
</div>

К сожалению, я надеялся, что эта ветка может решить мою проблему с WebKit Android, отображающим пиксели размытия прямоугольной тени как поля на элементах с фиксированным положением, но похоже, что это ошибка.
В любом случае, я надеюсь, что это поможет!

person Graeme Blackwood    schedule 06.08.2012
comment
Не совсем ЛЮБОЙ сценарий, но это хорошее начало. Если под .wrapper много места, тогда ваш .fixed-wrapper будет заканчиваться внизу родительского элемента, но ваш .fixed элемент будет продолжать вытекать из обоих контейнеров в любое содержимое ниже. Как я уже сказал, это хорошее начало, не идеальное, но я не понимаю, как этого можно достичь без некоторых js. - person o_O; 11.07.2013
comment
Однако это не очень хорошо сочетается с плавным дизайном. - person Zuhaib Ali; 28.01.2014
comment
Я пытался сделать это, но когда я прокручиваю вниз, заголовок, который я применил, фиксированный (с родительским абсолютным, относительно которого родитель был относительным), не перемещался при прокрутке. - person Mirage; 26.03.2014
comment
Это сработало для меня с верхним правым div в Chromium и Firefox, за исключением того, что вертикальное положение фиксированного div было другим (в Chromium он был поверх родительского div, в Firefox он был внутри). - person Damien; 15.10.2014
comment
Случайно я обернул <div> на position:absolute внутри <div> на position:fixed, и это отлично работает, даже при изменении размера окна и т. Д., По крайней мере, в Chrome и IE. Итак, это: ‹div style = position: relative› ‹div style = position: fixed› ‹div style = position: absolute; top: 0px;› ‹/div› ‹/div› ‹/div› - person Philip Stratford; 16.07.2015
comment
Но, задав все эти жесткие значения ширины, не теряем ли мы отзывчивость? Есть ли способ реализовать div с фиксированной шириной реагирования? Использование процентов не сработало для меня, поскольку width: 100% означает 100% ширины области просмотра, а не ширину моего контейнера начальной загрузки, дочерним элементом которого является мой фиксированный элемент. - person Kyle Vassella; 19.01.2018
comment
Это был ответ для меня! Спасибо @Graeme Blackwood - person Tabu.Net; 14.02.2018
comment
Как это работает согласно w3c An element with position: fixed; is positioned relative to the viewport? Просвети меня, пожалуйста. - person timebandit; 13.07.2018
comment
Не понимаю, какой здесь смысл position:fixed. Только position: absolute необходимо, чтобы добиться того же. - person Shawn; 23.07.2018
comment
@timebandit это все еще относительно области просмотра. Просто без указания top и left он позиционируется на основе позиции родителя по умолчанию. - person Shawn; 23.07.2018

Да, по спецификации способ есть.

Хотя я согласен с тем, что ответ Грэма Блэквуда должен быть приемлемым, поскольку он практически решает проблему, следует отметить, что фиксированный элемент можно расположить относительно своего контейнера.

Заметил случайно, что при нанесении

-webkit-transform: translateZ(0);

к телу он сделал фиксированный дочерний элемент относительно него (вместо области просмотра). Итак, мои свойства фиксированных элементов left и top теперь относились к контейнеру.

Итак, я провел небольшое исследование и обнаружил, что проблема уже была рассмотрена Eric Meyer, и даже если это было похоже на" уловку ", оказалось, что это часть спецификаций:

Для элементов, макет которых управляется блочной моделью CSS, любое значение преобразования, кроме none, приводит к созданию как контекста стека, так и содержащего блока. Объект действует как содержащий блок для фиксированных потомков.

http://www.w3.org/TR/css3-transforms/

Итак, если вы примените какое-либо преобразование к родительскому элементу, он станет содержащим блоком.

Но...

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

Такое же поведение будет обнаружено в Safari, Chrome и Firefox, но не в IE11 (где фиксированный элемент по-прежнему останется фиксированным).

Другая интересная (недокументированная) вещь заключается в том, что когда фиксированный элемент содержится внутри преобразованного элемента, тогда как его свойства top и left теперь будут связаны с контейнером, соблюдая свойство box-sizing, его контекст прокрутки будет распространяться за границу элемента, как если бы размер коробки был установлен на border-box. Для некоторых творческих людей это могло бы стать игрушкой :)

ТЕСТ

person Francesco Frapporti    schedule 08.04.2013
comment
Это позволило мне создать таблицу с фиксированными заголовками внутри контейнера - person Zach Saucier; 12.12.2013
comment
Хорошо, у меня это работает в Chrome. Любые идеи о том, как добиться того же в IE? Я пробовал использовать translateZ, но этого не произошло ни в одной версии IE. - person Anish Patel; 17.04.2014
comment
То же самое .. кто-нибудь знает, как это сделать в IE? это своего рода боль, чтобы обнаружить браузер, а затем систематически показывать или не показывать left: (учитывая, что это портит) - person Tallboy; 03.06.2014
comment
Я просто встречаю противоположное условие, которое мне нужно исправить в относительном контейнере, но изменить с помощью свойства transform. Ваш ответ очень полезен, спасибо! - person mytharcher; 28.09.2014
comment
@Francesco Frapporti кажется, что это больше не работает ... в любом случае в последней версии Chrome (версия 42.0.2311.90) :( - person jjenzz; 28.04.2015
comment
Идеально подходит, спасибо! Для всех, кому интересно: работает для Chrome 84.0.4147.89 и Firefox 78.0.2 и Edge 44.18362.449.0 - person thiout_p; 29.07.2020
comment
Вы также можете добиться этого, применив will-change - person nullhook; 07.10.2020
comment
FF 81 позволяет заголовку прокручиваться вверх и исчезать, но прилипание работает нормально. - person G-Cyrillus; 09.10.2020

Ответ - да, если вы не установили left: 0 или right: 0 после того, как вы установили позицию div на fixed.

http://jsfiddle.net/T2PL5/85/

Оформить заказ на боковой панели div. Он фиксирован, но связан с родительским элементом, а не с точкой обзора окна.

body {
  background: #ccc;
}

.wrapper {
  margin: 0 auto;
  height: 1400px;
  width: 650px;
  background: green;
}

.sidebar {
  background-color: #ddd;
  float: left;
  width: 300px;
  height: 100px;
  position: fixed;
}

.main {
  float: right;
  background-color: yellow;
  width: 300px;
  height: 1400px;
}
<div class="wrapper">wrapper
  <div class="sidebar">sidebar</div>
  <div class="main">main</div>
</div>

person Shadow_boi    schedule 21.03.2013
comment
Есть ли причина, по которой это не получает больше голосов? Для меня это наиболее очевидное решение. - person html_programmer; 27.08.2014
comment
Насчет кроссбраузерной совместимости. Кто-нибудь из вас это проверял? - person Alexandre Bourlier; 17.06.2015
comment
Это правильно, но только для «позиционирования» фиксированного элемента. Он никоим образом не учитывает ширину контейнера или его размер. Например, если у вас есть жидкая оболочка с max-width: 1000px; маржа: авто; так не пойдет. Если все может быть фиксированной ширины, то да, это решит вашу проблему. - person Rhys; 18.05.2016
comment
@AlexandreBourlier Да, у меня это хорошо сработало для фиксированного элемента, по крайней мере, в Chrome, Firefox и IE11. - person Jason Frank; 11.08.2016
comment
Сработало отлично. Пришлось добавить margin-left: X%, чтобы переместить элемент справа от контейнера. - person Anand; 01.02.2017
comment
Совершенно неверно. Боковая панель располагается в точке обзора окна, а не в родительской точке обзора. Попробуйте это с оберткой меньшего размера по высоте. jsfiddle.net/xf0jygcz - person fat_mike; 14.04.2019
comment
Я бы добавил к этому - если вы не уверены, установлены ли left / top, используйте style = left: unset; right: unset; top: unset; bottom: unset; - person TerrorBight; 05.03.2020
comment
Это действительно сработало и для меня! Поскольку то, с чем я работаю, привязано к дальнему правому краю обертки страницы, я просто добавил transform: translateX(-300px); (ширина элемента, который мне нужно было зафиксировать), чтобы получить его там, где мне нужно. Я действительно удивлен, что это работает, но счастлив, что нашел это! - person tklives; 26.06.2020

position: sticky, это новый способ позиционирования элементов, концептуально похожий на position: fixed. Разница в том, что элемент с position: sticky ведет себя как position: relative внутри своего родителя, пока заданный порог смещения не будет достигнут в области просмотра.

В Chrome 56 (в настоящее время бета-версия по состоянию на декабрь 2016 года, стабильная в январе 2017 года) позиция: липкий теперь вернулся.

https://developers.google.com/web/updates/2016/12/position-sticky

Подробнее см. Прикрепите посадки! позиция: липкие земли в WebKit.

person PoseLab    schedule 19.04.2013
comment
Это значительно упрощает жизнь, единственная проблема заключается в том, что липкость не поддерживается в Internet Explorer, Edge 15 и более ранних версиях. - person ricks; 06.09.2018
comment
position:sticky отлично. Поддерживается всеми браузерами, кроме IE. caniuse.com/#feat=css-sticky - person Yarin; 10.10.2018
comment
lol, так старый api, и ты спасешь меня ... я использую его для фиксированных столбцов для гибких таблиц. - person Vladislav Gritsenko; 30.04.2019
comment
внутри своего родителя - можно ли остаться липким элементом вверху, если родительский элемент, прокрученный вверх, стал невидимым? - person Fikret; 24.05.2019

РЕШЕНИЕ 2019: вы можете использовать свойство position: sticky.

Вот пример CODEPEN, демонстрирующий использование, а также его отличия от position: fixed.

Как он себя ведет, объясняется ниже:

  1. Элемент с закрепленной позицией позиционируется в зависимости от положения прокрутки пользователя. Он в основном действует как position: relative, пока элемент не будет прокручен за пределы определенного смещения, и в этом случае он превратится в position: fixed. Когда он прокручивается назад, он возвращается в свое предыдущее (относительное) положение.

  2. Он влияет на поток других элементов на странице, т.е. занимает определенное место на странице (как position: relative).

  3. Если он определен внутри некоторого контейнера, он позиционируется относительно этого контейнера. Если у контейнера есть переполнение (прокрутка), в зависимости от смещения прокрутки он превращается в position: fixed.

Поэтому, если вы хотите достичь фиксированной функциональности, но внутри контейнера, используйте липкий.

person Pransh Tiwari    schedule 20.01.2018
comment
Хорошее решение. Я еще не знал о position: sticky. Очень помогло, спасибо! - person dave0688; 08.08.2019
comment
Я как раз собирался опубликовать это. Хороший ответ! липкий путь. - person dkellner; 16.04.2020
comment
Если вы увеличиваете размер окна вывода в Codepen, фиксированный элемент не фиксируется, а перемещается вверх. Нехорошо. Лучшее решение удерживает его привязанным к нижней части области просмотра. - person AndroidDev; 10.06.2020
comment
@AndroidDev Только верхний элемент определен как фиксированный для всей страницы. Он визуализируется по желанию. Остальные элементы являются пояснительными примерами для разных случаев. - person Pransh Tiwari; 10.06.2020
comment
Важно помнить, что position: sticky не будет работать, если какой-либо из родительских элементов использует свойство overflow: hidden. - person AndreVitorio; 28.03.2021

Просто удалите верхний и левый стили из div с фиксированной позицией. Вот пример

<div id='body' style='height:200%; position: absolute; width: 100%; '>
    <div id='parent' style='display: block; margin: 0px auto; width: 200px;'>
        <div id='content' style='position: fixed;'>content</div>
    </div>
</div> 

Div #content будет размещаться там, где находится родительский div, но будет там фиксироваться.

person hobberwickey    schedule 28.03.2012
comment
Почему минус? Это идеально подходит для фиксации элемента в любом месте в потоке DOM. deadlykitten.com/tests/fixedPositionTest.php - person hobberwickey; 28.03.2012

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

Вот ссылка на этот плагин jQuery, который может решить эту проблему:

https://github.com/bigspotteddog/ScrollToFixed

Описание этого плагина следующее:

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

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

Этот плагин был протестирован в Firefox 3/4, Google Chrome 10/11, Safari 5 и Internet Explorer 8/9.

Использование для вашего конкретного случая:

<script src="scripts/jquery-1.4.2.min.js" type="text/javascript"></script>
<script src="scripts/jquery-scrolltofixed-min.js" type="text/javascript"></script>

$(document).ready(function() {
    $('#mydiv').scrollToFixed();
});
person bigspotteddog    schedule 29.08.2011

Мне пришлось сделать это с рекламой, которую мой клиент хотел разместить за пределами области контента. Я просто сделал следующее, и это сработало отлично!

<div id="content" style="position:relative; width:750px; margin:0 auto;">
  <div id="leftOutsideAd" style="position:absolute; top:0; left:-150px;">
    <a href="#" style="position:fixed;"><img src="###" /></a>
  </div>
</div>
person Eric K    schedule 30.04.2012
comment
Мое объявление было 140 пикселей в ширину, поэтому я переместил его на 150 пикселей влево, чтобы придать ему небольшое правое поле по отношению к краю фрейма веб-сайта. - person Eric K; 30.04.2012

Два элемента HTML и чистый CSS (современные браузеры)

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

Как здесь многие заявили, один ключ не устанавливает никаких позиционных настроек для элемента fixed (без значений top, right, bottom или left).

Скорее, мы помещаем все фиксированные элементы (обратите внимание, как в последнем блоке их четыре) первыми в блок, от которого они должны быть расположены, например:

<div class="reference">
  <div class="fixed">Test</div>
  Some other content in.
</div>

Затем мы используем margin-top и margin-left, чтобы переместить их по отношению к их контейнеру, примерно так, как это делает этот CSS:

.fixed {
    position: fixed;
    margin-top: 200px; /* Push/pull it up/down */
    margin-left: 200px; /* Push/pull it right/left */
}

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

Является ли оболочка статической, relative или абсолютный в позиционировании, не имеет значения.

person ScottS    schedule 12.12.2013

Вы можете попробовать мой плагин jQuery, FixTo.

Использование:

$('#mydiv').fixTo('#centeredContainer');
person Burak    schedule 10.08.2012

Да, это возможно, если вы не устанавливаете позицию (top или left и т. Д.) Вашего fixed элемента (хотя вы все равно можете использовать margin для установки относительной позиции). Саймон Бос некоторое время писал об этом назад.

Однако не ожидайте, что фиксированный элемент будет прокручиваться с нефиксированными родственниками.

См. демонстрацию здесь.

person Javarome    schedule 28.02.2020

Заявление об ограничении ответственности:

Это отвечает только на заголовок: Фиксированное положение, но относительно контейнера. Для фактического варианта использования, который пользователь запрашивает, position: sticky - это путь.


https://developer.mozilla.org/en-US/docs/Web/CSS/position

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

Вам просто нужно добавить преобразование в контейнер, и положение фиксированного элемента будет относительно контейнера. Я думаю, что transform: translateX(0); должно быть достаточно.

person pykiss    schedule 01.11.2020

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

person Beto Aveiga    schedule 24.07.2012

С чистым CSS этого сделать не удастся; по крайней мере, нет. Однако вы можете сделать это с помощью jQuery очень просто. Я объясню свою проблему, и с небольшими изменениями вы сможете ее использовать.

Итак, для начала я хотел, чтобы мой элемент имел фиксированную верхнюю часть (сверху окна) и левый компонент, унаследованный от родительского элемента (поскольку родительский элемент центрирован). Чтобы установить левый компонент, просто поместите свой элемент в родительский и установите position:relative для родительского элемента.

Затем вам нужно знать, насколько далеко от верхнего края находится ваш элемент, когда полоса прокрутки находится сверху (y ноль прокручивается); снова есть два варианта. Во-первых, это статическое значение (какое-то число) или его нужно прочитать из родительского элемента.

В моем случае это 150 пикселей от верхней статики. Итак, когда вы видите 150, это то, сколько стоит элемент сверху, когда мы не прокручивались.

CSS

#parent-element{position:relative;}
#promo{position:absolute;}

jQuery

$(document).ready(function() { //This check window scroll bar location on start
    wtop=parseInt($(window).scrollTop());
    $("#promo").css('top',150+wtop+'px');

});
$(window).scroll(function () { //This is when the window is scrolling
    wtop=parseInt($(window).scrollTop());
    $("#promo").css('top',150+wtop+'px');
});
person Mr Br    schedule 23.05.2013
comment
Проблема в том, что рассматриваемый div мерцает при прокрутке. - person vvohra87; 29.07.2013
comment
Вероятно, потому что прокрутка обновляется слишком часто или слишком быстро. У меня не было этой проблемы, но я могу предложить вам попробовать использовать глобальный блокировщик, который будет обновляться, например, каждые 10 мс или какое-то время, и устанавливать значение блокировки каждый раз, когда вы делаете какое-то изменение высоты. Конечно, вам нужно добавить условие if к событию .scroll, которое проверяет, прокручивали ли вы уже в этот период (10 мс) div. Повторяю, я не пробовал, но верю, что это может сработать :) Таким образом, вы могли бы помешать div слишком сильно менять свое положение, чтобы компьютер не мог на самом деле следовать, и достаточно, чтобы человеческий глаз видел это. - person Mr Br; 30.07.2013
comment
Я уже дал ваш ответ +1 товарищ;) Беда с подключением метода глобального цикла - это действительно производительность. Добиться того, чтобы что-то подобное нормально работало на старых компьютерах и планшетах, было болезненным. Много раз младший разработчик на работе писал 'var x' внутри такого метода, что приводило к ненужным утечкам памяти, если страница оставалась открытой слишком долго: P Но да, ваше предложение кажется единственным реальным вариант. - person vvohra87; 31.07.2013
comment
У вас есть смысл с глобальными циклами; нехорошо, согласен. Мне просто нравится думать о такого рода проблемах, поэтому я написал другое предложение :) Tbh, теперь это выглядит немного лучше, я бы избегал этого xD Теперь у меня есть другое решение. Что вы говорите о настройке setTimeout () для события прокрутки, которое вызывает func. это делает движение div .. также вы используете глобальный блокировщик, который установлен в true во время ожидания тайм-аута, и когда тайм-аут вызывается, вы возвращаете блокировщик в false, который через некоторое время разрешает другой вызов ... в этом случае вы бы не использовали глобальный цикл но по-прежнему можете контролировать частоту движения div. - person Mr Br; 01.08.2013
comment
Это более элегантно, но мне трудно принять. Я ожидаю, что спецификации html и css будут обрабатывать tbh именно так. Ненавижу тот факт, что в первую очередь задействован js! - person vvohra87; 01.08.2013

У меня такая же проблема, один из членов нашей команды предлагает мне решение. Чтобы разрешить фиксированное положение div относительно другого div, наше решение состоит в том, чтобы использовать родительский контейнер, оборачивая фиксированный div и прокручивая div.

<div class="container">
  <div class="scroll"></div>
  <div class="fix"></div>
</div>

css

.container {
  position: relative;
  flex:1;
  display:flex;
}

.fix {
  prosition:absolute;
}
person Jay0Lu    schedule 21.02.2017

Это просто (согласно HTML ниже)

Уловка состоит в том, чтобы НЕ использовать верхнюю или левую часть элемента (div) с "position: fixed;". Если они не указаны, элемент «фиксированного содержимого» будет отображаться ОТНОСИТЕЛЬНО к включающему элементу (div с «position: relative;») ВМЕСТО относительно окна браузера !!!

<div id="divTermsOfUse" style="width:870px; z-index: 20; overflow:auto;">
    <div id="divCloser" style="position:relative; left: 852px;">
        <div style="position:fixed; z-index:22;">
            <a href="javascript:hideDiv('divTermsOfUse');">
                <span style="font-size:18pt; font-weight:bold;">X</span>
            </a>
        </div>
    </div>
    <div>  <!-- container for... -->
         lots of Text To Be Scrolled vertically...
         bhah! blah! blah!
    </div>
</div>

Это позволило мне найти закрывающую кнопку «X» в верхней части большого количества текста в div с вертикальной прокруткой. "X" находится на месте (не перемещается с прокручиваемым текстом, но все же перемещается влево или вправо вместе с охватывающим контейнером div, когда пользователь изменяет ширину окна браузера! Таким образом, он "фиксируется" по вертикали, но позиционируется относительно ограждающий элемент по горизонтали!

До того, как я получил эту работу, «X» прокручивалась вверх и скрывалась из поля зрения, когда я прокручивал текстовое содержимое вниз.

Приносим извинения за то, что не предоставили мою функцию hideDiv () в javascript, но это без нужды сделало бы этот пост длиннее. Я решил сделать его как можно короче.

person Bruce Allen    schedule 11.02.2014
comment
Надежное кросс-браузерное решение, прекрасно работает в IE8. - person dmi3y; 20.05.2015

Я создал jsfiddle, чтобы продемонстрировать, как это работает с помощью преобразования.

HTML

<div class="left">
    Content
</div>
<div class="right">
<div class="fixedContainer">
    X
</div>
    Side bar
</div>

CSS

body {
  margin: 0;
}
.left {
  width: 77%;
  background: teal;
  height: 2000px;
}
.right {
  width: 23%;
  background: yellow;
  height: 100vh;
  position: fixed;
  right: 0;
  top: 0;
}
.fixedContainer {
    background-color:#ddd;
    position: fixed;
    padding: 2em;
    //right: 0;
    top: 0%;
    transform: translateX(-100px);
}

jQuery

$('.fixedContainer').on('click', function() {
    $('.right').animate({'width': '0px'});
  $('.left').animate({'width': '100%'});
});

https://jsfiddle.net/bx6ktwnn/1/

person Wen    schedule 09.08.2016

Когда вы используете position:fixed правило CSS и пытаетесь применить _2 _ / _ 3 _ / _ 4 _ / _ 5_, он позиционирует элемент относительно окна.

Обходной путь - использовать свойства margin вместо _7 _ / _ 8 _ / _ 9 _ / _ 10_

person Sunil Garg    schedule 17.03.2020

Некоторое время назад я делал что-то подобное. Я был новичком в JavaScript, поэтому уверен, что у вас получится лучше, но вот отправная точка:

function fixxedtext() {
    if (navigator.appName.indexOf("Microsoft") != -1) {
        if (document.body.offsetWidth > 960) {
            var width = document.body.offsetWidth - 960;
            width = width / 2;
            document.getElementById("side").style.marginRight = width + "px";
        }
        if (document.body.offsetWidth < 960) {
            var width = 960 - document.body.offsetWidth;
            document.getElementById("side").style.marginRight = "-" + width + "px";
        }
    }
    else {
        if (window.innerWidth > 960) {
            var width = window.innerWidth - 960;
            width = width / 2;
            document.getElementById("side").style.marginRight = width + "px";
        }
        if (window.innerWidth < 960) {
            var width = 960 - window.innerWidth;
            document.getElementById("side").style.marginRight = "-" + width + "px";
        }
    }
    window.setTimeout("fixxedtext()", 2500)
}

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

person webLacky3rdClass    schedule 22.07.2011
comment
одна проблема, которую я вижу в этом подходе, заключается в том, что он полагается на таймер (2,5 секунды), и в течение этого времени, если пользователь изменяет размер окна, ему потребуется некоторое время, чтобы оно исправилось. Это не самое лучшее, что касается пользовательского опыта. Кроме того, если это может помочь, попробуйте использовать прослушиватели событий вместо таймеров. - person Joseph Marikle; 22.07.2011
comment
Как я уже сказал, это СТАРЫЙ сценарий, один из моих первых, и мне не нужно было возвращаться, чтобы исправить его. Так что это не лучший вариант, но может стать хорошей отправной точкой. - person webLacky3rdClass; 23.07.2011

Это возможно, если вы используете JavaScript. В этом случае подключаемый модуль jQuery Sticky-Kit:

person Paz Aricha    schedule 13.08.2015

Мой проект - это шаблон .NET ASP Core 2 MVC Angular 4 с Bootstrap 4. Добавление «липкой вершины» в основной компонент html приложения (т.е. app.component.html) в первой строке работало следующим образом:

<div class='row sticky-top'>
    <div class='col-sm-12'>
        <nav-menu-top></nav-menu-top>
    </div>
</div>
<div class="row">
    <div class='col-sm-3'>
        <nav-menu></nav-menu>
    </div>
    <div class='col-sm-9 body-content'>
        <router-outlet></router-outlet>
    </div>
</div>

Это соглашение или я слишком упрощал это?

person Adam Cox    schedule 02.11.2017

Магия состоит в том, чтобы взять ширину экрана за вычетом ширины контейнера и разделить ее на 2:

//1400px is according to container max-width (left can be also right)
.fixed {
  position: fixed;
  right: calc((100vw - 1400px)/2);
}

Примечание: функция css calc () поддерживается почти, но не на 100%. Для большинства случаев использования он определенно поддерживается. Щелкните здесь для получения дополнительных сведений.

Фрагмент (с контейнером 300 пикселей, чтобы он соответствовал виджету этого веб-сайта):

.container {
  max-width: 300px;
  margin-left: auto;
  margin-right: auto;
}


.fixed {
  position: fixed;
  right: calc((100vw - 300px)/2);
}


@media screen and (max-width: 300px) {
  right: 0px;
}
<div style="height: 3000px">
    <div class="container">
        <button class="fixed">
            FIXED CONTENT
        </button>
    Lorem ipsum dolor sit amet consectetur adipisicing elit. Laborum, eum? Animi quidem accusamus minima vel, dolorem suscipit quia accusantium minus harum modi commodi distinctio! Iste voluptatum earum quam voluptate culpa ad, ipsum dolorum recusandae quis atque eligendi necessitatibus magnam nisi dolores beatae qui? Perspiciatis natus cum nostrum in quod odio sapiente doloremque rerum quo dolore tenetur facere, quisquam atque accusamus fugiat eligendi, deleniti nisi minus recusandae distinctio dignissimos! Dicta quos ipsum qui pariatur at vel veritatis veniam quisquam minus modi et voluptas aliquam laborum, cumque in quo magnam sapiente. Expedita ut dolore laboriosam tempora reprehenderit vero eaque blanditiis, cumque voluptatibus, velit nemo, veniam tenetur quisquam numquam adipisci quae odio repellendus neque incidunt! Cum odio corporis soluta voluptate nesciunt, quasi nobis deleniti neque porro expedita fugiat placeat alias autem pariatur animi error, dicta veritatis atque perspiciatis inventore tempora dolor ad! Mollitia in dolorem ipsam eos porro magni perspiciatis possimus maiores, itaque facere ut. Eos culpa eum error quia incidunt repellendus quam possimus, asperiores earum ipsum molestias dicta sint fugit atque veniam dolorum illo? Officia harum sint incidunt totam, reiciendis illum eos maxime sequi neque repellat quis, expedita eum, corporis quaerat nemo qui soluta aspernatur animi. Sint ad rem numquam omnis sit.
    </div>
 </div>

person Nadav    schedule 20.09.2020

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

<div class='parent'>
  <div class='child'></div>
<div>
.parent {
  contain: content;
}

.child {
  position: fixed;
  top: 0;
  left: 0;
}
person holmberd    schedule 31.05.2021

Проверь это:

<html xmlns="http://www.w3.org/1999/xhtml">
    <head>
        <title></title>
    </head>
    <body style="width: 1000px !important;margin-left: auto;margin-right: auto">
        <div style="width: 100px; height: 100px; background-color: #ccc; position:fixed;">
        </div>
        <div id="1" style="width: 100%; height: 600px; background-color: #800000">
        </div>
        <div id="2" style="width: 100%; height: 600px; background-color: #100000">
        </div>
        <div id="3" style="width: 100%; height: 600px; background-color: #400000">
        </div>
    </body>
</html>
person Kunal    schedule 11.04.2012
comment
Я не думаю, что это соответствует тому, о чем спрашивал ОП. - person JasonWyatt; 26.10.2012