IE 10 & 11 make fixed backgrounds jump when scrolling with mouse wheel - css

When you scroll with the mouse wheel in Windows 8 the fixed background image bounces around like crazy. This only affects IE 10 and IE 11. This affects elements with position:fixed as well.
Here is an example with a fixed background-image:
http://www.catcubed.com/test/bg-img-fixed.html
Here is example code:
#section{
position: fixed;
top:0;
left:0;
background-color:#eee;
background-position: top left;
background-image: url("images/7.png");
background-size: auto;
background-repeat: no-repeat;
z-index: 10;
}
Is there a solution to keep the background still in IE 10 and 11?

I know it is a bit late for an answer but I've had the same problem and was able to fix it by adding these attributes to my css file
html{
overflow: hidden;
height: 100%;
}
body{
overflow: auto;
height: 100%;
}
From the comments:
This solution stops scroll events from firing on the window, so do be careful if you're using anything that relies on such events firing. codepen.io/anon/pen/VawZEV?editors=1111 ( overflow: hidden, scroll events don't work) codepen.io/anon/pen/PNoYXY?editors=1111 ( overflow: auto, scroll events fire) - Dan Abrey
So this might cause some problems in your projects. But I don't see another way to workaround this bug in IE.

This looks like a z-index bug, try adding z-index: 1.
Looking into this, I've found the best way to debug is to:
Create a simple element at the top of the page, e.g.
<style>#test {position: fixed; background: red; top: 0; left: 0; width: 4em}</style>
<div id="test">Test</div>
In all the above cases, this works correctly, and the scroll is smooth. So this proves it can be done! Now slowly add your properties back in, until you are able to get the element with position fixed to work in the context of your site.
I then found that adding a z-index to the fixed items resolved the issue. (e.g. z-index: 1)
I also discovered that once a position is set on a child element, the bug presents it's self from that point down/onwards.
So you need to ensure none of the child elements have a position set,
or if they do, you explicitly set a position on each child.
E.g.
<!-- Works -->
<div style="position: fixed;">
<div>Nice</div>
<div>Wicked</div>
<div>Cool</div>
</div>
<!-- Element with position: relative, experiences the bug -->
<div style="position: fixed;">
<div style="position: relative;">sad</div>
<div>sad</div>
<div style="position: fixed;">happy</div>
</div>
It's fixable, but will require some tweaking!

Here is a workaround (tested on Windows 8.1):
Move the "background" CSS property to the BODY element. Currently it is on the DIV element with id="filler". Here is the resulting CSS:
body {
font-family: Helvetica, Arial, sans-serif;
background: #fff url(blue-kitty.jpg) no-repeat fixed center 100px;
}
#filler {
text-align: center;
}
.big-margin {
margin-top: 500px;
}

try to turn off smooth scrolling option.
Internet Options - Advenced Tab - Use Smooth Scrolling
it's like rendering bug.... MS IE team is investigating....

just simply define body container to relative.
<style>
body
{
position: relative;
}
</style>

The fix in my case was to simply remove the z-index property from the element that has position:fixed, IE then stopped the strange flickering.
(disabling smooth scrolling on IE options worked while having he z-index property but that's not a solution since users would most likely have it on by default).

Related

How to stop mobile safari from setting fixed positions to absolute on input focus?

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

Nested position:fixed clipped with overflow:auto, but only in Webkit on Mac

I have two DIVs, main and header. Both are position: fixed. The top of the header places it above (in the negative top margin of) the main DIV, which has overflow: auto to allow for scrolling. The header is visible on all modern desktop browsers I've tested, except Chrome and Safari on Mac, where it's clipped (hidden).
This seems like a bug, but I don't understand why it would only affect Webkit-based browsers on OS X.
Here's the code...
HTML:
<div id="main">
<div id="header">Partially clipped in Chrome and Safari on Mac.</div>
Main content goes here.<br/>
Main content goes here.<br/>
...
</div>
CSS:
#main {
position: fixed;
top: 50px;
height: 100px;
overflow: auto;
}
#header {
position: fixed;
top: 42px;
}
Live example here.
I found a few similar reports and suggestions about using -webkit-transform: translateZ(0). Interestingly, that doesn't fix it, but it does make the bug occur on Windows. Example here.
Any ideas?

z-index chrome bug

