Background-attachment:fixed not working as expected

Hi all,

I’m trying to achieve this effect, when you scroll the image stays the the top and the content goes over the top.

http://narrative.ly/drinking-buddies/the-great-brooklyn-vodka-experiment/

I’m trying the effect on the #top_header div by adding background-attachment: fixed. It works when I put the div outside the #l_container div which has (and needs) position: relative and I need it inside that container really.

Is this normal behaviour? I didn’t realise that background-attachment: fixed was constrained by a relatively positioned container.

http://mikeebee.com/staging/carter/interactive/index.html

Any ideas?

Many thanks
Mike

Hm, having position: relative on #l_container (the parent element) seems to be getting in the way, as it works if you remove that. However, this messes with the menu.

You’ve got your elements in a strange order, though, which doesn’t help. Why are you using that source order?

I know, I need the container positioned relative. Hmm the source order is crazy isn’t it! I was experimenting and it got away from me. I’ve reworked it :slight_smile:

Hi,

This is a known webkit bug as it is working ok elsewhere. The problem is that transforms kill position:fixed on all children so you either have to remove the transforms (and probably transitions) or else move the fixed elements out of the same context.

I’ve seen this bug a few times now and its a real pain to workaround.

Weirdly, it works OK for me in Chrome if you change the right setting here from 0 to -320px:

and change the right setting here:

#side_panel {
position: absolute;
[COLOR="#FF0000"]right: -320px;[/COLOR]
top: 0;
bottom: 0;
width: 320px;
background: #111;
z-index: 10;
}

Yes that’s weird :slight_smile: I can only guess that because the element is no longer over the transformed area it starts behaving. It seems that the exact value is -238px for some strange reason. Any less and it doesn’t work again.

However that gives you a horizontal scrollbar so perhaps setting right to :200% will push it off the left side of the screen instead and no scrollbar.

However both versions stop working again once the menu is selected and slides into position.

Perhaps something like this would be better.


#l_container{position:relative}
#side_panel{
float:right;
position:relative;
margin-right:-300px;
}
#side_panel.is_open{
margin-right:0;
}

#nav_main{
width:320px;
background:#111;
height:100vh;
}

(The code above is over-rides and should follow the original)

It uses ralphs trick of moving the element off screen but doesn’t incur a scrollbar.

Hmm that is producing some unusual behaviour in Chrome. I have updated the example.

When you open the menu, the image is no longer fixed. If you scroll down so some of the picture container is off screen and then open the menu and scroll back to the top the top part of the picture that was off screen has disappeared!

Huh, I don’t get that at all in Chrome. Have you refreshed your browser?

Hi,

As Ralph said I don’t see that effect.

When you click the menu the background does become un-fixed but I mentioned that above as once the menu is on the page it then affects the fixed positioning. However, it shouldn’t really be a problem. You either have to lose the fixed positioing or the transforms or re-work the html (if possible) so that the transitions aren’t in the same parent as the background (although transitions to seem to take over all the page in webkit).

I’ll have another look later and see if there is any other fixes (or Ralph might fond some other anomaly that will work :))

Sorry for the late reply chaps! I’ve tried it on a different machine (although same browser and OS - Chrome 29 and OS X 10.8) and I still get that weird effect.

I’ve fashioned a workaround where I’ve positioned a similar sized container behind the header and positioned it behind. It’s working ok at the moment but it feels a bit hacky.

Check it out here

