it-swarm.com.de

Feste Position, jedoch relativ zum Behälter

Ich versuche, eine div zu korrigieren, damit sie immer am oberen Rand des Bildschirms haftet.

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

Die Variable div befindet sich jedoch in einem zentrierten Container. Wenn ich position:fixed verwende, wird die div relativ zum Browserfenster festgelegt, z. B. gegenüber der rechten Seite des Browsers. Stattdessen sollte es relativ zum Container festgelegt werden.

Ich weiß, dass position:absolute verwendet werden kann, um ein Element relativ zur div zu fixieren, aber wenn Sie die Seite nach unten scrollen, verschwindet das Element und bleibt nicht wie bei position:fixed oben.

Gibt es einen Hack oder einen Workaround, um dies zu erreichen?

539
Zach Nicodemous

Kurze Antwort: nein. (Mit CSS-Transformation jetzt möglich

Lange Antwort: Das Problem bei der "festen" Positionierung besteht darin, dass das Element aus dem Fluss genommen wird. Daher kann es nicht relativ zum übergeordneten Element neu positioniert werden, da es so ist, als hätte es keinen. Wenn der Container jedoch eine feste, bekannte Breite hat, können Sie Folgendes verwenden:

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

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

Bearbeiten (03/2015):

Dies sind veraltete Informationen. Es ist jetzt möglich, den Inhalt einer dynamischen Größe (horizontal und vertikal) mithilfe der Magie der CSS3-Transformation zu zentrieren. Dasselbe Prinzip gilt, aber anstatt den Rand zum Versetzen des Containers zu verwenden, können Sie translateX(-50%) verwenden. Dies funktioniert nicht mit dem obigen Randtrick, da Sie nicht wissen, wie viel es versetzt werden soll, wenn die Breite nicht festgelegt ist und Sie keine relativen Werte (wie 50%) verwenden können, da dies relativ zum übergeordneten Element und nicht zum Element ist es gilt für. transform verhält sich anders. Seine Werte sind relativ zu dem Element, auf das sie angewendet werden. Daher bedeutet 50% für transform die Hälfte der Breite des Elements, während 50% für den Rand die Hälfte der Breite des übergeordneten Elements ist. Dies ist eine IE9 + -Lösung

Mit ähnlichem Code wie im obigen Beispiel habe ich dasselbe Szenario mit vollständig dynamischer Breite und Höhe erstellt:

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

Wenn Sie möchten, dass es zentriert wird, können Sie dies auch tun:

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

Demos:

jsFiddle: Nur horizontal zentriert
jsFiddle: Horizontal und vertikal zentriert
Der ursprüngliche Kredit geht an den Benutzer aaronk6 für den Hinweis darauf in diese Antwort

358
Joseph Marikle

Eigentlich ist dies möglich und die akzeptierte Antwort befasst sich nur mit der Zentralisierung, was unkompliziert ist. Sie müssen auch kein JavaScript verwenden.

So können Sie mit jedem Szenario umgehen:

Richten Sie alles so ein, als würden Sie positionieren: absolut innerhalb einer Position: relativer Container. Erstellen Sie dann eine neue feste Position div im div mit position: absolute, legen Sie jedoch mit not die Eigenschaften top und left fest. Sie wird dann an jedem beliebigen Ort relativ zum Container fixiert.

Zum Beispiel:

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

Leider hatte ich gehofft, dass dieser Thread mein Problem mit Android WebKit Rendering-Box-Schatten-Unschärfepixeln als Ränder für feste Positionselemente lösen könnte, aber es scheint ein Fehler zu sein.
Wie auch immer, ich hoffe das hilft!

157

Ja, den Spezifikationen zufolge gibt es einen Weg.

Obwohl ich damit einverstanden bin, dass Graeme Blackwoods die akzeptierte Antwort sein sollte, da das Problem praktisch gelöst wird, ist zu beachten, dass ein festes Element can relativ zu seinem Container positioniert ist.

Das habe ich bei der Bewerbung durch Zufall bemerkt

-webkit-transform: translateZ(0);

in Bezug auf den Körper wurde ein festes Kind relativ dazu (anstelle des Ansichtsfensters) erstellt. Meine fixierten Elemente left und top waren nun relativ zum Container.

Also recherchierte ich und stellte fest, dass das Thema bereits von Eric Meyer behandelt wurde. Auch wenn es sich als "Trick" anfühlte, stellt sich heraus, dass dies ein Teil der Spezifikationen ist:

Für Elemente, deren Layout vom CSS-Boxmodell bestimmt wird, kann jeder Wert außer none für die Transformation führt dies zur Erstellung von beiden Stapelkontext und ein enthaltender Block. Das Objekt fungiert als Block für fix positionierte Nachkommen enthalten.

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

Wenn Sie also eine Transformation auf ein übergeordnetes Element anwenden, wird es zum übergeordneten Block.

Aber...

Das Problem ist, dass die Implementierung fehlerhaft/kreativ erscheint, da sich die Elemente auch nicht mehr wie fix verhalten (auch wenn dieses Bit nicht zur Spezifikation gehört).

Das gleiche Verhalten wird in Safari, Chrome und Firefox gefunden, nicht aber in IE11 (wo das feste Element weiterhin fixiert bleibt).

Eine weitere interessante (undokumentierte) Sache ist, dass, wenn ein festes Element in einem transformierten Element enthalten ist, die top- und left -Eigenschaften nun unter Berücksichtigung der box-sizing-Eigenschaft auf den Container bezogen werden, der Bildlaufkontext über den Rand des Elements hinausgeht. als ob die Boxgröße auf border-box eingestellt wäre. Für einige Kreative da draußen könnte dies zu einem Spielzeug werden :)

