Elemento de posición fijo verticalmente, absoluto horizontalmente

Esto es lo que estoy tratando de lograr:

Necesito un botón que esté posicionado a cierta distancia del lado derecho de un div, y siempre esté a esa misma distancia del lado del div sin importar el tamaño de la ventana gráfica, pero se desplazará con la ventana.

Por lo tanto, es x píxeles desde el lado derecho del div en todo momento, pero y píxeles desde la parte superior del puerto de visualización en todo momento.

es posible?

Posición del elemento fijo horizontalmente basado en otro elemento

( Nota de exención de responsabilidad : la solución ofrecida aquí no es técnicamente ” absoluta horizontalmente ” como el título de la pregunta indica, pero logró lo que el OP originalmente quería, el elemento de posición fija es la distancia ‘X’ del borde derecho de otro, pero fijo en su desplazamiento vertical.)

Me encantan estos tipos de desafíos CSS. Como una prueba de concepto, sí, puedes obtener lo que deseas . Puede que tenga que ajustar algunas cosas para sus necesidades, pero aquí hay ejemplos de html y css que pasaron Firefox, IE8 e IE7 (IE6, por supuesto, no tiene position: fixed ).

HTML:

  

CSS (bordes y todas las dimensiones para la demostración):

 div.inflow { width: 200px; height: 1000px; border: 1px solid blue; float: right; position: relative; margin-right: 100px; } div.positioner {position: absolute; right: 0;} /*may not be needed: see below*/ div.fixed { width: 80px; border: 1px solid red; height: 100px; position: fixed; top: 60px; margin-left: 15px; } 

La clave es no configurar la left o la right en absoluto para la horizontal en el div.fixed pero use los dos divs del wrapper para establecer la posición horizontal. El div.positioner no es necesario si el div.inflow tiene un ancho fijo, ya que el margen izquierdo de div.fixed se puede establecer en el ancho conocido del contenedor. Sin embargo, si desea que el contenedor tenga un ancho de porcentaje, necesitará que div.positioner presione div.fixed en el lado derecho de div.inflow .

Editar: Como nota al margen interesante, cuando configuro el overflow: hidden (si es necesario hacer eso) en div.inflow no tiene efecto en el div de posición fija que se encuentra fuera de los límites del otro. Aparentemente, la posición fija es suficiente para sacarlo del contexto del div que contiene para el overflow .

Llegué aquí en busca de una solución a un problema similar, que consistía en tener una barra de pie de página que abarca el ancho de la ventana y se encuentra debajo del contenido (altura y ancho variable). En otras palabras, haga que parezca que el pie de página está “fijo” con respecto a su posición horizontal, pero conserva su posición normal en el flujo de documentos con respecto a su posición vertical. En mi caso, tenía el texto del pie de página alineado a la derecha, así que funcionó para que ajuste dinámicamente el ancho del pie de página. Aquí es lo que se me ocurrió:

HTML

  

CSS

 #footer-outer { width: 100%; } #footer { text-align: right; background-color: blue; /* various style attributes, not important for the example */ } 

CoffeeScript / JavaScript

(Usando prototype.js).

 class Footer document.observe 'dom:loaded', -> Footer.width = $('footer-outer').getDimensions().width Event.observe window, 'scroll', -> x = document.viewport.getScrollOffsets().left $('footer-outer').setStyle( {'width': (Footer.width + x) + "px"} ) 

que comstack en:

 Footer = (function() { function Footer() {} return Footer; })(); document.observe('dom:loaded', function() { return Footer.width = $('footer-outer').getDimensions().width; }); Event.observe(window, 'scroll', function() { var x; x = document.viewport.getScrollOffsets().left; return $('footer-outer').setStyle({ 'width': (Footer.width + x) + "px" }); }); 

Esto funciona muy bien en Firefox, y bastante bien en Chrome (es un poco nervioso); No he probado otros navegadores.

También quería que cualquier espacio libre debajo del pie de página fuera de un color diferente, así que agregué este div de footer-stretch :

HTML

 ...    

CSS

 #footer-outer { height: 100%; } #footer-stretch { height: 100%; background-color: #2A2A2A; } 

Tenga en cuenta que para que el div # footer-stretch funcione, todos los elementos principales hasta el elemento body (y posiblemente el elemento html – no seguro) deben tener una altura fija (en este caso, altura = 100%).

Después de excavar mucho (incluida esta publicación), no pude encontrar la solución que me gustaba. La respuesta aceptada aquí no hace lo que dice el título del OP, y las mejores soluciones que pude encontrar resultaron en elementos con muchas posibilidades. Entonces, me di cuenta: haga que el elemento sea “fijo”, detecte cuándo se produce un desplazamiento horizontal, y póngalo en posición absoluta. Aquí está el código resultante:

Véalo como un lápiz de código.

HTML

  

CSS

 /* Styling */ .blue, .red { border-style: dashed; border-width: 2px; padding: 2px; margin-bottom: 2px; } /* This will be out "vertical-fixed" element */ .red { border-color: red; height: 120px; position: fixed; width: 500px; } /* Container so we can see when we scroll */ .blue { border-color: blue; width: 50%; display: inline-block; height: 800px; } 

JavaScript

 $(function () { var $document = $(document), left = 0, scrollTimer = 0; // Detect horizontal scroll start and stop. $document.on("scroll", function () { var docLeft = $document.scrollLeft(); if(left !== docLeft) { var self = this, args = arguments; if(!scrollTimer) { // We've not yet (re)started the timer: It's the beginning of scrolling. startHScroll.apply(self, args); } window.clearTimeout(scrollTimer); scrollTimer = window.setTimeout(function () { scrollTimer = 0; // Our timer was never stopped: We've finished scrolling. stopHScroll.apply(self, args); }, 100); left = docLeft; } }); // Horizontal scroll started - Make div's absolutely positioned. function startHScroll () { console.log("Scroll Start"); $(".red") // Clear out any left-positioning set by stopHScroll. .css("left","") .each(function () { var $this = $(this), pos = $this.offset(); // Preserve our current vertical position... $this.css("top", pos.top) }) // ...before making it absolutely positioned. .css("position", "absolute"); } // Horizontal scroll stopped - Make div's float again. function stopHScroll () { var leftScroll = $(window).scrollLeft(); console.log("Scroll Stop"); $(".red") // Clear out any top-positioning set by startHScroll. .css("top","") .each(function () { var $this = $(this), pos = $this.position(); // Preserve our current horizontal position, munus the scroll position... $this.css("left", pos.left-leftScroll); }) // ...before making it fixed positioned. .css("position", "fixed"); } });