【问题标题】:Position element fixed vertically, absolute horizontally位置元素垂直固定,绝对水平
【发布时间】:2011-03-19 04:56:30
【问题描述】:

这是我想要完成的:

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

所以它始终是 div 右侧的 x 像素,但始终是视口顶部的 y 像素。

这可能吗?

【问题讨论】:

    标签: css position


    【解决方案1】:

    基于另一个元素水平定位固定元素

    (免责声明The solution offered here 在技术上不是问题标题所述的“absolute horizontally”,但确实实现了 OP 最初想要的,固定位置元素为 'X' 距离从另一个的右边缘开始,但固定在其垂直滚动中。)

    我喜欢这些类型的 CSS 挑战。作为概念证明,是的,you can get what you desire。您可能需要根据自己的需要调整一些东西,但这里有一些通过 FireFox、IE8 和 IE7 的示例 html 和 css(当然,IE6 没有position: fixed)。

    HTML:

    <body>
      <div class="inflow">
        <div class="positioner"><!-- may not be needed: see notes below-->
          <div class="fixed"></div>
        </div>
      </div>
    </body>
    

    CSS(用于演示的边框和所有尺寸):

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

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

    编辑:作为一个有趣的附注,当我在div.inflow 上设置overflow: hidden(应该需要这样做)时,在固定时没有效果位置 div 在对方的边界之外。显然,固定位置足以将其从包含 div 的上下文中取出 overflow

    【讨论】:

    • 我的荣幸(从字面上看,这很有趣)
    • 它实际上并没有按预期工作。只要有水平滚动条并且您可以向右滚动,固定位置框就不会与 div 保持相同的距离。在此页面上向右滚动:jsfiddle.net/tXXtL
    • @sparebytes——如果这是您所期望的,那么我同意。最初的 OP 只是在寻找一种方法来使固定元素水平定位在另一个元素之外。在他的版本中,视口会改变大小(不会出现水平滚动条)。最终,该元素仍然是 fixed 元素,并且不受滚动影响。也许我应该更新问题标题以反映这一点。
    • @sparebytes--我没有更改帖子的标题,而是选择在我的答案中添加免责声明,这样其他人就不会对它的成就感到措手不及。感谢您提请我注意您的期望,以便我们解决它。
    • @ScottS,很高兴您更新了答案。我认为不可能有一个维度 fixed 和另一个 absolute 单独使用 Css,javascript 必须更新滚动坐标。
    【解决方案2】:

    经过大量挖掘(包括这篇文章),我找不到我喜欢的解决方案。此处接受的答案并没有按照 OP 的标题阅读,而且我能找到的最佳解决方案无疑会导致跳动的元素。然后,它击中了我:让元素“固定”,检测何时发生水平滚动,并将其切换为绝对定位。这是生成的代码:

    View it as a Code Pen.

    HTML

      <div class="blue">
        <div class="red">
        </div>
      </div>
    

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

    【讨论】:

    • 这是迄今为止找到的最佳解决方案。即使在此解决方案发布 4 年后。似乎我们必须解决这个问题,只要 Sticky 没有在所有浏览器中得到适当的支持
    • 2 年多后,仍然没有修复...可提供可悲的 CHROME 错误报告 here
    【解决方案3】:

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

    HTML

    <div id="footer-outer">
    <div id="footer">
        Footer text.
    </div><!-- end footer -->
    </div><!-- end footer-outer -->
    

    CSS

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

    CoffeeScript / JavaScript

    (使用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"} )
    

    编译成:

    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

    ...
    </div><!-- end footer -->
    <div id="footer-stretch"></div>
    </div><!-- end footer-outer -->
    

    CSS

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

    请注意,要使 #footer-stretch div 正常工作,直到 body 元素(可能还有 html 元素 - 不确定)的所有父元素都必须具有固定高度(在这种情况下,高度 = 100%)。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2011-06-16
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2021-08-08
      • 1970-01-01
      相关资源
      最近更新 更多