Posición fija pero relativa al contenedor

Estoy tratando de arreglar un div para que siempre se quede en la parte superior de la pantalla, usando:

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

Sin embargo, el div está dentro de un contenedor centrado. Cuando uso position:fixed , corrige el div relativo a la ventana del navegador, como que está en el lado derecho del navegador. En cambio, debe ser reparado en relación con el contenedor.

Sé que la position:absolute se puede usar para fijar un elemento relativo al div , pero cuando se desplaza hacia abajo de la página, el elemento desaparece y no se pega a la parte superior como con la position:fixed .

¿Hay algún truco o solución para lograr esto?

Respuesta corta: no. (Ahora es posible con la transformación CSS. Consulte la edición a continuación)

Respuesta larga: el problema con el uso del posicionamiento “fijo” es que elimina el elemento del flujo . por lo tanto, no puede ser reubicado en relación con su padre porque es como si no tuviera uno. Sin embargo, si el contenedor tiene un ancho fijo y conocido, puede usar algo como:

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

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

Editar (03/2015):

Esta es información desactualizada. Ahora es posible centrar el contenido de un tamaño dynamic (horizontal y verticalmente) con la ayuda de la magia de la transformación CSS3. Se aplica el mismo principio, pero en lugar de utilizar el margen para compensar su contenedor, puede usar translateX(-50%) . Esto no funciona con el truco de margen anterior porque no sabe cuánto compensarlo a menos que el ancho sea fijo y no pueda usar valores relativos (como 50% ) porque será relativo al padre y no al padre. elemento al que se aplica. transform comporta de manera diferente. Sus valores son relativos al elemento al que se aplican. Por lo tanto, 50% para la transform significa la mitad del ancho del elemento, mientras que el 50% del margen es la mitad del ancho del elemento principal. Esta es una solución IE9 +

Usando un código similar al ejemplo anterior, recreé el mismo escenario usando ancho y alto completamente dynamics:

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

Si quieres que esté centrado, puedes hacerlo también:

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

Población:

jsFiddle: Centrado horizontalmente solamente
jsFiddle: Centrado tanto horizontal como verticalmente
El crédito original es para el usuario aaronk6 por señalarlo en esta respuesta

En realidad, esto es posible y la respuesta aceptada solo trata de la centralización, lo cual es bastante sencillo. Además, realmente no necesita usar JavaScript.

Esto te permitirá lidiar con cualquier situación:

Configure todo como lo haría si desea posicionar: absoluto dentro de una posición: contenedor relativo, y luego crear un nuevo div de posición fijo dentro del div con la position: absolute , pero no establezca sus propiedades superior e izquierda. Luego se fijará donde lo desee, en relación con el contenedor.

