Background-position-y: Firefox Fails!

26 Apr 2007

I am trying to switch to the technique of 1 giant icons file.  I didn’t like the opacity filter for the disabled elements.  I really wanted grayscale.  So I had to use duplicate images.  I made a grid on my image so that the math was easy.  See image here.  So in my CSS, all I have to do is adjust the horizontal axis for the background-position.  Internet Explorer does this with background-position-x.  Firefox doesn’t support that!  They just have regular background-position.

This blows.  Now my css for this section is 3x longer than it needs to be.  Bad Firefox. I usually don’t need to say that, but, well, there it is.

Unless there is a CSS opacity filter that shields out all the color?  It would be a cool feature for IE8 and FF3!

  • Google Buzz

43 Comments

Avatar

commadot.com » Blog Archive » The right sprite?

August 11th, 2007 at 3:44 pm

[...] is that this method creates alot of CSS defintitions that are hard to manage. The reason is that Firefox does not support the background-position-x CSS attribute. This really sucks because it means that you can’t have a sprite ‘matrix’ that [...]

Avatar

Bryan Buchs

August 13th, 2007 at 1:35 pm

Firefox doesn’t “fail” background-position-x/y! That’s a MSIE specific CSS property.

“…Microsoft introduced two new, browser-specific background properties with the release of version 5.5 of Internet Explorer: background-position-x and background-position-y…”

http://safari.oreilly.com/0130092789/ch14lev1sec7

Avatar

Glen Lipka

August 13th, 2007 at 2:24 pm

I understand. But it’s such an obvious feature to have. I really think Firefox dropped the ball by not implementing it. This is where standards and common sense do not always match. In my mind, they fail the common sense test. And when I try to use the feature, it fails to work.

Avatar

Stuart Steel

August 14th, 2007 at 1:12 am

re: standards.

I agree with Glen. While standards are a fantastic idea, and to be supported, being too blinkered about them can be limited. While web standards and standard compliant browsers are usually the good guys its also important to recognise when companies like microsoft implement something of quality and commonsense. Hopefully the standards will follow.

Avatar

erkko

August 17th, 2007 at 8:54 am

what’s with a moaning? 3x longer css? how come?

background-position-x: 300px;
background-position: 0 300px;

so, where’s the three times longer css? Any example of your code to illustrate this claim? not to mention first example is clearly no-css/ie-only and second is as old as css1

Avatar

Glen Lipka

August 17th, 2007 at 3:46 pm

Sample code and more detail:
http://commadot.com/?p=590

Avatar

andy

January 16th, 2008 at 4:13 pm

erkko, thats only assuming you want the background’s y position to be at zero. What if it is at a variable y position? Without changing the X only, you would have to use redundant logic to find the Y again.

Avatar

Renato

January 23rd, 2008 at 6:18 am

I was searching just to find this same issue.
I am using CSS Sprites, which is a great performance technique, and I’ve got really disappointed with Firefox because of this…

For those who not understood what is the real issue, try to imagine this situation…

I have one image with a lot of logos which I just use background-position to place to the right location of my div. But I do not want that all of my divs have the same appearance. For this kind of situation, I want that sometimes the logo can be placed at the left and sometimes at the right…

HTML CODE

HERE I WANT ONE LOGO TO THE LEFT
HERE TO THE RIGHT

CSS CODE

/* default background position to the left */
div{background:url(logos.gif) no-repeat;}

/* set background position to the right */
div.customdiv{background-position-x:right;}

/* positioning the logos */
div.logo1{background-position-y:-10px;}
div.logo2{background-position-y:-50px;}

If I use the standard and firefox logic, I cannot use the background-position-y nor the background-position-x. I’d have to make a redundant logic to all position both at the same time…
background-position:right -50px;
background-position:left -50px;

ALWAYS… Sorry, I hate to say this, but this time MSIE won.

Avatar

Glen Lipka

January 23rd, 2008 at 9:14 am

@Renato: Hmm, I wonder if FF3 allows independant background positions? In the meantime, check out fofreground sprites. They do othe trick very well.

http://commadot.com/the-right-sprite/

Avatar

Anon

March 6th, 2008 at 12:33 pm

Andy wrote: “erkko, thats only assuming you want the background’s y position to be at zero. What if it is at a variable y position? Without changing the X only, you would have to use redundant logic to find the Y again.”

