CSS 应用 position: fixed 时是否可以保持父元素的宽度?
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/16018520/
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
Is it possible to keep the width of the parent element when position: fixed is applied?
提问by George Katsanos
When we apply position:fixed
to an element, it's taken out of the normal flowof the document, therefore it doesn't respect it's parent's element width.
Are there ways to make it inherit it's parent's width if this is declared as a percentage? (working use case below)
当我们应用position:fixed
到一个元素时,它被从文档的正常流中取出,因此它不尊重它的父元素宽度。如果将其声明为百分比,是否有办法使其继承其父级的宽度?(下面的工作用例)
let widthis = $('.box').width();
$('.dimensions').text(`width is ${widthis}`);
$('button').on('click', function() {
$('.box').toggleClass('fixed');
let widthis = $('.box').width();
$('.dimensions').text(`width is ${widthis}`);
});
.container {
max-width: 500px;
height: 1000px;
}
.box {
background-color: lightgreen;
}
.fixed {
position: fixed;
}
.col-1 {
border: 1px solid red;
float: left;
width: 29%;
}
.col-2 {
border: 1px solid pink;
float: left;
width: 69%;
}
<link href="https://cdnjs.cloudflare.com/ajax/libs/meyer-reset/2.0/reset.css" rel="stylesheet"/>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<button>Click this to toggle position fixed for the left column</button>
<div class="container">
<div class="col-1">
<div class="box">
fixed content<br>
<span class="dimensions"></span>
</div>
</div>
<div class="col-2">
some other content
</div>
</div>
回答by Philll_t
This is an interesting challenge. To approach this, we should first understand what fixed
actually does.
这是一个有趣的挑战。为了解决这个问题,我们应该首先了解fixed
实际的作用。
Understand Fixed
了解固定
Unlike absolute
, fixed
doesn't position itself from its closest relativeparent. Instead, fixed
positions itself relative to the viewport. The viewport will always stay fixed, which is why you get the effect that you do.
与 不同absolute
, ,fixed
不会从其最近的相对父级定位自己。相反,fixed
相对于 viewport 定位自身。视口将始终保持固定,这就是您获得效果的原因。
That being said, whenever you "inherit" any width it will be respective to the viewport. So it does us no good when we're trying set the width of our target element to the width of it's parent.
话虽如此,每当您“继承”任何宽度时,它都会与 viewport 相关。因此,当我们尝试将目标元素的宽度设置为其父元素的宽度时,这对我们没有好处。
Learn more about the different behaviors of position.
详细了解position的不同行为。
Quick Solutions
快速解决方案
There are two approaches to fix this.
有两种方法可以解决这个问题。
Pure CSS
纯 CSS
We can use pure CSSto fix this problem, but we would need to know the width in advance. Suppose that its parent element is 300px;
我们可以使用纯 CSS来解决这个问题,但我们需要提前知道宽度。假设它的父元素是300px;
.parent{
width: 300px;
}
.parent .fixed_child{
position: fixed;
width: 300px;
}
JS
JS
Now with mobile devices, we don'treally havethe luxury of having set widths, especially anything over 300px
. Using percentages won't work either, since it will be relative to the viewport and not the parent element. We can use JS, in this case with jQuery to achieve this. Lets take a look at a functionthat will always set the width of the parent at the given moment:
现在,随着移动设备,我们并不真正拥有具有奢侈品集宽度,尤其是上什么300px
。使用百分比也不起作用,因为它将相对于视口而不是父元素。我们可以使用 JS,在这种情况下使用 jQuery 来实现这一点。让我们看看一个函数,它总是在给定时刻设置父级的宽度:
function toggleFixed () {
var parentwidth = $(".parent").width();
$(".child").toggleClass("fixed").width(parentwidth);
}
css:
css:
.fixed{
position:fixed;
}
View in CodePen
在CodePen 中查看
Dynamic Widths
动态宽度
That's fine and dandy, but what happens if the width of the window changeswhile the user is still on the page, changing the parent element with this? While the parent may adjust its width, the child will stay the set width that the function set it. We can fix this with jQuery'sresize()
event listener. First we'll need to split the function we created into two:
这很好,但如果当用户仍在页面上时窗口的宽度发生变化,从而更改父元素,会发生什么?虽然父级可以调整其宽度,但子级将保持函数设置的宽度。我们可以使用jQuery 的resize()
事件监听器来解决这个问题。首先,我们需要将我们创建的函数一分为二:
function toggleFixed() {
adjustWidth();
$(".child").toggleClass("fixed");
}
function adjustWidth() {
var parentwidth = $(".parent").width();
$(".child").width(parentwidth);
}
Now that we've separated each part, we can call them individually, we'll include our original button method that toggles the fixed and width:
现在我们已经分离了每个部分,我们可以单独调用它们,我们将包含我们原来的按钮方法来切换固定和宽度:
$("#fixer").click(
function() {
toggleFixed();
});
And now we also add the resize event listener to the window:
现在我们还将调整大小事件侦听器添加到窗口中:
$(window).resize(
function() {
adjustWidth();
})
View in CodePen
在CodePen 中查看
There! Now we have a fixed element who's size will be adjusted when the window is resized.
那里!现在我们有一个固定元素,当窗口调整大小时,它的大小将被调整。
Conclusion
结论
We've tackled this challenge by understanding fixed
position and it's limitations. Unlike Absolute, fixed
only relates to the view port and therefore cannot inherit its parent's width.
我们通过了解fixed
位置及其局限性来应对这一挑战。与 Absolute 不同,fixed
仅与视口相关,因此不能继承其父级的宽度。
To solve this, we need to use some JS magic, which didn't take very much with jQuery, to achieve this.
为了解决这个问题,我们需要使用一些 JS 魔法来实现这一点,这在 jQuery 中不需要太多。
In some cases, we need a dynamic approach with scaling devices of varying widths. Again, we took the JS approach.
在某些情况下,我们需要一种动态方法来缩放不同宽度的设备。同样,我们采用了 JS 方法。
回答by egon12
You can use width:inherit
. This will make it listen to parent. I test it and it works in Firefox.
您可以使用width:inherit
. 这将使它听父母。我测试了它,它在 Firefox 中工作。
回答by Michael Rader
The width is changing because the object when static is receiving its percentage width from its parent. Once you set the object to fixed it is no longer in flow and resizes.
宽度正在变化,因为静态时对象正在从其父级接收其百分比宽度。一旦您将对象设置为固定,它就不再流动并调整大小。
You're gonna have to set a size to your nav menu on its own and not expect the element to get its width from the parent.
您将不得不自行设置导航菜单的大小,而不是期望元素从父元素获取其宽度。
.nav {
position: fixed;
width: 20%;
border: 1px solid green;
padding: 0px;
list-style-type:none;
background:lightblue;
}
回答by khoekman
Hi you could also use jquery to keep the width. For example:
嗨,您也可以使用 jquery 来保持宽度。例如:
jQuery(function($) {
function fixDiv() {
var $cache = $('#your-element');
var $width = $('#your-element').parent().width();
if ($(window).scrollTop() > 100) {
$cache.css({
'position': 'fixed',
'top': '10px',
'width': $width
});
} else {
$cache.css({
'position': 'relative',
'top': 'auto'
});
}
}
$(window).scroll(fixDiv);
fixDiv();
});
回答by Zach Saucier
This is likely because of some default margin or padding on the <html>
or <body>
element. When it's static, it sizes based on the <body>
's width at the time, but when it changes to position:fixed
it's sized in respect to the viewport.
这可能是因为<html>
或<body>
元素上的某些默认边距或填充。当它是静态的时,它的大小基于当时<body>
的宽度,但是当它更改为position:fixed
它时,它的大小是相对于视口的。
As such, removing that default margin/padding should fix the problem (in my experience body { margin:0; }
fixes it) as should changing the sizing when it is fixed (like width:calc(n% - 5px);
).
因此,删除默认的边距/填充应该可以解决问题(根据我的经验可以body { margin:0; }
修复它),就像在修复时更改大小一样(如width:calc(n% - 5px);
)。
回答by pldg
As someone already suggest, using javascript is the best solution.
正如有人已经建议的那样,使用 javascript 是最好的解决方案。
Without jQuery.
没有jQuery。
const parentElement = document.querySelector('.parent-element');
const fixedElement = document.querySelector('.fixed-element');
// get parent-element width when page is fully loaded
// and change fixed-element width accordingly
window.addEventListener('load', changeFixedElementWidth);
// get parent-element width when window is resized
// and change fixed-element width accordingly
window.addEventListener('resize', changeFixedElementWidth);
function changeFixedElementWidth() {
const parentElementWidth = parentElement.getBoundingClientRect().width;
fixedElement.style.width = parentElementWidth + 'px';
}
回答by Simke Nys
A workaround might be: left:8px; right:0; width:18%;
in the CSS for the nav.
Not the best solution though.
解决方法可能是:left:8px; right:0; width:18%;
在导航的 CSS 中。虽然不是最好的解决方案。
回答by Naveen Attri
Add width:auto;
to the element with position:fixed;
to make its width equal to the width of its parent element.
添加width:auto;
到元素position:fixed;
以使其宽度等于其父元素的宽度。