Por ejemplo:

 /* 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í, de acuerdo con las especificaciones, hay una manera.

Si bien estoy de acuerdo con que Graeme Blackwood debe ser la respuesta aceptada, ya que prácticamente resuelve el problema, se debe tener en cuenta que un elemento fijo se puede colocar con relación a su contenedor.

Noté por accidente que cuando aplicaba

 -webkit-transform: translateZ(0); 

para el cuerpo, hizo un niño fijo con relación a él (en lugar de la ventana gráfica). Entonces, mis elementos fijos, top propiedades left y top , ahora estaban relacionadas con el contenedor.

Así que investigué un poco y descubrí que el problema ya había sido cubierto por Eric Meyer y, aunque pareciera un “truco”, resulta que esto forma parte de las especificaciones:

Para los elementos cuyo diseño se rige por el modelo de caja de CSS, cualquier valor que no sea ninguno para la transformación da como resultado la creación de un contexto de astackmiento y un bloque contenedor. El objeto actúa como un bloque contenedor para descendientes posicionados fijos.

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

Entonces, si aplica cualquier transformación a un elemento padre, se convertirá en el bloque contenedor.

Pero…

El problema es que la implementación parece fallida / creativa, porque los elementos también dejan de comportarse como fijos (incluso si este bit no parece ser parte de la especificación).

El mismo comportamiento se encontrará en Safari, Chrome y Firefox, pero no en IE11 (donde el elemento fijo seguirá siendo fijo).

Otra cosa interesante (no documentada) es que cuando un elemento fijo está contenido dentro de un elemento transformado, mientras que sus propiedades top e left ahora estarán relacionadas con el contenedor, respetando la propiedad de box-sizing , su contexto de desplazamiento se extenderá más allá del borde del elemento, como si el tamaño del cuadro se estableció en border-box . Para algunos creativos por ahí, esto podría convertirse en un juguete 🙂

PRUEBA

La respuesta es sí, siempre que no establezca a la left: 0 o a la right: 0 después de establecer la posición de div a fija.

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

Pagar la barra lateral div. Es fijo, pero está relacionado con el padre, no con el punto de vista de la ventana.

 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

Creé este plugin de jQuery para resolver un problema similar al que tenía cuando tenía un contenedor centrado (datos tabulares), y quería que el encabezado se fijara en la parte superior de la página cuando se desplazaba la lista, pero quería anclarlo. los datos tabulares de modo que estén donde coloque el contenedor (centrado, izquierdo, derecho) y también permitan que se muevan hacia la izquierda y hacia la derecha con la página cuando se desplazan horizontalmente.

Aquí está el enlace a este plugin jQuery que puede resolver este problema:

https://github.com/bigspotteddog/ScrollToFixed

La descripción de este complemento es la siguiente:

Este complemento se usa para fijar elementos en la parte superior de la página, si el elemento se hubiera desplazado fuera de la vista, verticalmente; sin embargo, permite que el elemento continúe moviéndose hacia la izquierda o hacia la derecha con el desplazamiento horizontal.

Dada una opción marginTop, el elemento dejará de moverse verticalmente hacia arriba una vez que el desplazamiento vertical haya alcanzado la posición objective; pero, el elemento se moverá horizontalmente mientras la página se desplaza hacia la izquierda o hacia la derecha. Una vez que la página se ha desplazado hacia atrás, ha pasado a la posición objective, el elemento se restaurará a su posición original en la página.

Este complemento ha sido probado en Firefox 3/4, Google Chrome 10/11, Safari 5 e Internet Explorer 8/9.

Uso para su caso particular:

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

Solo saca los estilos superior e izquierdo de la div posición fija. Aquí hay un ejemplo

 
content

El #content div se sentará donde esté el div principal, pero se arreglará allí.

Tienes una position: sticky que es una nueva forma de posicionar elementos y es conceptualmente similar a la position: fixed . La diferencia es que un elemento con position: sticky comporta como position: relative dentro de su primario, hasta que se cumple un umbral de offset dado en la ventana gráfica.

En la posición de Chrome 56 (actualmente en beta desde diciembre de 2016, estable en enero de 2017): sticky ya ha vuelto.

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

¡Más detalles están en Stick your landingings! posición: tierras pegajosas en WebKit .

Tuve que hacer esto con un anuncio que mi cliente quería sentarse fuera del área de contenido. ¡Simplemente hice lo siguiente y funcionó como un amuleto!

 

Dos elementos HTML y CSS puro (navegadores modernos)

Vea este ejemplo jsFiddle. Cambie el tamaño y vea cómo se mueven los elementos fijos con los elementos flotantes en los que se encuentran. Utilice la barra de desplazamiento más interna para ver cómo funcionaría el desplazamiento en un sitio (los elementos fijos permanecen fijos).

Como muchos de ellos han indicado, una tecla no establece ninguna configuración posicional en el elemento fixed (ningún valor top , right , bottom o left ).

Más bien, colocamos todos los elementos fijos (observe cómo la última caja tiene cuatro de ellos) primero en la caja desde la que se colocarán, de esta forma:

 
Test
Some other content in.

Luego usamos margin-top y margin-left para “moverlos” en relación con su contenedor, algo así como lo hace este CSS:

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

Tenga en cuenta que debido a que fixed elementos fixed ignoran todos los demás elementos de diseño, el contenedor final en nuestro violín puede tener múltiples elementos fixed y aún tener todos esos elementos relacionados con la esquina superior izquierda. Pero esto solo es cierto si todos se colocan primero en el contenedor, ya que este violín de comparación muestra que si se dispersa dentro del contenido del contenedor, el posicionamiento no es confiable .

Si la envoltura es estática , relativa o absoluta en el posicionamiento, no importa.

Puede usar la propiedad position: sticky .

Aquí hay un ejemplo de CODEPEN que demuestra el uso y también cómo difiere de la position: fixed .

Cómo se comporta se explica a continuación:

  1. Un elemento con posición adhesiva se coloca según la posición de desplazamiento del usuario. Básicamente actúa como position: relative hasta que un elemento se desplaza más allá de un desplazamiento específico, en cuyo caso se convierte en posición: fijo. Cuando se desplaza hacia atrás, vuelve a su posición anterior (relativa).

  2. Efectúa el flujo de otros elementos en la página, es decir, ocupa un espacio específico en la página (al igual que la position: relative ).

  3. Si se define dentro de algún contenedor, se posiciona con respecto a ese contenedor. Si el contenedor tiene un exceso de desbordamiento (desplazamiento), dependiendo del desplazamiento de desplazamiento, cambia a su posición: fijo.

Por lo tanto, si desea lograr la funcionalidad fija pero dentro de un contenedor, utilice Sticky.

Puedes probar mi plugin jQuery, FixTo .

Uso:

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

Otra solución extraña para lograr una posición relativa fija es convertir su contenedor en un iframe, de esa manera su elemento fijo puede ser fijado a la ventana de su contenedor y no a toda la página.

Con CSS puro no puedes lograrlo; al menos yo no. Sin embargo, puedes hacerlo con jQuery de manera muy simple. Explicaré mi problema y con un pequeño cambio podrás usarlo.

Entonces, para comenzar, quería que mi elemento tuviera una parte superior fija (desde la parte superior de la ventana) y un componente izquierdo para heredar del elemento principal (porque el elemento principal está centrado). Para configurar el componente izquierdo, simplemente coloque su elemento en el padre y establezca la position:relative para el elemento padre.

Entonces necesitas saber cuánto sube desde arriba tu elemento cuando la barra de desplazamiento está en la parte superior (y cero desplazado); hay dos opciones de nuevo. Primero es que es estático (algún número) o tiene que leerlo desde el elemento padre.

En mi caso, está a 150 píxeles de la estática superior. Entonces cuando ves 150 es cuánto es el elemento de la parte superior cuando no nos hemos desplazado.

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

Esto es fácil (según el HTML a continuación)

El truco es NO usar arriba o izquierda en el elemento (div) con “posición: fija;”. Si no se especifican, el elemento “contenido fijo” aparecerá RELATIVO al elemento adjunto (el div con “posición: relativo;”) EN LUGAR DE relativo a la ventana del navegador !!!

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

Arriba me permitió ubicar un botón “X” de cierre en la parte superior de un montón de texto en un div con desplazamiento vertical. La “X” se coloca en su lugar (no se mueve con texto desplazado y sin embargo se mueve hacia la izquierda o hacia la derecha con el contenedor divisor div cuando el usuario cambia el ancho de la ventana del navegador. Por lo tanto, se “fija” verticalmente, pero se coloca en relación con el elemento envolvente horizontalmente!

Antes de que funcionara, la “X” se desplazó hacia arriba y desapareció cuando desplacé el contenido del texto hacia abajo.

Disculpas por no proporcionar mi función hideDiv () de JavaScript, pero innecesariamente haría que esta publicación sea más larga. Opté por mantenerlo lo más corto posible.

Creé un jsfiddle para demostrar cómo funciona esto con la transformación.

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/

Tengo el mismo problema, uno de los miembros de nuestro equipo me da una solución. Para permitir la posición de div fix y relativa a otro div, nuestra solución es usar un contenedor padre wrap the fix div y scroll div.

 

css

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

Hice algo así un tiempo atrás. Era bastante nuevo en JavaScript, así que estoy seguro de que puede hacerlo mejor, pero este es un punto de partida:

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

Tendrá que establecer su ancho, y luego obtiene el ancho de la ventana y cambia el margen cada pocos segundos. Sé que es pesado, pero funciona.

Es posible si usas JavaScript. En este caso, el complemento jQuery Sticky-Kit :

Mi proyecto es .NET ASP Core 2 MVC Plantilla Angular 4 con Bootstrap 4. Agregando “sticky-top” al componente principal de la aplicación html (es decir, app.component.html) en la primera fila trabajada, de la siguiente manera:

 

Mira esto: