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

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

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

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

есть ли Хак или обходной путь для достижения этого?

21 ответов


короткий ответ: нет. (теперь это возможно с преобразованием CSS. См. редактирование ниже)

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

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

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

Edit (03/2015):

это устаревшая информация. Теперь можно центрировать содержимое динамического размера (по горизонтали и вертикали) с помощью магии преобразования CSS3. Тот же принцип применяется, но вместо использования поля для смещения контейнера вы можете использовать translateX(-50%). Это не работает с вышеуказанным трюком маржи, потому что вы не знаете, сколько его компенсировать если ширина не фиксирована, и вы не можете использовать относительные значения (например,50%) потому что он будет относительно родителя, а не элемента, к которому он применяется. transform ведет себя по-разному. Его значения относятся к элементу, к которому они применяются. Таким образом, 50% на transform означает половину ширины элемента, в то время как 50% for margin-половина ширины родителя. Это 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 для указывая мне в ответ


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

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

настройте все, как вы хотели бы, если вы хотите позиционировать: Абсолют внутри позиции: относительный контейнер, а затем создайте новое фиксированное положение div внутри div с position: absolute, а не не установите его верхние и левые свойства. Тогда будет зафиксировано везде, где вы хотите его, по отношению к контейнеру.

например:

/* 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>

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


Да, согласно спецификациям, есть способ.

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

я случайно заметил, что при подаче заявки

-webkit-transform: translateZ(0);

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

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

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

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

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

но...

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

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

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

тест


ответ-да, пока вы не установите left: 0 или right: 0 после того, как вы установите положение дел исправлено.

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>

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

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

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

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


Я создал этот плагин 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();
});

просто возьмите верхний и левый стили из фиксированной позиции 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> 

# content div будет сидеть там, где сидит Родительский div, но будет исправлен.


Я должен был сделать это с рекламой, которую мой клиент хотел сидеть вне области контента. Я просто сделал следующее, И это сработало как шарм!

<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>

два 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 элементы, и все еще есть все эти элементы, связанные с верхним левым углом. Но это верно только в том случае, если все они помещены первыми в контейнер,как это сравнение скрипка показывает, что если рассеивается внутри содержимого контейнера, позиционирование становится ненадежным.

является ли обертка static, относительные или абсолютное в позиционировании, это не важно.


можно использовать position: sticky собственность.

вот пример сайт CodePen демонстрация использования, а также чем он отличается от position: fixed.

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

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

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

  3. если он определен внутри некоторого контейнера, то он расположен по отношению к этому контейнеру. Если контейнер имеет некоторое переполнение (прокрутку), в зависимости от смещения прокрутки он переходит в положение:исправлено.

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


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

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

$('#mydiv').fixTo('#centeredContainer');

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


С чистым 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');
});

Это легко (согласно 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" прокрутился вверх и исчез из поля зрения, когда я прокрутил текстовое содержимое вниз.

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


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

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/


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

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

в CSS

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

.fix {
  prosition:absolute;
}

Я сделал что-то подобное некоторое время назад. Я довольно новыми для 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)
}

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


это возможно, если вы используете JavaScript. В этом случае плагин jQuery Липкая-Комплект:


мой проект-.NET ASP Core 2 MVC Angular 4 шаблон с загрузочным 4. Добавление "sticky-top" в основной компонент приложения html (т. е. приложение.деталь.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>

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


/* html */

/* this div exists purely for the purpose of positioning the fixed div it contains */
<div class="fix-my-fixed-div-to-its-parent-not-the-body">

     <div class="im-fixed-within-my-container-div-zone">
          my fixed content
     </div>

</div>



/* css */

/* wraps fixed div to get desired fixed outcome */
.fix-my-fixed-div-to-its-parent-not-the-body 
{
    float: right;
}

.im-fixed-within-my-container-div-zone
{
    position: fixed;
    transform: translate(-100%);
}

проверить это:

<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>