Css 位置元素垂直固定,绝对水平

Css 位置元素垂直固定,绝对水平,css,position,Css,Position,以下是我试图实现的目标: 我需要一个按钮,该按钮位于距离div右侧一定距离的位置,并且无论视口大小如何,与div侧的距离始终相同,但将随窗口滚动 因此,始终是距离div右侧的x像素,但始终是距离视图端口顶部的y像素 这可能吗?根据另一个元件水平定位固定元件 (免责声明注释:从技术上讲不是问题标题所述的“”,但确实实现了OP最初想要的,固定位置元素与另一个元素的右边缘的距离为“X”,但在其垂直滚动中固定。) 我喜欢这些类型的css挑战。作为概念的证明,是的。您可能需要根据自己的需要调整一些内容,但

以下是我试图实现的目标:

我需要一个按钮,该按钮位于距离div右侧一定距离的位置,并且无论视口大小如何,与div侧的距离始终相同,但将随窗口滚动

因此,始终是距离div右侧的x像素,但始终是距离视图端口顶部的y像素

这可能吗?

根据另一个元件水平定位固定元件 (免责声明注释:从技术上讲不是问题标题所述的“”,但确实实现了OP最初想要的,固定位置元素与另一个元素的右边缘的距离为“X”,但在其垂直滚动中固定。)

我喜欢这些类型的css挑战。作为概念的证明,是的。您可能需要根据自己的需要调整一些内容,但下面是一些通过FireFox、IE8和IE7的html和css示例(当然,IE6没有
位置:fixed

HTML:

关键是在
div.fixed
上根本不为水平方向设置
left
right
,而是使用两个包装器div设置水平位置。如果
div.inflow
为固定宽度,则不需要
div.positioner
,因为
div.fixed
的左边距可以设置为容器的已知宽度。但是,如果您希望容器具有一定的宽度百分比,则需要使用
div.positioner
首先将
div.fixed
推到
div.inflow
的右侧


编辑:作为一个有趣的旁注,当我在
div上设置
overflow:hidden
(如果需要这样做)时,流入对位于另一方边界之外的固定位置div没有影响。显然,固定的位置足以将其从包含div的
溢出上下文中移除

我来到这里,是为了寻找一个类似问题的解决方案,即有一个横跨窗口宽度的页脚栏,位于(可变高度和宽度)内容下方。换句话说,使页脚看起来相对于其水平位置是“固定的”,但相对于其垂直位置保留其在文档流中的正常位置。在我的例子中,我将页脚文本右对齐,因此动态调整页脚宽度对我来说很有效。以下是我的想法:

HTML CoffeeScript/JavaScript (使用prototype.js)

其中包括:

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"
  });
});
这在FireFox中运行良好,在Chrome中运行良好(有点紧张);我还没有尝试过其他浏览器

我还希望页脚下方的任何空闲空间都是不同的颜色,因此我添加了此
footer stretch
div:

HTML 请注意,要使#footer stretch div工作,所有父元素(可能还有html元素-不确定)都必须具有固定的高度(在本例中,高度=100%)。

经过大量挖掘(包括本文),我找不到我喜欢的解决方案。这里被接受的答案与OP的标题不符,我能找到的最好的解决方案无疑导致了不安的因素。然后,我突然想到:让元素“固定”,检测何时出现水平滚动,并将其切换到绝对位置。以下是生成的代码:

HTML

  <div class="blue">
    <div class="red">
    </div>
  </div>
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");
  }
});

我的荣幸(从字面上说,这很有趣)它并没有像预期的那样起作用。只要有一个水平滚动条,您就可以向右滚动,固定位置框与div的距离就不会保持不变。在这一页上向右滚动:@sparebytes——如果这是您所期望的,那么我同意。最初的OP只是想找到一种方法,将固定元素水平放置在另一个元素之外。在他的版本中,视图端口将改变大小(不会出现水平滚动条)。该元素最终仍然是一个
固定的
元素,不受滚动的影响。也许我应该更新问题标题以反映这一点。@sparebytes——我没有将标题改为帖子,而是选择在我的答案中添加一条免责声明,这样就不会让其他人对它的成就感到措手不及。感谢您提醒我您的期望,以便能够解决。@ScottS,很高兴您更新了您的答案。我不认为单用Css就可以将一个维度
固定
和另一个维度
绝对
,javascript必须更新scroll上的坐标。这是迄今为止找到的最佳解决方案。即使在发布此解决方案4年后。看来我们必须解决这个问题,只要在2年多后的所有浏览器中都没有适当的支持,而且还没有解决方案……悲伤的CHROME bug报告是可用的
#footer-outer
{
    width: 100%;
}
#footer
{
    text-align: right;
    background-color: blue;
    /* various style attributes, not important for the example */
}
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"} )
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"
  });
});
...
</div><!-- end footer -->
<div id="footer-stretch"></div>
</div><!-- end footer-outer -->
#footer-outer
{
    height: 100%;
}
#footer-stretch
{
    height: 100%;
    background-color: #2A2A2A;
}
  <div class="blue">
    <div class="red">
    </div>
  </div>
/* 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;
}
$(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");
  }
});