When we apply position:fixed
to an element, it\'s taken out of the normal flow of the document, therefore it doesn\'t respect it\'s parent\'s element width.
Are the
Hi you could also use jquery to keep the width. For example:
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();
});
A workaround might be: left:8px; right:0; width:18%;
in the CSS for the nav.
Not the best solution though.
Add width:auto;
to the element with position:fixed;
to make its width equal to the width of its parent element.
You can use width:inherit
. This will make it listen to parent. I test it and it works in Firefox.
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.
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);
).
This is an interesting challenge. To approach this, we should first understand what fixed
actually does.
Unlike absolute
, fixed
doesn't position itself from its closest relative parent. Instead, fixed
positions itself relative to the viewport. The viewport will always stay fixed, which is why you get the effect that you do.
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.
Learn more about the different behaviors of position.
There are two approaches to fix this.
We can use pure CSS to fix this problem, but we would need to know the width in advance. Suppose that its parent element is 300px;
.parent{
width: 300px;
}
.parent .fixed_child{
position: fixed;
width: 300px;
}
Now with mobile devices, we don't really have the 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 function that will always set the width of the parent at the given moment:
function toggleFixed () {
var parentwidth = $(".parent").width();
$(".child").toggleClass("fixed").width(parentwidth);
}
css:
.fixed{
position:fixed;
}
View in CodePen
That's fine and dandy, but what happens if the width of the window changes while 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's resize()
event listener. First we'll need to split the function we created into two:
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
There! Now we have a fixed element who's size will be adjusted when the window is resized.
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.
To solve this, we need to use some JS magic, which didn't take very much with jQuery, to achieve this.
In some cases, we need a dynamic approach with scaling devices of varying widths. Again, we took the JS approach.