CSS 位置元素垂直固定,绝对水平
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/3303173/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Position element fixed vertically, absolute horizontally
提问by Jimmy
Here's what I'm trying to accomplish:
这是我想要完成的:
I need a button which is positioned a certain distance from the right side of a div, and is always that same distance from the side of the div no matter the size of the viewport, but will scroll with the window.
我需要一个按钮,它位于距 div 右侧一定距离的位置,并且无论视口大小如何,距 div 侧面的距离始终相同,但会随窗口滚动。
So it is x pixels from the right side of the div at all times, but y pixels from the top of the view port at all times.
因此,它始终距离 div 右侧的 x 像素,但始终距离视口顶部的 y 像素。
Is this possible?
这可能吗?
采纳答案by ScottS
Position Fixed Element Horizontally Based Off Another Element
基于另一个元素水平定位固定元素
(Disclaimer Note: The solution offered hereis not technically "absolute horizontally" as the question title stated, but did achieve what the OP originally wanted, the fixed position element to be 'X' distance from the right edge of another but fixed in its vertical scroll.)
(免责声明:此处提供的解决方案在技术上并不是问题标题所述的“绝对水平”,但确实实现了 OP 最初想要的,固定位置元素与另一个元素的右边缘的距离为“X”,但固定在其垂直滚动。)
I love these types of css challenges. As a proof of concept, yes, you can get what you desire. You may have to tweak some things for your needs, but here is some sample html and css that passed FireFox, IE8 and IE7 (IE6, of course, does not have position: fixed
).
我喜欢这些类型的 css 挑战。作为概念证明,是的,你可以得到你想要的。您可能需要根据自己的需要调整一些内容,但这里有一些通过 FireFox、IE8 和 IE7(当然,IE6 没有position: fixed
)的示例 html 和 css 。
HTML:
HTML:
<body>
<div class="inflow">
<div class="positioner"><!-- may not be needed: see notes below-->
<div class="fixed"></div>
</div>
</div>
</body>
CSS (borders and all dimensions for demonstration):
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;
}
The keyis to not set the left
or right
at all for the horizontal on the div.fixed
but use the two wrapper divs to set the horizontal position. The div.positioner
is notneeded if the div.inflow
is a fixed width, as the left margin of the div.fixed
can be set to known width of the container. However, if you desire than container to have a percentage width, then you will need the div.positioner
to push the div.fixed
to the right side of the div.inflow
first.
关键是不要设置left
或根本不right
为水平设置,div.fixed
而是使用两个包装器 div 设置水平位置。的div.positioner
是不需要的,如果div.inflow
是一个固定的宽度,随着左边距div.fixed
可以设置在容器的已知宽度。但是,如果您希望容器具有百分比宽度,那么您需要将div.positioner
推div.fixed
到第一个的右侧div.inflow
。
Edit:As an interesting side note, when I set overflow: hidden
(should one need to do that) on the div.inflow
had no effecton the fixed position div being outside the other's boundaries. Apparently the fixed position is enough to take it out of the containing div's context for overflow
.
编辑:作为一个有趣的方面说明,当我设置overflow: hidden
(应一个需要这样做)的div.inflow
有没有影响的固定位置的div被对方的边界之外。显然,固定位置足以将其从包含 div 的上下文中取出overflow
。
回答by Grinn
After much digging (including this post) I couldn't find a solution that I liked. The Accepted Answer here doesn't do what the OP's title read, and the best solutions I could find admittedly resulted in jumpy elements. Then, it hit me: Have the element be "fixed", detect when a horizontal scroll occurs, and switch it to be absolutely positioned. Here is the resulting code:
经过大量挖掘(包括这篇文章),我找不到我喜欢的解决方案。此处接受的答案与 OP 的标题所读的内容不同,我可以找到的最佳解决方案无可否认会导致跳跃元素。然后,它击中了我:让元素“固定”,检测何时发生水平滚动,并将其切换为绝对定位。这是结果代码:
HTML
HTML
<div class="blue">
<div class="red">
</div>
</div>
CSS
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
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");
}
});
回答by Waz
I arrived here looking for a solution to a similar problem, which was to have a footer bar that spans the width of the window and sits below the (variable height and width) content. In other words, make it appear that the footer is "fixed" with respect to its horizontal position, but retains its normal postion in the document flow with respect to its vertical position. In my case, I had the footer text right-aligned, so it worked for me to dynamically adjust the width of the footer. Here is what I came up with:
我来到这里寻找类似问题的解决方案,即有一个跨越窗口宽度并位于(可变高度和宽度)内容下方的页脚栏。换句话说,使页脚看起来相对于其水平位置“固定”,但相对于其垂直位置保留其在文档流中的正常位置。就我而言,我将页脚文本右对齐,因此我可以动态调整页脚的宽度。这是我想出的:
HTML
HTML
<div id="footer-outer">
<div id="footer">
Footer text.
</div><!-- end footer -->
</div><!-- end footer-outer -->
CSS
CSS
#footer-outer
{
width: 100%;
}
#footer
{
text-align: right;
background-color: blue;
/* various style attributes, not important for the example */
}
CoffeeScript / JavaScript
CoffeeScript / JavaScript
(Using prototype.js).
(使用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"} )
which compiles into:
编译成:
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"
});
});
This works nicely in FireFox, and pretty well in Chrome (it's a little jittery); I haven't tried other browsers.
这在 FireFox 中运行良好,在 Chrome 中运行良好(有点紧张);其他浏览器我没试过。
I also wanted any spare space below the footer to be a different colour, so I added this footer-stretch
div:
我还希望页脚下方的任何空闲空间都是不同的颜色,所以我添加了这个footer-stretch
div:
HTML
HTML
...
</div><!-- end footer -->
<div id="footer-stretch"></div>
</div><!-- end footer-outer -->
CSS
CSS
#footer-outer
{
height: 100%;
}
#footer-stretch
{
height: 100%;
background-color: #2A2A2A;
}
Note that for the #footer-stretch div to work, all the parent elements up to the body element (and possibly the html element - not sure) must have a fixed height (in this case, height = 100%).
请注意,要使 #footer-stretch div 起作用,直到 body 元素(可能还有 html 元素 - 不确定)的所有父元素都必须具有固定的高度(在这种情况下,高度 = 100%)。