Posizione fissa ma relativa al contenitore

Sto cercando di sistemare un div modo che rimanga sempre in cima allo schermo, usando:

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

Tuttavia, il div è all’interno di un contenitore centrato. Quando utilizzo la position:fixed risolve il div relativo alla finestra del browser, come se fosse contro il lato destro del browser. Invece, dovrebbe essere fisso rispetto al contenitore.

Conosco quella position:absolute può essere usata per correggere un elemento relativo al div , ma quando scorri verso il basso la pagina l’elemento svanisce e non si attacca in alto come con la position:fixed .

C’è un trucco o una soluzione per raggiungere questo objective?

Risposta breve: no. (Ora è ansible con la trasformazione CSS. Vedere la modifica sotto)

Risposta lunga: il problema con l’utilizzo del posizionamento “fisso” è che elimina l’elemento dal stream . quindi non può essere riposizionato rispetto al suo genitore perché è come se non ne avesse uno. Se, tuttavia, il contenitore ha una larghezza fissa e conosciuta, puoi usare qualcosa come:

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

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

Modifica (03/2015):

Questa informazione è obsoleta. Ora è ansible centrare il contenuto di una dimensione dynamic (orizzontale e verticale) con l’aiuto della magia della trasformazione CSS3. Si applica lo stesso principio, ma invece di utilizzare il margine per compensare il contenitore, è ansible utilizzare translateX(-50%) . Questo non funziona con il trucco del margine di cui sopra perché non sai quanto compensarlo a meno che la larghezza sia fissa e non puoi usare valori relativi (come il 50% ) perché sarà relativo al genitore e non al elemento a cui è applicato. transform comporta diversamente. I suoi valori sono relativi all’elemento a cui sono applicati. Pertanto, il 50% per la transform significa metà della larghezza dell’elemento, mentre il 50% per il margine è la metà della larghezza del genitore. Questa è una soluzione IE9 +

Usando un codice simile all’esempio precedente, ho ricreato lo stesso scenario usando larghezza e altezza completamente dinamiche:

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

Se vuoi che sia centrato, puoi farlo anche tu:

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

Demos:

jsFiddle: centrato solo orizzontalmente
jsFiddle: centrato sia orizzontalmente che verticalmente
Il credito originale va all’utente aaronk6 per avermelo fatto notare in questa risposta

In realtà questo è ansible e la risposta accettata riguarda solo la centralizzazione, che è abbastanza semplice. Inoltre non hai davvero bisogno di usare JavaScript.

Questo ti permetterà di gestire qualsiasi scenario:

Impostare tutto come si farebbe se si desidera posizionare: assoluto all’interno di una posizione: contenitore relativo, quindi creare un nuovo div posizione fissa all’interno del div con position: absolute , ma non impostare le proprietà superiore e sinistra. Verrà quindi riparato ovunque lo desideri, relativamente al contenitore.

Per esempio:

 /* 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! */ } 
 
Content in here will be fixed position, but 240px to the left of the site body.

Sì, secondo le specifiche, c’è un modo.

Mentre sono d’accordo sul fatto che Graeme Blackwood dovrebbe essere la risposta accettata, perché praticamente risolve il problema, si dovrebbe notare che un elemento fisso può essere posizionato relativamente al suo contenitore.

Ho notato per caso che durante l’applicazione

 -webkit-transform: translateZ(0); 

al corpo, ha reso un bambino fisso rispetto ad esso (invece del viewport). Quindi i miei elementi fissi a left e le proprietà top ora erano relative al contenitore.

Così ho fatto delle ricerche e ho scoperto che il problema era già stato trattato da Eric Meyer e, anche se sembrava un “trucco”, risulta che questo è parte delle specifiche:

Per gli elementi il ​​cui layout è governato dal modello di box CSS, qualsiasi valore diverso da none per la trasformazione porta alla creazione sia di un contesto di stack che di un blocco contenitore. L’object agisce come un blocco contenitore per i discendenti posizionati fissi.

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

Quindi, se applichi una trasformazione a un elemento genitore, diventerà il blocco contenitore.

Ma…

Il problema è che l’implementazione sembra bacata / creativa, perché anche gli elementi smettono di comportarsi come fissi (anche se questo bit non sembra essere parte delle specifiche).

Lo stesso comportamento si troverà in Safari, Chrome e Firefox, ma non in IE11 (dove l’elemento fisso rimarrà comunque fisso).

