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!

78 Replies to “Background-position-y: Firefox Fails!”

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

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

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

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

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

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

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

  8. 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. 🙂

  9. 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. 😀

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

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

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

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

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

  14. 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!

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

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

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

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

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

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

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

  22. 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;

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

  24. 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 😛 (you know it’s true!)

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

  26. 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 🙁

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

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

  29. 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. 🙂

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

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

  32. 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….

  33. 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”;
    }

  34. Firefox does not support background-position-y, but it does support background-position which accepts 2 values (x y). If you specify only the x coordinate rather than both, the y coordinate will cascade from the previous class.


    .c1 {background: url(...) no-repeat 10px 10px}
    .c2 {background-position:900px}

    c1+c2 result: background-position: 900px 10px;

    You may need to adjust the layout of your sprite image to work with only X based position modifiers.

  35. yeah, amazing this thread is still going. but here we are, still in need of this ability, and ff still failing to implement. i have a sprite for some page titles, but i need to override the positioning for a mobile-optimized version of the site. i want all the individual y positions to remain, since they are based on which page is being viewed, but rather than have x set to 0, i want to set all x positions to 50%.

    due to ff, instead of just declaring:


    .page-head
    h2
    background-position-x: 50%

    i have to rewrite the rule for every page


    .picks
    .page-head
    h2
    background-position: 50% -20px

    .leagues
    .page-head
    h2
    background-position: 50% -40px

    this is ridiculous, since i’ve already set all the x values.

  36. Wow.. so many posters failed to comprehend the scope of the problem. Think about matrixes, guys!

    So yeah, that’s something that should definitely be available in the standard, as to force FF to implement it!

  37. Haha, I just ran into the same issue. Chrome, IE6+, Safari all support background-position-y. Opera and Firefox do not, since they aren’t running MSIE or WebKit.

    This is just too bad. I’d have really liked to not have to retype a .select class for each of my sprite navigation images. Would save some code and make it much easier to keep things dynamic.

    The JS options are cool but I don’t like forcing my websites into using javascript. For usability, your site should never require javascript, it should only be used as an enhancement.

  38. To all those who blamed Firefox for not supporting this specific property: do you really want to compare the number of standard compliant rules Firefox implements to the ones MSIE implements??
    Or would you like to compare the innovative CSS rules Firefox implemented years before the advent of CSS3, such as nifty corners and box shadow?
    I hope it’s a joke…

    The funny part is that I landed to this post while trying to use this selector to implement a lack of CSS interpretation from MSIE.
    If MSIE would interpret correctly multiple classes selectors (e.g. .class1.class2 instead of parsing it as .class1 .class2) or other simple syntaxes, I would have never needed things like it, being able to solve every problem with a state-marker class on the wrapper element.

  39. I read Pauls Post and it works firefox. if you want
    background-position-y: -50px;
    then use
    background-position:left -50px;
    for firefox, alternatively for
    background-position-x: -50px;
    then use
    background-position:right -50px;

    Good luck, nice and easy…

  40. This would definitely be a brilliant thing for Mozilla to implement. I have a sprite of 8 navigation buttons, each with a roll-over and a down effect – so 24 buttons in total. The buttons are arranged in a single PNG, in a grid of 8 x 3.

    Instead of implementing a single line of CSS for the hover effect, eg:

    #nav li a:hover { background-position-y: -80px; }

    I have to write 8 lines of CSS:

    #nav li.home a:hover { background-position: 0 -80px; }
    #nav li.about a:hover { background-position: -100px -80px; }
    #nav li.about a:contact { background-position: -200px -80px; }

    … and so on

    so in my case, the CSS will be many times longer because this hasn’t been implemented.

  41. I think Erkko’s solution pretty much wraps up the initial issue, right?

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

    Works for me, any way.

  42. You could try a trick like this:

    Sprite

    div {
    background-position: 10px 0;
    }

    a {
    background-position: inherit 10px;
    }

    I dont know what support is like for the inherit option.

  43. Jeez, firefox! still not solved the -x -y issue, the thing most people answer is that you can write a combined 😡 y;
    but imaging i have 20+ sprites in a image each has just a -30px on y axis,
    – background-position-y will only need to be set once to -30px for all .class a:hover {}
    but since freaking firefox dosent work
    – i need to repeat that code for every single .classA a:hover, .classB a:hover, 20 times 2, 40 lines of code. compare to only 21 lines of code.
    I dislike IE, but it works with this on both webkit and ie browsers just not freaking firefox….

  44. Addin to this epic post; FF _still_ does not support this obviously useful property. For now I am just leaving FF users in the cold with ugly looking backgrounds and non-moving bg sprintes. Servers them well, they are probably used to seeing websites being rendered ugly.

    Amazing how many people do not get the problem by the way and insist in copying the other axis in the rule, not seeing how this would bloat the code or just plain override the correct value.

    Firefox, get your act together fast!

    P.S. Is Kalen’s solution (about 8 replies up) totaly bonkers or is it me? Makes no sense at all 😉 certainly does _not_ what I want.

  45. I hit this one making a counter which had a 10×10 sprite matrix (one column for each position, one row for each number). for most browsers: 20 lines of CSS, one for each row and column, specifying x and y coordinates. Setting class=”row-4 col-3″ on the items in the counter then worked great.

    Matching this behavior in FF according to their wonderfully “standards correct” approach would have needed *100 lines* of CSS. Haha!! Firefox users get the crappy edition as a result. I could have implemented a patch in JS but really, I didn’t want to coddle a bad way of doing things.

    In this case, the FF standardistas need to get with the “worse is better” program.
    http://www.jwz.org/doc/worse-is-better.html

  46. This problem is most inconvenient when using sprites for different states (:hover, :focus, :hover:active, etc). Rather than exponentially increase the size of my CSS file, though I just left it so that Firefox doesn’t change state for my buttons. I’d recommend others do the same if possible, I know it always isn’t. In my case, it’s not a site-breaking feature, so I’d rather have it as one of those subtle things that you might notice when trying out a new browser.

    Unfortunately, the Firefox devs have made it clear they won’t be adding this, even though Webkit supports it too. Just another reason to encourage the use of Chrome, I suppose.

  47. well my problem is that sure following code works for just a setup or using it more statically:
    background-position-x: 300px;
    background-position: 300px 0;
    background-position-y: 300px;
    background-position: 0 300px;
    But, I want to use it for dynamically and use it as condition check with jQuery:
    var yposition=50%;
    if($(“.showimage”).css(“background-position”) === “-21600px ” + yposition){
    $(“.showimage”).css(“background-position”,”21000″ + yposition );
    else{
    $(“.showimage”).css(“background-position”,”+=600″ + yposition );
    }
    }
    change function(){//not real function
    yposition = {change on condition}
    }

    Funny thing is it above code actually works in IE and Chrome , where as Firefox doesn’t and it doesn’t support background-position-x and background-position-y. I could explicitly declare the position on x and y too in IE and Chrome and works…above if condition works in IE and Chrome. I’m not a big fan of IE but man…Firefox is giving me a big headache.

  48. How does this make your CSS longer? Instead of:

    .scroll-controller a {
    display: block;
    text-indent: -9999px;
    float: left;
    width: 22px;
    height: 22px;
    background: transparent url(../img/sprite-arrow-btns.png) no-repeat 0 0 scroll;
    }

    .scroll-controller a.up {
    background-position-x: -11px;
    margin-right: 13px;
    }

    .scroll-controller a.down {
    background-position-x: -48px;
    }

    .scroll-controller a.disable {
    background-position-y: -32px;
    }

    You have:

    .scroll-controller a {
    display: block;
    text-indent: -9999px;
    float: left;
    width: 22px;
    height: 22px;
    background: transparent url(../img/sprite-arrow-btns.png) no-repeat 0 0 scroll;
    }

    .scroll-controller a.up {
    background-position: -11px 0;
    margin-right: 13px;
    }

    .scroll-controller a.down {
    background-position: -48px 0;
    }

    .scroll-controller a.disable {
    background-position: inherit -32px;
    }

    Same number of lines. This is more fail-proof anyway as I am sure background-position isn’t going anywhere. As stated earlier background-position-x and -y were MSIE specific at one point. That’s where things go to die.

  49. Uhm, if you’re using sprites and have 19 buttons with the same X background-position, that hover with a 20 pixel shift to the bottom, I’m sorry, but background-position-y is extremely useful. I just ran into this issue, and I’m now forced to write a rule for each one of these buttons:hover…

    I think it’s absolutely ridiculous to dog it just because MSIE was the first to implement it. Yes, it’s a shitty browser, but that’s a good implementation. I agree with whoever it was above that stated Firefox was the black sheep, since every other browser supports this rule.

    This is much shorter than writing out each :hover state rule.

    #actionPanel .button.like > span {
    background: transparent url(../images/header-sprite.png) no-repeat -322px -53px;
    }
    #actionPanel .button.unlike > span {
    background: transparent url(../images/header-sprite.png) no-repeat -349px -53px;
    }
    #actionPanel .button.share > span {
    background: transparent url(../images/header-sprite.png) no-repeat -378px -53px;
    }
    #actionPanel .button.flag > span {
    background: transparent url(../images/header-sprite.png) no-repeat -408px -53px;
    }

    #actionPanel .button:hover > span, #actionPanel .button:hover > span.active, #actionPanel .button > span.active {
    background-position-y: -81px;
    }

  50. I’m learning CSS now, and I just finished making navigation buttons in a nice image with the hover sprites below each. Wrote all the code for Chrome with a list element selector to change background-position-y on hover, and now found out that to support Firefox I have to write a specific background-position for EACH button’s hover… How is it they haven’t implemented this after SIX YEARS??

  51. Can I butt in? because the following code does not work in IE10 or Firefox but is ok in Chrome.

    markup:

    style:
    _______________________________________________
    .splashIcon{
    background-image: url(‘../images/splashSprites.png’);
    width: 33px;
    height:23px;
    margin-left:30px;
    float:left;
    }

    #loginLi{
    background-position: 66 0;
    background-position-x: 66;
    background-position-y: 0;
    }

    #loginLi:hover {
    background-position: 66 23;
    background-position-x: 66;
    background-position-y: 23;
    }

    _______________________________________________

    behavior:

    Chrome: OK

    IE10: shows the different background positions per li but does not change background position on hover.

    Firefox: shows the same background position for all li of 0 0 and does not change background position on hover.

    Anybody have an idea? Thanks in advance…

  52. Um… odd… but basically I have an Unordered list where i set the list items’ classes to splashIcon and different ids. (e.g. loginLi)

Leave a Reply