I'm experiencing a really annoying bug that seems to only happen on Windows and OS X: the z-index of an element whose parent has fixed position doesn't work on Chrome! I converted my odd situation to a simple code:
html:
<div id="mask">
</div>
<div id="box">
<div class="below-mask circle">
should be below the mask
</div>
<div class="above-mask circle">
should be above the mask
</div>
</div>​
css:
body {
font-family: Verdana;
font-size: 9px;
margin: 0px;
}
#box {
position: fixed;
}
#mask {
position: absolute;
left: 0px;
top: 0px;
background-color: rgba(0, 0, 0, 0.5);
width: 100%;
height: 100%;
z-index: 9998;
}
.circle {
position: relative;
background-color: rgba(255, 204, 0, 0.75);
border-radius: 75px;
line-height: 150px;
margin: 50px;
text-align: center;
width: 150px;
height: 150px;
}
.above-mask {
z-index: 9999;
}
.below-mask {
z-index: 9997;
}​
sandbox: http://jsfiddle.net/gibatronic/umbgp/
I tested on Internet Explorer 9, Firefox 15, Opera 12.02 and Safari 5.1.7 on OS X and Windows and all of them displayed as expected.
I also tested on Ubuntu 12.10 and it worked just fine for every browser including Chrome!
I even tested on Kindle 4 browser and it worked!
I wonder if anyone knows any kind of fix to workaround this issue!
one800higgins's answer is along the right lines. The real answer is that on mobile WebKit and Chrome 22+, position: fixed always creates a new stacking context, even when z-index is auto. So the stacking context hierarchy looks like this:
document root (z-index 0)
#mask (z-index 9998)
#box (z-index 0)
.above-mask (z-index 9999)
.below-mask (z-index 9997)
That means that 9998 is never compared with 9999 or 9997 to determine stacking order. Instead, 9999 is compared with 9997 to determine which of .above-mask and .below-mask is further in front, and then once everything inside #box is stacked in that context, it's treated as a single layer at z-index 0 which gets stacked behind #mask at z-index 9998.
This also explains why #TheNextBillGates's answer of moving #mask inside #box works - because then #mask is in the same stacking context as .above-mask and .below-mask. I highly recommend the above link for more comprehensive details, and you should also see the announcement for the stacking change for fixed elements in Chrome.
I just came across this bug, and its still happening in Google Chrome v26. I could set the z-index as high as I wanted to from code or Chrome's CSS editor and it made no difference (and the element's position was set to absolute). The same z-index setting was working as expected in Firefox and even IE8-IE10. When I switched the parent element from position:fixed to position:absolute then the child element's z-index worked fine in Chrome.
If you move the #mask inside of the #box it works just fine.
<div id="box">
<div id="mask"> </div>
<div class="below-mask circle">should be below the mask</div>
<div class="above-mask circle">should be above the mask</div>
</div>
Here's a fiddle http://jsfiddle.net/TheNextBillGates/jKm4b/
Not sure why this is just yet.
Assign a z-index to your fixed div. That should cause chrome to respect the z-index values for all it's children as well.
The multiple z-index stacks is unfortunate and confusing in my opinion, however you may be able to solve this without changing your html structure if you raise the z-index of any of the target element's parents. Try to find a parent element that is a sibling of the troublesome element overlapping your content. Apply this styling:
position: relative; z-index: [# higher than overlapping element's z-index];
Your milage may vary depending on your project, however this solution worked for my project.
I think its because its not at the bottom of the page like modal windows are suppose to be. Easy fix is to just grab all of the modal windows and throw them into a div before the ending body tag. Example below fixes every chrome issue i have.
$('body').append('<div id="modelContainer" />');
$('.modal').each(function() {
$(this).appendTo('#modelContainer');
})
Change or remove the position: fixed on #box, and you're set.
jsFiddle

large image causes browser scroll

I'm having trouble with a large image on my page, I can't seem to avoid it causing a scroll on certain browsers. So far I can only see it on Safari, but my friend apparently also see's it on Chrome.
All I'm doing, is positioning an image inside its container absolutely, and then moving it right, so that it actually outside of the container and wrapper. The problem is, that its quite a large image, so in some browsers you are able to scroll to the right revealing the rest of the image. Here's the code.
<html>
<head>
<style>
body{
background: aqua;
margin: 0;
overflow-x: hidden;
}
#wrapper{
background: #fff;
width: 960px;
height: 100%;
margin: 0 auto;
}
#content{
width: 960px;
height: 500px;
background: yellow;
position: relative;
}
#image{
position: absolute;
bottom: 0;
right: -320px;
z-index: 0;
width: 1210px;
height: 468px;
background: red;
}
</style>
</head>
<body>
<div id="wrapper">
<div id="content">
<div id="image"></div>
</div>
</div>
</body>
</html>
and heres a fiddle that deomonstrates it: http://jsfiddle.net/alsweeet/5mqHf/
Adding the overflow-x: hidden to the body style seems to solve the problem in most browsers, but not safari. You will see that I have not added this yet into the fiddle demo, and once you add it, you won't be able to scroll left or right anymore, which is the effect I'm trying to achieve cross browser.
I would sure appreciate some advice on this one. I'm sure there's probably a better way of doing this than absolutely positioning it.
Thanks!
Alsweeet
edit: problem IS occurring on Chrome also, the scroll bar is hidden, but you are still able to scroll sideways. Still works fine in Fire fox though.
edit: heres a screen shot to help explain what i'm trying to achieve without any side scroll. The red box is the box which is causing the side scroll. You can see that the red box is outside of the 960 wrapper.
this is what you are looking for?
DEMO
http://jsfiddle.net/5mqHf/4/
overflow-x: is not fully cross browser compatible, try using overflow:hidden;, as long as you don't need to scroll vertical on the element then that will never cause you an issue.
A workaround to have overflow-y on an element and restrict the overflow-x on another element is this fiddle.
http://jsfiddle.net/5mqHf/7/ - Fix for image position
A consideration for this is that if you are going to scroll vertically, when looking at the width of the image element, you need to account for the wdtih of a scrollbar to avoid a horizontal scroll bar, this usually varies between 15px and 30px depending on the browser.
Please have a look. Is it matching your requirements. if no please let me know so I can try something more.
DEMO
http://jsfiddle.net/saorabhkr/FyJ4F/

