2

I'm trying to hide a background-image (that is scaled with background-size) using background-position.

I'm purposely not using visibility or anything that will cause a relayout as such has been causing minor fluctuations in the rendered output when toggling back into view. Additionally, my current application limits me from using pseudo-elements as a hack/workaround.

div {
    background: url(image.png) no-repeat 200% 200%/100%;
    height: 100px;   /* half height of image */
    width: 250px;    /* half width of image */
}

Unfortunately, the image is not getting positioned. If the /100% is removed, the positioning works correctly.

jsfiddle: http://jsfiddle.net/prometh/60jtpust/

Update:
Curiously, it works when the background-size is 50%: http://jsfiddle.net/60jtpust/8/

Steven Vachon
  • 3,814
  • 1
  • 30
  • 30
  • I can answer the bit on why `background-position` does not work with `background-size: 100%`, but unfortunately I can't think of a solution to your problem that doesn't trigger a reflow, as you essentially will not be able to use `background-position` unless you know the exact pixel values in advance. Would an answer to the former suffice? – BoltClock Feb 19 '15 at 17:50
  • ~~Fortunately, my background image was inside an absolutely positioned pseudo-element stemming from an element with `overflow:hidden`. With that, I was able to place it out of view with `left:auto; right:100%`.~~ – Steven Vachon Feb 19 '15 at 18:19
  • That's actually pretty clever. Also, I see someone went ahead and posted an answer with just an explanation from the spec - I had a different explanation in mind, but if you understand the spec for what it is then my explanation won't be necessary ;) – BoltClock Feb 19 '15 at 18:21
  • :) My fortunateness disappeared. `left` caused the same fluctuations due to relayout. http://csstriggers.com – Steven Vachon Feb 19 '15 at 18:25
  • And yeah, Oriol's answer made sense, but I did have to read it a few times. If you have a better explanation, go for it and I'll choose yours as the best answer. It might help someone else. – Steven Vachon Feb 19 '15 at 18:27
  • 2
    Well, know that you've helped someone already - that site is incredible and I had no idea it existed. Thanks for the link! – BoltClock Feb 19 '15 at 18:31

2 Answers2

5

The problem is that

3.9. Sizing Images: the ‘background-size’ property

A percentage is relative to the background positioning area.

And

3.6. Positioning Images: the ‘background-position’ property

Percentages: refer to size of background positioning area minus size of background image, [...] where the size of the image is the size given by ‘background-size’.

Therefore, if you use a background-size of 100%, the percentage is background-position will refer to 0. So it will be 0.

Oriol
  • 274,082
  • 63
  • 437
  • 513
  • I guess that I'll have to find another solution, then. Static positions might be ok short-term, but long-term they'll be problematic. – Steven Vachon Feb 19 '15 at 18:10
3

Percentage values for background-position have funky behavior with relation to background-size, which I explain in depth, complete with a sliding puzzle analogy, in this answer. Unfortunately, because the background image fits the box exactly due to background-size: 100%, you won't be able to position it using percentage values. From the final paragraph of my answer:

If you want to position a background image whose size is 100% of the background area, you won't be able to use a percentage, since you can't move a tile that fits its frame perfectly (which incidentally would make for either the most boring puzzle or the perfect prank). This applies whether the intrinsic dimensions of the background image match the dimensions of the element, or you explicitly set background-size: 100%. So, to position the image, you will need to use use an absolute value instead (forgoing the sliding-puzzle analogy altogether).

The reason it works with background-size: 50% is because the image is now given space to move around. At the same time, the sliding puzzle analogy now falls flat because the percentage values you've set for background-position are greater than 100%...

Anyway, in your specific example, the absolute values are equal to your element's width and height properties respectively (note: not the actual image dimensions):

div {
    background: url(image.png) no-repeat 250px 100px/100%;
    height: 100px;   /* half height of image */
    width: 250px;    /* half width of image */
}

Updated fiddle

If you cannot hardcode these values, e.g. if you need this effect to apply across elements of different sizes, then unfortunately you will not be able to use background-position to hide the image.

Community
  • 1
  • 1
BoltClock
  • 700,868
  • 160
  • 1,392
  • 1,356