Un’altra cosa interessante (non documentata) è che quando un elemento fisso è contenuto in un elemento trasformato, mentre le sue proprietà top e left saranno ora correlate al contenitore, rispettando la proprietà di box-sizing della box-sizing , il suo contesto di scorrimento si estenderà oltre il bordo del elemento, come se il ridimensionamento del box fosse impostato su border-box . Per alcuni creativi là fuori, questo potrebbe eventualmente diventare un giocattolo 🙂

TEST

La risposta è sì, finché non si imposta left: 0 o right: 0 dopo aver impostato la posizione div su fixed.

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

Acquista la barra laterale div. È fisso, ma correlato al genitore, non al punto di vista della finestra.

 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; } 
wrapper
main

Ho creato questo plugin jQuery per risolvere un problema simile a quello in cui avevo un contenitore centrato (dati tabulari), e volevo che l’intestazione si fissasse in cima alla pagina quando l’elenco era a scorrimento, eppure volevo che fosse ancorato a i dati tabulari quindi sarebbe ovunque dovessi posizionare il contenitore (centrato, a sinistra, a destra) e permettere anche a lui di spostarsi a sinistra ea destra con la pagina quando si scorre orizzontalmente.

Ecco il link a questo plugin jQuery che può risolvere questo problema:

https://github.com/bigspotteddog/ScrollToFixed

La descrizione di questo plugin è la seguente:

Questo plugin viene utilizzato per correggere gli elementi nella parte superiore della pagina, se l’elemento si sarebbe spostato fuori dalla vista, verticalmente; tuttavia, consente all’elemento di continuare a spostarsi a sinistra o a destra con lo scorrimento orizzontale.

Data un’opzione marginTop, l’elemento smetterà di muoversi verticalmente verso l’alto una volta che lo scroll verticale avrà raggiunto la posizione target; ma, l’elemento si sposta ancora orizzontalmente mentre la pagina scorre verso sinistra o verso destra. Una volta che la pagina è stata spostata verso il basso ha superato la posizione di destinazione, l’elemento verrà ripristinato nella sua posizione originale sulla pagina.

Questo plug-in è stato testato in Firefox 3/4, Google Chrome 10/11, Safari 5 e Internet Explorer 8/9.

Uso per il tuo caso particolare:

   $(document).ready(function() { $('#mydiv').scrollToFixed(); }); 

Prendi solo gli stili in alto a sinistra dal div di posizione fissa. Ecco un esempio

 
content

Il div #content sarà seduto dovunque si trovi il genitore div, ma verrà riparato lì.

Hai position: sticky che è un nuovo modo di posizionare gli elementi ed è concettualmente simile alla position: fixed . La differenza è che un elemento con position: sticky si comporta come la position: relative all’interno del relativo genitore, finché una determinata soglia di offset non viene soddisfatta nella finestra.

In Chrome 56 (attualmente beta a partire da dicembre 2016, stabile a gennaio 2017) posizione: sticky è tornato.

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

Maggiori dettagli sono in Stick your landings! posizione: terre adesive in WebKit .

Dovevo farlo con una pubblicità che il mio cliente voleva sedersi al di fuori dell’area del contenuto. Ho semplicemente fatto il seguente e ha funzionato come un fascino!

 

Due elementi HTML e puro CSS (browser moderni)

Vedi questo esempio di jsFiddle. Ridimensiona e osserva come gli elementi fissi si muovono anche con gli elementi fluttuanti in cui si trovano. Utilizza la barra di scorrimento più interna per vedere come funzionerebbe lo scorrimento su un sito (gli elementi fissi rimanevano fissi).

Come molti hanno affermato, una chiave non sta impostando alcuna impostazione posizionale sull’elemento fixed (nessun valore top , right , bottom o left ).

Piuttosto, mettiamo tutti gli elementi fissi (nota come l’ultima casella ne ha quattro) prima nella casella in cui devono essere posizionati, in questo modo:

 
Test
Some other content in.

Quindi usiamo margin-top e margin-left per “spostarli” in relazione al loro contenitore, qualcosa come questo CSS:

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

Nota che poiché gli elementi fixed ignorano tutti gli altri elementi di layout, il contenitore finale nel nostro violino può avere più elementi fixed e avere ancora tutti quegli elementi correlati all’angolo in alto a sinistra. Ma questo è vero soltanto se sono tutti collocati per primi nel contenitore, poiché questo paragone di comparazione mostra che se disperso nel contenuto del contenitore, il posizionamento diventa inaffidabile .

Se il wrapper è statico , relativo o assoluto nel posizionamento, non importa.

È ansible utilizzare la position: sticky proprietà position: sticky .