“background-position: 0 300px;” was an EXAMPLE!
You can make what you need…
background-position: 150px 300px;
background-position: 300 0px;
background-position: 100% 100%;
background-position: 45% 93%;
They all work and they only are one line of CSS.

@Renato: you just need to specify both the x and y of your div.logo1 position (i.e., drop the “-y” and just add 0 for the “x” position.

Avatar

Jonas

March 19th, 2008 at 7:06 am

I’m having the same problem, I have a menu with a big bg image for all the links.
Then i have a set of rules that sets bg pos x/y for every link.
Then, because of Firefox, what could have been #nav a:hover { background-position-y: -25px; } for ALL the links, now have to be another set of rules for every link, to set both positions right.
And then a third set for the active state.

And bg pos x/y is valid CSS3, BTW.

Avatar

Paul Tierney

April 9th, 2008 at 2:49 am

background-position-x: left; should be

background-position: left 100%;

background-position-x: right; should be

background-position: right 100%;

its all very simple.

Avatar

Glen Lipka

April 9th, 2008 at 7:40 am

Paul, I am not understanding your comment. The goal is to declare X/Y coordinated INDEPENDANTLY. That means that one css line can control a column in a background sprite matrix with many columns and many rows. Without independant declaration, there is no way to use a matrix as a background image. I have a separate post about foreground-images which can use margin-left and margin-top to achieve the desired goal.

Unless, I am misreading and you are referring to one of the followup posts. :)

Avatar

Troy III

June 12th, 2008 at 11:25 am

I’ve just checked my page that has in use a background-position-x and/or -y @ CSS level 2.1 at their validation site. After seeing a green safe bar it offered me icons that this page is CSS2.1 Valid and certified.

Now I really don’t understand – what are they checking there for? A well formed text or CSS declarations?
Or does this mean that background-position-x/y is CSS 2.1 standard?!!

Or does this mean that we should wait another decade for W3C, to come to their “own brilliant idea” that is should be very useful to be able to position background x/y positions separately. Therefore we propose a new CSS invention: background-placement-horizontal: 16px-to-the-right/left; and
background-placement-vertically: 25px-tho-the-top/bottom;
or some other goddamn novel-length statements, like their famous: document.getElementBy(‘theID”).style.backgroundPlacementVertically=
25pxToTheTop, with a warning: “be sure not to forget to explicitly state the “ToTheTop” instruction as indicated otherwise the browser will completely ignore your instruction since the browser will not know the direction which way to push the background image. :D

Well. So much for the standards and lazy browsers like Mozilla’s or should I say, Godzilla’s…

Avatar

Glen Lipka

June 12th, 2008 at 2:54 pm

I just tested in Firefox 3. Still no support although there was some rumblings about support using the mode here: http://archivist.incutio.com/viewlist/css-discuss/74335

I just realized that all of my examples have moved. Sorry about that.

Avatar

Shivam

September 17th, 2008 at 9:32 am

Guys this works!:

The syntax for setting the background x and y properties is:

background-position: [horizontal position] [vertical position];

Such as:

background-position: right top; //places the image right horizontally and top vertically
background-position: left bottom; //places the image left horizontally and bottom vertically
background-position: center center; //places the image center horizontally and center vertically

..it’s really simple.

Avatar

Glen Lipka

September 17th, 2008 at 9:40 am

Shivam, please read the post more closely.
I am trying to set the Y position independantly of the X. In other words, I want background-position-y, not X, not both. Your answer, unfortunately, is not helpful.

The reason to want to do this is to use a background sprite as a matrix where you could change columns without changing the row. That way you could have icon “states” without an explosion of CSS for every single matrix x-y position.

Avatar

Greg Tczap

September 29th, 2008 at 11:10 am

I am currently dealing with this same problem – it has been frustrating to say the least. I find it slightly pathetic that there exists no standard CSS properties that allow you to define the background image on the x and y axis separately. However, I don’t see this as a failing of Firefox, because they are following web standards and there is no such properties as background-position-x and background-position-y in the official CSS specs. Perhaps there should be – but that is an argument that should be directed at the W3C and not at Firefox.

Anyways, here is my initial idea for a solution. Why not just write your own javascript functions to change the x and y positions? This could be done in two generic functions so as to hide the complexity of this operation. For example, a changeYPos(myElement, newPos) function could parse out the current x AND y positions for the background image of the element, and then set the Y of the background position by passing it the old x along with the new y. Then that function could be re-used and it would be relatively easy to create cross-browser compatible image matrix using this technique.

Avatar

Glen Lipka

September 29th, 2008 at 11:42 am

@Greg: Interesting solution. That could even be made as a jQuery plugin, for example to make it easier.

Avatar

Greg Tczap

September 29th, 2008 at 12:02 pm

@Glen: Here is an example of a function I just wrote to do this. I have not tested it extensively across all browsers but it seems to work fine so far in FF3.

function changeBackgroundPosition(element, axis, value)
{
var oldPos;
var newPos;

oldPos = document.getElementById(element).style.backgroundPosition;

alert(“oldPos = ” + oldPos);

if (axis == “x”) {
newPos = oldPos.replace(/^\S+/, value);
} else if (axis == “y”) {
newPos = oldPos.replace(/\S+$/, value);
}

document.getElementById(element).style.backgroundPosition = newPos;
}

Avatar

jameal

November 23rd, 2008 at 6:29 pm

I didn’t bother reading any of the other comments,  so I don’t know if someone else posted this, but I also had this same problem and solved it this way:

background-position: 0% -40px;

Just use 0% for whichever axis stays the same!

Avatar

jameal

November 23rd, 2008 at 6:31 pm

Actually, that didn’t work. Nevermind, haha.

Avatar

Glen Lipka

November 23rd, 2008 at 6:35 pm

@jameal: Man, you almost had me there.  My heart started beating faster.
I’ve been working on a product where high speed and no-IE6 is ok.  It’s so freeing to ignore IE6 and not bother with sprites.  I just use a single PNG file and call it a day.

Avatar

Nathan Clark

January 7th, 2009 at 6:56 am

This recreates the background-position-y, allowing for independent declaration:

currBG = $(whichTab + ” a”).css(‘background-position’);
currBG = currBG.substr(0,currBG.indexOf(” “)) + ” -31px”;
$(whichTab + ” a”).css({‘background-position’: currBG});

You could obviously swap that around to change on -x if you wanted.

Avatar

Ethan

March 17th, 2009 at 6:31 am

Hello. I apologize in advanced if this has been already posted by somebody else. I too, was looking for the problem regarding the missing backgroundPositionX property.

Instead of that I use

parseInt(document.getElementById(“myElement”).style.backgroundPosition.split(” “)[0]) to get X and
parseInt(document.getElementById(“myElement”).style.backgroundPosition.split(” “)[1]) to get Y.

Of course, before the values can be read, they have to be first assigned, somewhere in the javascript code with

document.getElementById(“myElement”).style.backgroundPosition = “10px 10px”;

as you can’t read the default values specified in css.

Ethan

Avatar

Ethan

March 17th, 2009 at 6:32 am

split(” “)

space character.

Avatar

SamGoody

April 30th, 2009 at 2:09 am

You are able to declare the x position independently in Firefox 3.01, but there is no way to change the y.
Many times, though, that is enough.

http://www.w3schools.com/js/tryit.asp?filename=try_dom_style_backgroundposition

background-image:url(bgdesert.jpg);
background-repeat:no-repeat;
background-position:25px center;
background-attachment:fixed;


function changePosition(){
document.body.style.backgroundPosition=\

Avatar

Leon Poole

June 2nd, 2009 at 2:58 am

Glen I’m in the same boat as you and find it hard to understand why the ability to define background-position-x/y isn’t standard. They give your border-left, border-top, padding-left, bottom etc. – being able to define x or y uniquely seems to be the natural progression.

Would love a follow up on this if it ever becomes standard.

Avatar

David W

September 6th, 2009 at 1:38 pm

I’m in need of the same thing – a way to independently set the X and Y background-positions independently (in different selectors) in Firefox + Webkit + IE 7+.

I tried:
.column-2{background-position-x:-16px;}
.row-2{background-position-y:-16px;}

and:
.column-2{background-position:-16px inherit;}
.row-2{background-position:inherit -16px;}

any other value (i.e. 0, 0%, 100%, top, left, center, right, bottom, inherit, etc) will override both axes of the previous selector — which destroys the purpose.

Avatar

????

September 27th, 2009 at 5:55 pm

well, I search and hit here, frustrating reading down.

Finally I took this solution and it works:

function set_backpos_y(ele, val){
var posX = $(ele).css(‘background-position’).split(‘ ‘)[0];
$(ele).css(‘background-position’, posX+” “+val+”px”);
}

Avatar

TempNameNr2346234

October 20th, 2009 at 11:44 am

The solution is to first set height = “100%”! It can also (only?) be done with javascript…

//…For example you set the background in fram x to bottom-right…
bFn = getElementsByAttribute(top.frames[x].document,”body”,”background”)[0];
bFn.style.margin = “0″;
bFn.style.padding = “0″;
bFn.style.width = “100%”;
bFn.style.height = “100%”; // <<< important
bFn.style.backgroundRepeat = "no-repeat";
bFn.style.backgroundPosition = "right bottom"; //x y

Avatar

TempNameNr2346234

October 20th, 2009 at 12:35 pm

CHANGE background TO bgcolor !!! Somehow I missed to test the last change I made :(

Avatar

Flavio Copes

November 15th, 2009 at 4:20 pm

Thanks, I solved a bug using the comments above:

background-position-x: -300px;
=
background-position: 0 -300px;

background-position-x: -300px;
background-position-y: 20px;
=
background-position: 20px -300px;

background-position-x: -300px;
=
background-position-y: 50%;
background-position: 50% -300px;

Avatar

mStudios

November 15th, 2009 at 8:41 pm

What people don’t understand who state the setting the -x plus the -y at the same time is no big deal: I have a whole array of -y = top but on the -x axis they are all at different positions.

THAT is what makes the code so much longer, as now I have to write -x=50/-y=top and -x=25/-y=top and -x30/-y=top etc. etc. etc… that is A LOT more than just -y=top.

Avatar

Glen Lipka

November 15th, 2009 at 9:19 pm

Agreed mStudio. I have no idea why the W3C never dealt with this and why Mozilla/WebKit dont either. It’s such a simple thing.

Avatar

Ryan

December 4th, 2009 at 9:38 am

Webkit supports `background-position-x` and `background-position-y`. Firefox is the black sheep here.

Those who think it’s not an issue clearly have never optimized a website using sprites, and are unlikely to be gainfully employed in the web development industry :P (you know it’s true!)

Avatar

Alex

January 23rd, 2010 at 1:48 pm

Here is my solution for u’re problem:
You need to append this lines to the css:

background-attachment: fixed;
height:100%;

Cheer’s,
Alex Manolescu

Avatar

Ahmad Alfy

January 27th, 2010 at 4:50 pm

I had my navigation like this :
#nav li a {
background : url(image.png) no-repeat;
}
and every a has an ID to specify the position and the width. I wanted to do
#nav li a:hover{
background-position-y : -35px;
}
and all will be fixed… Shame it fails on FF :(

Avatar

Brandon

February 1st, 2010 at 1:20 pm

Want to break the background-position into x and y? Use the JavaScript split() function to break the string into an array so you can then use it dynamically. One line and you have the respective x and y coordinates for the background-position.

var bgpos = someObj.style.backgroundPosition.split(‘ ‘);
bgpos[0]; // x
bgpos[1]; // y

Avatar

J. Millington

February 23rd, 2010 at 11:45 am

Glen, you’re an idiot awesome.
[Edited by Glen 2/24/2009]

Avatar

Paul Tierney

February 23rd, 2010 at 12:08 pm

I cant believe this post is still running…

In my view there are more than enough ways to control the backgound position on all browsers to satisify any given scenario or requirements.

I do agree that in IE you write less CSS to satisfy the requirement but code efficiency is not about the number of lines you write.

Using CSS in conjunction with multiple class assignments would be what I would recommend as a solution to this problem.

UNsubscribing now

Avatar

Glen Lipka

February 24th, 2010 at 10:39 am

This post is funny to me. It’s from April 2007. 41 posts is ridiculous.

However, this is still not resolved. There is no reason why NOT to have independent background-position available in CSS.

With that said…I don’t care anymore. This blog is really about User Experience design. Read the front page. :)

Avatar

Espen

March 13th, 2010 at 2:14 pm

Say you’re using this for a menu. You have a ul list with anchor tags. Couldn’t you do something like this? Haven’t cross browser tested it, but it should work.

#nav li{
display:block;
float:left;
height:16px;
overflow:hidden;
}
#nav li a{
display:block;
height:32px;
text-indent:-9999px;
background:url(../Gfx/menu.png) no-repeat 0 1px;
}
#nav li a:hover{
margin-top:-16px;
}

Comment Form

About commadot.com

Started in 1996, Glen Lipka has been been randomly publishing about User Experience, Technology, Human Psychology and other subjects.

Good Karma

Did you save or make money off this blog?

Contact Glen or try to IM me below.

Archives