Got an issue now on iOS where if you scroll to the very bottom of the page, some elements (#top_bar and #page_header) disappear when you scroll back to the top… until scrolling stops. Looks like it’s something to do with the transition again! - I tried to do a screencast but it wouldn’t work.

That looks better in Chrome Mike and I think you will have to live with the hacks until Chrome fixes that bug.

Regarding IOS then I looked on the ipad and it seemed ok and the only think I noticed was the background to the small menu icon was missing but the rest of content seemed to be there. This will be very hard to debug from our end as the only way to debug mobile/tablet is to make a working copy and test it.

Howdy chaps,

Just revisiting this as I no longer need position: relative; on the container. So, am I right in thinking if I set background-attachement: fixed; on an element, it’s background image will stay fixed to the window but also be 100% of the viewport too?

Basically, I want the image to remain fixed to the top of the window but only occupy the space of it’s container. Is this possible?

Thanks!

Yes, that’s the way it’s supposed to work. IF the background-image of the body is the same as the background-image in the container, it could look like a hole in the page :slight_smile:

Ah, rats! So there is no way to fix it but just occupy a certain height?.. Other than using an absolutely positioned container with the image.

Maybe I misunderstood the question, mikeebee8. Let me rephrase my answer anyway.

If you have a container somewhere on a page and you give it a {background-image} with {background-attachment: fixed}, the image should be positioned within that container as if the image started at the top left corner of the window. Your understanding of {background-attachment: fixed} sounds correct to me. I’m not sure about the “100% of the viewport” part of your question, but would be correct to say that the image in the container should appear to be fixed to top left corner of the window no matter where that container is positioned on the page or what size it is.

Apparently Webkit has/had a problem with {background-position:fixed} and, at one time, FF had a problem if {background-position:fixed} was applied to a <td> (not sure it it’s been fixed).

If you want to post a link to your page without the {position:relative} ancestor, I can look at it with Opera and see how it behaves.


<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd">
<html>
<head>
    <meta http-equiv="content-type" content="text/html; charset=utf-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>background-attachment</title>
    <style type="text/css">

body {
    background-image:url('http://25.media.tumblr.com/tumblr_medeoycBYZ1qcdtsho1_400.jpg');
    background-repeat:repeat;
    background-attachment:fixed;
}
.outer {
    width:50%;
    background-color:#843;
    padding:4em 4em;
    margin:50% auto;
}
.inner {
    border:1px solid #000;
    background-image:url('http://25.media.tumblr.com/tumblr_medeoycBYZ1qcdtsho1_400.jpg');
    background-repeat:repeat;
    background-attachment:fixed;
}
p {
    font-weight:bold;
    font-size:1.5em;
    line-height:1.25;
    margin:1em 2em;
}

    </style>
</head>
<body>

<div class="outer">
    <div class="inner">
        <p>Lorem Ipsum lives here.</p>
        <p>Lorem Ipsum lives here.</p>
        <p>Lorem Ipsum lives here.</p>
        <p>Lorem Ipsum lives here.</p>
        <p>Lorem Ipsum lives here.</p>
    </div>
</div>

</body>
</html>

Works in Opera, Chrome and FF.

No worries, I’m still a little confused though. Your example shows that the image does indeed take up the full height of the browser window but I only want the image to occupy the height of my hero container. Otherwise it’s far too stretched.

Apologies if I’m not explaining it correctly… or I’m missing something!

You’re fine, Mike. I didn’t read the entire thread thoroughly enough. My response is off base. Sorry.

If you apply background-attachment fixed to an element the image is placed in relation to the viewport and not the element you applied it to.

However, the image will only be visible if your container is over the area where the image resides.

Best seen in a live example:

Rons example shows the same behaviour if you remove the image from the body.


<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd">
<html>
    <head>
    <meta http-equiv="content-type" content="text/html; charset=utf-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>background-attachment</title>
    <style type="text/css">

.outer {
	width:50%;
	background-color:#843;
	padding:4em 4em;
	margin:50% auto;
}
.inner {
	border:1px solid #000;
	background-image:url('http://25.media.tumblr.com/tumblr_medeoycBYZ1qcdtsho1_400.jpg');
	background-repeat:repeat;
	background-attachment:fixed;
}
p {
	font-weight:bold;
	font-size:1.5em;
	line-height:1.25;
	margin:1em 2em;
}
</style>
    </head>
    <body>
				<div class="outer">
						<div class="inner">
								<p>Lorem Ipsum lives here.</p>
								<p>Lorem Ipsum lives here.</p>
								<p>Lorem Ipsum lives here.</p>
								<p>Lorem Ipsum lives here.</p>
								<p>Lorem Ipsum lives here.</p>
						</div>
				</div>
</body>
</html>


You would need to place a fixed positioned element at the top of the page at the size you want with a normal background image set to cover. In that way the image can span the element and still remain fixed because the element is fixed.

However I couldn’t see your original page so can’t remember what we were doing here exactly :slight_smile: