position:sticky is said to be working in firefox but I'm not seeing my sidebar stick.
My html looks like this:
<div class="wrap">
<div class="sticky">side </div>
<div class="content">content <div>
<div>
My css:
.content{
height: 2000px;
overflow: hidden;
}
.sticky{
position: sticky;
width: 200px;
float: left;
}
As I scroll down the sidebar scrolls with the content. It doesn't stick. Anyone know what could be the issue?
I have the same issue in 2020 - this post pops up first in google but none of the answers helped me.
The actual problem was that sticky doesn't play well with the parent element being display: flex.
References:
- position: sticky, works in Chrome but not in Firefox
- https://bugzilla.mozilla.org/show_bug.cgi?id=1488080
It sticks if you specify a top value:
.sticky{
position: -webkit-sticky; /* for safari */
position: sticky;
width: 200px;
float: left;
top: 10px;
}
fiddle
Position sticky also don't work if the parent element is set to overflow: hidden because it can't calculate the height correctly.
position: sticky does not work on table elements such as tr as well as some others.
A workaround is to wrap whatever you want sticky inside a span element.
<style>.sticky span {position: -webkit-sticky; position: sticky; top: 0;}</style>
<td class='sticky' valign='top' width='200'>
<span>
(table contents)
</span>
</td>
Related answers and solutions
I was able to fix it by using 'display: table-cell'.
My problem concerned a thead that didn't want to stick anymore on Firefox as soon as I fixed the same problem in Chrome by using display: block or inline-block.
I had same issue, even though I set a top value, the sticky element would not stick. The solution was to set a value also for height...
.sticky-top {
position: -webkit-sticky;
position: sticky;
z-index: 1020;
top: 86px;
height: min-content;
}
Adding height: min-content; fixed my issue on firefox
To anyone still having this trouble:
Firefox uses the parent display as a rendering condition
So try making the child display: inline and parent display: inline
Remember that you still need to check the parent position and size for all browsers.
Sticky is great but it is very case-specific use.
I found the alt way with very simple but works.
position:fixed;
width:100%;
top:0;
z-index:1; /*depends on your elements*/
Work on every browsers, no bulls. If your topnav has a lot of elements, the sticky wil not working, I beleive it's because of some overflow:hidden;
In my case, the sticky element was taking a display: table; property, which when I changed to display: block;, the sticky was fixed in Firefox. So, have a look at the display property before considering other fixes.
Just stumbled on this so it seems to still be an issue in 2022. I'll leave here what I had that allowed me to clearly replicate the OP and what I added to mitigate it.
div {
position: sticky;
- display: inline;
+ display: block;
+ height: 100px;
z-index: 2;
top: 0;
}
Related
I'm using CSS position: sticky to stick some elements to my page. I'm using <div>s to produce a grid-like structure (<table>s aren't appropriate to my use case). Please note that this is specifically a position: sticky question - I'm not looking for a Javascript solution, and I believe that position: sticky should work as desired based on the spec and the behaviour in other browsers.
I need to stick a row for vertical scrolling, and the first cell in that row for horizontal scrolling. If I use position: sticky; left: 0; on the first cell without sticking the row, the cell sticks to the left just fine. However, in Safari if I use eg.
.row {
position: sticky;
top: 10px;
width: ...
}
.cell {
position: sticky;
left: 0;
width: ...
}
the row sticks when vertically scrolling as desired but the cell does not stick when horizontally scrolling.
The code behaves as desired in Chrome and Firefox, and in an iframe in Safari.
Here's some code for a minimal example:
CSS:
.row {
position: -webkit-sticky;
position: sticky;
top: 10px;
white-space: nowrap;
width: 2000px;
z-index: 30;
}
.cell {
display: inline-block;
width: 100px;
}
.sticky {
position: -webkit-sticky;
position: sticky;
left: 0;
font-weight: bold;
}
HTML:
<div class="row">
<div class="cell sticky">Sticky</div>
<div class="cell">Content</div>
<div class="cell">Content</div>
...
</div>
Uploaded files here (can't use codepen/jsfiddle as they load into an iframe):
https://qcn.github.io/minimal_sticky.html Minimal example: doesn't work in Safari, works in Chrome/Firefox
https://qcn.github.io/minimal_sticky_iframe.html The same minimal example loaded into an iframe: does work in Safari!
Another interesting thing I noticed was that if I scroll the page horizontally and then refresh, the sticky cell renders at the left of the viewport, and then scrolls normally in that position (ie. it still doesn't stick, but it knows where it should have been on page load!). This and the fact that the behaviour works inside an iframe and in other browsers makes me suspect it's a browser bug, but I'm unable to find other references to it.
Try adding a unit. It worked when I wanted to sticky a nested header to the top. I haven't tried your horizontal situation. Hope it helped.
left: 0px; instead of left: 0;
This appears to be an instance of this bug: https://bugs.webkit.org/show_bug.cgi?id=106062
I worked around my issue by wrapping the page in a scrolling div to contain it, rather than using viewport scroll. Not ideal but it appears to be a browser bug.
I finally found a solution to this!!!
using display: contents;
https://css-tricks.com/get-ready-for-display-contents/
Disclaimer - I understand there exists questions around fixed elements in safari, and fixed elements weren't supported, but now are and so forth. However I can't find a question that addresses this exact question.
Given the simplest of fixed sidebars, something like:
.sidebar {
position: fixed;
top: 10px;
right: 10px;
}
And a relatively long page, with input elements.
When an input element is focused, any fixed element becomes absolute - I understand the why, safari is trying to declutter the viewport - thats fine, but not always appropriate. I ask that I get to choose the best experience for the user (i know best naturally).
So the Question..
Is there any way to leave fixed elements as fixed even when input elements are focused?
I have attempted to do a bit of $(window).on('scroll', magic and position elements manually on scroll, but its quite jittery on the ipad.
Safari has supported position: fixed since at least version 9.2, but if you're seeing difficult issues, you can fully create the fixed position effect by making the document element and body full screen and then using absolute positioning. Scrolling then occurs in some main container element rather than the body. Your "fixed" elements can exist anywhere in the markup using this method.
jsfiddle here
html,
body,
.mainContainer {
height: 100%;
width: 100%;
overflow: hidden;
margin: 0;
}
.mainContainer {
overflow: auto;
}
.fixed {
position: absolute;
bottom: 20px;
left: 20px;
}
In order to achieve the effect you desire you need to change your approach to the layout. Instead of positioning the sidebar with position:fixed you need to use position:absolute within a position:relative container that is set to the height of the viewport within that position:relative container you need another div that uses overflow-y: scroll and -webkit-overflow-scrolling : touch
Caveat: I generally avoid using position fixed on tablet & mobile if possible although the browser support is there, in my experience it'll be janky and javascript solutions leave a lot to be desired, my first response would be to challenge the pattern with the designer. If I'm given designs that include a position fixed element when there are input elements, I'm more likely to seek a design solution than a development one as the focus issues you're describing are difficult to circumvent and maintain a quality user experience.
THE MARKUP:
<div class="outer">
<div class="sidebar">
<ul>
<li>Dummy list nav or something</li>
</ul>
</div>
<div class="container">
<input type="text" />
<!-- I added 10000 inputs here as a demo -->
</div>
</div>
THE CSS:
html,body{
-webkit-overflow-scrolling : touch !important;
overflow: auto !important;
height: 100% !important;
}
.outer {
position: relative;
overflow: hidden;
/* I'm using Viewport Units here for ease, but I would more likely check the height of the viewport with javascript as it has better support*/
height: 100vh;
}
.sidebar {
position: absolute;
top: 10px;
right: 10px;
/*added bg colour for demo */
background: blue;
}
.container {
height: 100vh;
overflow-y: scroll;
-webkit-overflow-scrolling: touch
}
input {
display: block;
}
Here's a CodePen for you to open in your simulator (presentation view):
https://codepen.io/NeilWkz/full/WxqqXj/
Here's the editor view for the code:
https://codepen.io/NeilWkz/pen/WxqqXj
It works in chrome , and not in ff/opera.
Demo here: http://booksnearby.in/browse_items.php . The 'location: Dhoolsiras Village, delhi' line 'hangs' in the middle. I am trying to make it stay at the bottom of its container.
For this I tried
Child span tag- {
bottom: -5px;
font-size: 11px;
left: 115px;
line-height: 20px;
position: absolute;
}
Parent:- element.style {
height: 100%;
position: relative;
}
But it doesn't work, except in chrome. Please help
Thanks.
Do you have to use a table? Because your problems come from the td element's height. Tables have the worst cross browsers support out of all the html elements :)
Is it possible to change the structure to use div elements instead?
OR you could give the position: relative to your .listtd instead of the div (which means remove the position property from the div). This solution will do the trick.
Is there anyway for an absolute positioned child to expand to fill its relative positioned parent? (The height of parent is not fixed)
Here is what i did and it is working fine with Firefox and IE7 but not IE6. :(
<div id="parent">
<div id="child1"></div>
</div>
#parent { position: relative; width: 200px; height:100%; background:red }
#child1 { position: absolute; top: 0; left: 200px; height: 100%; background:blue }
That's easy. The trick is setting top: 0px and bottom: 0px at the same time
Here's the working code
html, body {
width: 100%;
height: 100%;
overflow: hidden;
}
#parent {
display: block;
background-color: #ff0;
border: 1px solid #f00;
position: relative;
width: 200px;
height: 100%;
}
#child1 {
background-color: #f00;
display: block;
border: 1px solid #ff0;
position: absolute;
left: 200px;
top: 0px;
bottom: 0px;
}
Check out a working example here http://jsfiddle.net/Qexhh/
If I remember correctly there is a bug with how IE6 handles div height. It will only create the div to the height needed to contain the content within it when height is set to 100%. I would recommend two approaches:
Don't worry about supporting IE6 as it is a dead browser anyway
If that doesn't work, use something like jQuery to get the height of the parent div and then set the child div to that height.
fake it by setting the backgrounds to be the same colour so no-one notices the difference
You can achieve this with setting both the top and bottom attributes of the child.
See how this is done
At the bottom of that article, there is a link to Dean Edwards' IE7 (and IE8) js library that you should include for IE6 visitors. It is a JS library that actually MAKES IE6 behave like IE7 (or 8) when you include it. Sweet!
Dean Edwars' IE7 and 8 JS libraries
As far as I know, there is no way of expanding a parent element around an absolutely positioned child element. By making the child element absolutely positioned your are removing it from the regular flow of page items.
I recently built a 2-column website where the right column was absolutely positioned but the left column was not. If the left column had less content and a smaller height than the right column, the page would cut off the right column since it was absolutely positioned.
In order to resolve this, I had to determine if the height of the right column was greater than the height of the left column and if so set the height of the parent div height to the greater of the two.
Here is my jQuery solution. I'm not much of a coder so feel free to tweak this:
jQuery(function(){
var rightColHeight = jQuery('div.right_column').height();
var leftColHeight = jQuery('div.left_column').height();
if (rightColHeight > leftColHeight){
jQuery('.content_wrap').height(rightColHeight+'px');
}
});
I have placed an absolutely positioned element (header) after relatively positioned element (body content). Due to some reason and this works fine in all the browsers except IE8.
The header is overlapping the content element with not positioned at its absolute position.
The css rules I have used:
#bodyContent{
clear: both;
display: table;
width: 920px;
margin-top: 173px;
_margin-top: 178px;
position: relative;
}
#headerContainer {
position: absolute;
top: 0px;
left:0px;
}
The header part is rendering from the content element postition with space in its position.
Is this the bug in IE8? Can anyone help me sort out this issue?
This sounds like an old IE7 bug.. can you place an element between them? That fixed it for me.
I've also had similar problems. I used the float command which solved the issue. Try float: left; in #headerContainer