PR&UUML;FUNG

121

Die Antwort lautet ja, solange Sie nicht left: 0 oder right: 0 setzen, nachdem Sie die div-Position auf fixed festgelegt haben.

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

Überprüfen Sie die Seitenleiste div. Es ist festgelegt, bezieht sich jedoch auf das übergeordnete Element und nicht auf den Fenstersichtpunkt.

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

position: sticky ist eine neue Methode zum Positionieren von Elementen, die konzeptionell position: fixed ähnlich ist. Der Unterschied besteht darin, dass ein Element mit position: sticky sich innerhalb seines übergeordneten Elements wie position: relative verhält, bis ein bestimmter Offset-Schwellenwert im Ansichtsfenster erreicht wird. 

In Chrome 56 (derzeit Beta im Dezember 2016, stabil im Januar 2017): Sticky ist jetzt zurück.

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

Mehr Details finden Sie in Halten Sie Ihre Landungen fest! Position: klebrige Länder in WebKit.

23
PoseLab

Ich habe dieses jQuery-Plugin erstellt, um ein ähnliches Problem zu lösen, bei dem ich einen zentrierten Container (Tabellendaten) hatte, und ich wollte, dass der Header oben auf der Seite angezeigt wird, wenn die Liste gescrollt wurde Die Tabellendaten sind also überall dort, wo ich den Container platziert habe (zentriert, links, rechts) und ihn auch bei horizontalem Bildlauf nach links und rechts mit der Seite bewegen lassen.

Hier ist der Link zu diesem jQuery-Plugin, das dieses Problem lösen kann:

https://github.com/bigspotteddog/ScrollToFixed

Die Beschreibung dieses Plugins lautet wie folgt:

Dieses Plugin wird verwendet, um Elemente oben auf der Seite zu fixieren, wenn das Element vertikal aus dem Bildlauf gescrollt worden wäre. Das Element kann sich jedoch weiterhin mit der horizontalen Bildlaufleiste nach links oder rechts bewegen.

Bei einer Option marginTop wird das Element nicht mehr vertikal nach oben bewegt, wenn der vertikale Bildlauf die Zielposition erreicht hat. Das Element wird jedoch immer noch horizontal verschoben, wenn die Seite nach links oder rechts gescrollt wird. Sobald die Seite die Zielposition nach unten gescrollt hat, wird das Element an der ursprünglichen Position auf der Seite wiederhergestellt.