Scrolling element contents without javascript

Dear all, is there a way to scroll, as in relatively shift the contents of, an element without using javascript, and only using CSS?
If that matters, the element in question has overflow:hidden and white-space: nowrap to make it 'hide' some parts of its content. The element is normally scrollable with javascript, but needs to be properly shifted upon initial rendering (and without further interactive scrolling, of course) in case javascript is disabled.
No, there is no way to scroll items on a page (unless it's an iframe with the hash portion of the url included, in which case the browser will control the initial positioning of the scroll, not css or html) using only CSS and HTML.
No. Not with CSS directly.
You could simulate it, by wrapping the contents with a div and giving it a margin-top value for the amount of scrolling you want.
(remember to remove it/set it to 0 with javascript when it is enabled)
update
A cool idea is what Jamie, mentions in his answer, if it fits your requirements.
update 2
Here is another solution i created out of Jamie's idea, that needs no frames.
Put an anchor <a name="anchor_name">..</a> at the place you want the scrolling to be and use a
<meta http-equiv="refresh" content="2;url=#anchor_name_here">
to auto-scroll there. (the meta element should go in the head though for (x)html conformance)
example at http://www.jsfiddle.net/gaby/f3CVY/5/
works great in all browsers i tested it (IE, Chrome, FF, Opera, Safari)
There is also another method - which is quite hacky - but it works without a reload.
The solution I've created works in the following browsers:
Firefox 4+
Safari 5+
Chrome 6+
Opera 11+
IE 10+
Android 2.3+
It's really a bit hacky, so see whether you would use it or not. :)
A little explanation
I used the HTML5 attribute autofocs on an <input>-field. As this will focus the input, it has to get it into the viewport. Therefor it will scroll to the given position. To get rid of the highlighted outline and to not see the input at all, you have to set some styles. But this still forced Safari to have one blinking pixel, so I did the trick with the span, that acts like an overlay. Note that you can't simply use display: none as this won't trigger the autofocus (only tested this in Safari).
Demo
Try before buy
The demo will run in Safari and Chrome only. IE and Firefox seem to not fire autofocus in an <iframe>.
CSS
div.outer {
height: 100px;
width: 100px;
overflow: auto;
}
div.inner {
position: relative;
height: 500px;
width: 500px;
}
div.inner > input {
width: 1px;
height:1px;
position: absolute;
z-index: 0;
top: 300px;
left: 200px;
border:0;
outline:0;
}
div.inner > span {
width: 1px;
height:1px;
position: absolute;
z-index: 1;
top: 300px;
left: 200px;
background: white;
}
HTML
<div class="outer">
<div class="inner">
<input type="text" autofocus></input>
<span></span>
</div>
</div>

Resources