Ecco un esempio di CODEPEN che ne dimostra l’utilizzo e anche in che modo si differenzia dalla position: fixed .

Come si comporta è spiegato di seguito:

  1. Un elemento con posizione adesiva è posizionato in base alla posizione di scorrimento dell’utente. Fondamentalmente agisce come position: relative fino a quando un elemento viene fatto scorrere oltre un offset specifico, nel qual caso si trasforma in posizione: fissa. Quando viene fatto scorrere indietro, torna alla posizione precedente (relativa).

  2. Effettua il stream di altri elementi nella pagina, ovvero occupa uno spazio specifico sulla pagina (proprio come la position: relative ).

  3. Se è definito all’interno di un contenitore, viene posizionato rispetto a quel contenitore. Se il contenitore presenta un overflow (scorrimento), a seconda dell’offset della spirale si trasforma in posizione: fissa.

Quindi, se vuoi ottenere la funzionalità fissa ma all’interno di un contenitore, usa sticky.

Puoi provare il mio plugin jQuery, FixTo .

Uso:

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

Un’altra strana soluzione per ottenere una posizione fissa relativa è la conversione del contenitore in un iframe, in modo tale che il tuo elemento fisso possa essere fissato alla finestra del contenitore e non all’intera pagina.

Con il puro CSS non puoi riuscire a farlo; almeno non l’ho fatto. Comunque puoi farlo con jQuery molto semplicemente. Spiegherò il mio problema e con un piccolo cambiamento puoi usarlo.

Quindi, per cominciare, volevo che il mio elemento avesse una cima fissa (dalla parte superiore della finestra), e un componente sinistro ereditasse dall’elemento genitore (perché l’elemento genitore è centrato). Per impostare il componente sinistro, basta mettere l’elemento nel genitore e impostare la position:relative per l’elemento genitore.

Quindi devi sapere quanto è alto il tuo elemento quando la barra di scorrimento è in cima (y zero a scorrimento); ci sono ancora due opzioni. Il primo è che è statico (un certo numero) o devi leggerlo dall’elemento genitore.

Nel mio caso si tratta di 150 pixel dalla parte superiore statica. Quindi quando vedi 150 è quanto è l’elemento dall’alto quando non abbiamo fatto scorrere.

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

Questo è facile (come per HTML qui sotto)

Il trucco è NON usare in alto o a sinistra sull’elemento (div) con “position: fixed;”. Se questi non sono specificati, l’elemento “fixed content” apparirà RELATIVO all’elemento che lo racchiude (il div con “position: relativo;”) INSTEAD OF relativo alla finestra del browser !!!

 
lots of Text To Be Scrolled vertically... bhah! blah! blah!

Sopra mi ha permesso di individuare un pulsante di chiusura “X” nella parte superiore di un sacco di testo in un div con scorrimento verticale. La “X” si trova sul posto (non si muove con il testo a scorrimento e tuttavia si sposta a sinistra oa destra con il contenitore div allegato quando l’utente ridimensiona la larghezza della finestra del browser! Quindi è “fissato” verticalmente, ma posizionato rispetto a l’elemento di chiusura orizzontalmente!

Prima di farlo funzionare, la “X” scorreva su e fuori dalla vista quando scorrevo il contenuto del testo verso il basso.

Mi scuso per non aver fornito la mia funzione javascript hideDiv (), ma inutilmente renderebbe questo post più lungo. Ho deciso di mantenerlo il più breve ansible.

Ho creato un jsfiddle per dimostrare come funziona usando la trasformazione.

HTML

 
Content
X
Side bar

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/

Ho lo stesso problema, uno dei membri del nostro team mi dà una soluzione. Per consentire la posizione di fix div e relativamente ad altri div, la nostra soluzione è usare un contenitore padre per avvolgere il div fix e scroll div.

 

css

 .container { position: relative; flex:1; display:flex; } .fix { prosition:absolute; } 

Ho fatto qualcosa del genere per un po ‘di tempo fa. Ero abbastanza nuovo su JavaScript, quindi sono sicuro che puoi fare di meglio, ma qui c’è un punto di partenza:

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

Sarà necessario impostare la larghezza, quindi otterrà la larghezza della finestra e cambierà il margine ogni pochi secondi. So che è pesante, ma funziona.

È ansible se usi JavaScript. In questo caso, il plugin jQuery Sticky-Kit :

Il mio progetto è .NET ASP Core 2 MVC Angular 4 template con Bootstrap 4. L’aggiunta di “sticky-top” al componente principale dell’app html (cioè app.component.html) sulla prima riga ha funzionato, come segue:

 

Controllare questo: