Background-position-y: Firefox Fails!

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!

This entry was posted in Uncategorized and tagged , . Bookmark the permalink.

48 Responses to Background-position-y: Firefox Fails!

  1. Pingback: commadot.com » Blog Archive » The right sprite?

  2. Bryan Buchs says:

    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

  3. Glen Lipka says:

    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.

  4. Stuart Steel says:

    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.

  5. erkko says:

    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

  6. andy says:

    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.

  7. Renato says:

    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.

  8. Glen Lipka says:

    @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/

  9. Anon says:

    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.

  10. Jonas says:

    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.

  11. Paul Tierney says:

    background-position-x: left; should be

    background-position: left 100%;

    background-position-x: right; should be

    background-position: right 100%;

    its all very simple.

  12. Glen Lipka says:

    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. :)

  13. Troy III says:

    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…

  14. Glen Lipka says:

    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.

  15. Shivam says:

    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.

  16. Glen Lipka says:

    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.

  17. Greg Tczap says:

    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.

  18. Glen Lipka says:

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

  19. Greg Tczap says:

    @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;
    }

  20. jameal says:

    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!

  21. jameal says:

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

  22. Glen Lipka says:

    @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.

  23. Nathan Clark says:

    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.

  24. Ethan says:

    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

  25. Ethan says:

    split(” “)

    space character.

  26. SamGoody says:

    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=\

  27. Leon Poole says:

    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.

  28. David W says:

    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.

  29. ???? says:

    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”);
    }

  30. TempNameNr2346234 says:

    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

  31. TempNameNr2346234 says:

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

  32. Flavio Copes says:

    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;

  33. mStudios says:

    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.

  34. Glen Lipka says:

    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.

  35. Ryan says:

    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!)

  36. Alex says:

    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

  37. Ahmad Alfy says:

    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 :(

  38. Brandon says:

    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

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

  40. Paul Tierney says:

    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

  41. Glen Lipka says:

    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. :)

  42. Espen says:

    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;
    }

  43. Pingback: Background Position in Firefox: In Which Some Developers are Jerks

  44. Kelt says:

    Classic example… in the following css I could easily say, to get a picture at that specific row & column (4×4 multi-dimensional array picture).

    If I use an 8×8 sprite this turns out to be 64 lines of CSS as opposed to 16 lines.

    .sprite {
    background-image: url(“./sprite-small.png”);
    background-repeat : no-repeat ;
    width : 150px ;
    height : 112px ;
    }

    .row0 { background-position-y: top; }
    .row1 { background-position-y: -112px; }
    .row2 { background-position-y: -225px; }
    .row3 { background-position-y: -338px; }

    .col0 { background-position-x: left; }
    .col1 { background-position-x: -150px; }
    .col2 { background-position-x: -300px; }
    .col3 { background-position-x: -450px; }

  45. Kelt says:

    Uh… in the above comment it should read <div class=”sprite row 2 col 3″ …

  46. Weel Young says:

    I previously thought that IE is full of bugs … now I think I have to change my view

    first: in FF ‘childnodes ‘ is defined in a totally quirky way — it takes every empty text node as one of those childs… my goodness … you cannot access childnodes array by the index directly

    second: it surprisingly doesn’t support backgroundPositionY … it is obvious that assigning a number to number-based variable is more meaningful and workable than using a string, under which condition string concatenation has to be used to combine number operation and string literals….

  47. When using styles, you can use this JS function (assuming that the element’s id is “elem” and “val” is the y-pos):

    function change_y(elem,val) {
    var elemento=document.getElementById(elem);
    var posx = elemento.style.backgroundPosition.split(‘ ‘)[0];
    elemento.style.backgroundPosition=posx+” -”+val+”px”;
    }

Leave a Reply

Your email address will not be published. Required fields are marked *

*

You may use these HTML tags and attributes: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <strike> <strong>