Dieses Plugin wurde in Firefox 3/4, Google Chrome 10/11, Safari 5 und Internet Explorer 8/9 getestet.

Verwendung für Ihren speziellen Fall:

<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();
});
18
bigspotteddog

Nehmen Sie einfach den oberen und den linken Stil aus der festen Position div heraus. Hier ist ein Beispiel

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

Das #content div wird überall dort sitzen, wo das übergeordnete div sitzt, wird aber dort fixiert. 

17
hobberwickey

Ich musste dies mit einer Werbung machen, die mein Kunde außerhalb des Inhaltsbereichs platzieren wollte. Ich habe einfach folgendes getan und es hat wie ein Zauber funktioniert!

<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>
12
Eric K

Zwei HTML-Elemente und reines CSS (moderne Browser)

Siehe dieses jsFiddle-Beispiel. Ändern Sie die Größe der festen Elemente und sehen Sie, wie sich die festen Elemente sogar mit den schwebenden Elementen bewegen, in denen sie sich befinden. Verwenden Sie die innerste Bildlaufleiste, um zu sehen, wie der Bildlauf auf einer Website funktioniert (feste Elemente bleiben fest).

Wie viele hier schon gesagt haben, werden mit einer Taste keine Positionseinstellungen für das fixed-Element festgelegt (keine top-, right-, bottom- oder left-Werte).

Stattdessen setzen wir alle festen Elemente (beachten Sie, wie das letzte Feld vier davon hat) zuerst in das Feld, aus dem sie positioniert werden sollen, wie folgt:

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

Dann verwenden wir margin-top und margin-left, um sie in Bezug auf ihren Container "zu verschieben", ähnlich wie dieses CSS:

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

Beachten Sie, dass fixed-Elemente alle anderen Layout-Elemente ignorieren. Der letzte Container in unserer Geige kann mehrere fixed-Elemente enthalten und alle Elemente, die sich auf die linke obere Ecke beziehen. Dies gilt jedoch nur, wenn sie alle zuerst im Container platziert werden. Wenn dieser Vergleich zeigt, wird die Positionierung unzuverlässig , wenn sie im Containerinhalt verteilt wird.

Ob der Wrapper bei der Positionierung statisch , relativ oder absolut ist, spielt keine Rolle.

7
ScottS

Sie können die position: sticky-Eigenschaft verwenden. 

Hier ist ein Beispiel CODEPEN , das die Verwendung und auch die Unterschiede zu position: fixed veranschaulicht. 

Wie es sich verhält, wird unten erklärt:

  1. Ein Element mit klebriger Position wird basierend auf der Bildlaufposition des Benutzers positioniert. Im Prinzip verhält es sich wie position: relative, bis ein Element über einen bestimmten Versatz hinaus verschoben wird. In diesem Fall wird es zu einer Position: fix. Wenn es zurückgescrollt wird, kehrt es zu seiner vorherigen (relativen) Position zurück.

  2. Es beeinflusst den Fluss anderer Elemente auf der Seite, dh es nimmt einen bestimmten Platz auf der Seite ein (genau wie position: relative).

  3. Wenn es in einem Container definiert ist, wird es in Bezug auf diesen Container positioniert. Wenn der Container einen gewissen Überlauf hat (Bildlauf), wird er abhängig vom Bildlaufversatz in Position: Festgelegt.

Wenn Sie also die feste Funktionalität in einem Container erzielen möchten, verwenden Sie Sticky.

6
Pransh Tiwari

Sie können mein jQuery-Plugin ausprobieren, FixTo .

Verwendungszweck:

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

Eine andere seltsame Lösung, um eine relativ feste Position zu erreichen, ist die Umwandlung Ihres Containers in einen Iframe. Auf diese Weise kann Ihr fixes Element im Viewport des Containers und nicht der gesamten Seite fixiert werden.

2
Beto Aveiga

Mit reinem CSS können Sie es nicht schaffen. Zumindest habe ich nicht. Mit jQuery ist dies jedoch sehr einfach möglich. Ich erkläre mein Problem, und mit einer kleinen Änderung können Sie es verwenden.

Zunächst wollte ich, dass mein Element eine feste Oberseite (von oben im Fenster) hat und eine linke Komponente, die vom übergeordneten Element geerbt werden soll (da das übergeordnete Element zentriert ist). Um die linke Komponente festzulegen, fügen Sie einfach Ihr Element in das übergeordnete Element ein und legen Sie position:relative für das übergeordnete Element fest.

Dann müssen Sie wissen, wie viel Ihr Element von oben ist, wenn sich eine Bildlaufleiste oben befindet (y null, gescrollt); Es gibt wieder zwei Möglichkeiten. Erstens ist das statisch (eine Anzahl) oder Sie müssen es aus dem übergeordneten Element lesen.

In meinem Fall sind es 150 Pixel von oben statisch. Wenn Sie also 150 sehen, ist es das Element von oben, wenn wir nicht gescrollt haben.

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');
});
2
Mr Br

Ich habe ein jsfiddle erstellt, um zu zeigen, wie dies mit transform funktioniert.

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/

1
Wen

Ich habe das gleiche Problem, eines unserer Teammitglieder gibt mir eine Lösung. Um die Position der div fix und relativ zu anderen div zuzulassen, besteht unsere Lösung darin, einen Vater-Container zu verwenden, der die fix div und scroll div einschließt. 

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

css

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

.fix {
  prosition:absolute;
}
1
Jay0Lu

Dies ist einfach (wie in HTML unten)

Der Trick besteht darin, das Element (div) mit "position: fixed;" ..__ nicht auf top oder left zu setzen. Wenn diese nicht angegeben werden, erscheint das Element "fixed content" RELATIVE für das umgebende Element (das div mit " position: relative; ") INSTEAD OF relativ zum Browserfenster !!!

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

Mit Oben konnte ich einen schließenden "X" -Knopf oben in einem div-Bereich mit vertikalem Bildlauf finden. Das "X" steht an Ort und Stelle (bewegt sich nicht mit gerolltem Text und bewegt sich dennoch mit dem umschließenden Div-Container nach links oder rechts, wenn der Benutzer die Breite des Browser-Fensters ändert). Daher wird es vertikal "fixiert", aber relativ zu diesem positioniert das umschließende Element horizontal!

Bevor ich diese Funktion bekam, rollte das "X" nach oben und außer Sicht, als ich den Textinhalt nach unten scrollen konnte. 

Entschuldigung, dass ich meine Javascript-Funktion hideDiv () nicht zur Verfügung gestellt habe, aber dies würde diesen Beitrag unnötig verlängern. Ich entschied mich, es so kurz wie möglich zu halten.

1
Bruce Allen

Mein Projekt ist .NET ASP Core 2 MVC Angular 4-Vorlage mit Bootstrap 4. Das Hinzufügen von "sticky-top" in die Haupt-Anwendungskomponente html (d. H. App.component.html) in der ersten Zeile funktionierte wie folgt:

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

Ist das die Konvention oder habe ich das zu stark vereinfacht?

0
Adam Cox
/* 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%);
}
0
Carol McKay

Ich habe so etwas vor einiger Zeit gemacht. Ich war ziemlich neu in JavaScript, also bin ich sicher, dass Sie es besser machen können, aber hier ist ein Ausgangspunkt:

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

Sie müssen Ihre Breite einstellen, dann erhält es die Fensterbreite und ändert den Rand alle paar Sekunden. Ich weiß, dass es schwer ist, aber es funktioniert.

0

Es ist möglich, wenn Sie JavaScript verwenden. In diesem Fall ist das jQuery-Plugin Sticky-Kit:

0
Paz Aricha