I learned something the other day when we were fleshing out the background properties in the Almanac. It’s such an intuitive thing, that I guess I just never stopped to think about it before.
By default, background-position is 0 0
, the top left
corner. Now imagine you set it to 50% 0
. That background image is now center top. It figures out the size of that image, and positions the center of it at the center of the element.
That’s different than if you, say, had an <img>
and positioned it at left: 50%;
in that scenario, the left edge of the image would be at the halfway point. If you want to center it, you’ll need to pull it back to the left (negative translate or negative margin).
Here’s a visualization of that difference:
See the Pen The Difference Between background-position and left by Chris Coyier (@chriscoyier) on CodePen.
So if you set something like background-position: 25% 25%
, that positions the image such that 25% of the way across itself aligns with 25% of the way across the element. And the same vertically.
Nothing revolutionary here. I just think it’s cleverly designed. You don’t have to think about it much, because it just works like you would assume it works. Of course if I set right top
for the background-position the image is drawn in the right top corner. I don’t think about how the browser must be calculating the image size and the element size and aligning axises at those positions.
Interesting…
One problem with the way background-position works is if you want negative positions (like for image sprites). Then, it’s a little confusing, and not well defined in the specs.
I generally use px (and -px) for sprites, as it is much more precise. Then in developer tools, you can just position and copy back to your code.
Specially sprites with images that I’d like to contain a background of a block or inline-block element, that’s confusing me too. Couldn’t find a way to make it work…
I always use percentages now, especially with responsive with all my CSS (except sprites, seems less complicated to just use pixels. Thanks for share!
Spec authors actually know what they’re talking about, huh? :) You can kinda do this with an actual image too. It’s a hack, but you can simulate this behavior with
left
andtransform
:Timothy, are you sure what you’re talking about, huh? :)
Looks right to me Patryk?
Great call Timothy. Patryk, don’t forget to include the vendor prefixes if you’re using it on Safari or Firefox.
-webkit-transform
is required and it does indeed work.Yes Patryk, I guess he knows what he is saying…
Thanks, Timothy, this will come in handy. :)
This is so simple. It works well in Firefox and Chrome, and IE down to 9. Any suggestions for IE below 9?
Thanks for backing me up, guys. :) Robert, I think just about your only option with IE<9 is tables (CSS table layout, probably not actual tables). Like this. It isn’t as nice, and might take a little more work, but if you aren’t doing anything too crazy it works pretty well!
| You don’t have to think about it much, because it just works like you would assume it works.
Actually, when using % in background-position, the behavior changes depending on the background-size. As in your example, the background image is smaller than the container it is used in, and an increment in x-axis will make the background move to the right. However, if you set background-position to a larger size than it’s container, then an increment in x-axis will move it to the left. I haven’t tried changing values for y-axis but I assume it’s the same thing.
And now I’m thinking about how to set the background image position with percentage units starting from the bottom–right position.
I think it gets a bit more complex once you also set background-size in percentage :)
getting an extra value to set distance FROM right would be great to have, that’s the only thing missing
Check out the four-value syntax: https://css-tricks.com/almanac/properties/b/background-position/
Thanks. Got it working now. Here’s another way:
What would make the whole background specification work better is if you could tell it to maintain the ratio of the background image’s dimensions. I guess this is really more about background-size. So maybe background-size:50% keep-ratio/true; could work. And also something like bg-size:fit keep-ratio/true; would be nice.
Try
background-size:50% auto;
Here’s a related background-position trick with percentages that I’ve found very useful:
This will load a background image that will cover the entire div, then fix a point in the image at a percentage position in the div (the point in the image 25% across the image and 75% down will stay at 25%/75% in the div). This means that you can load an image with a focal point, and make sure that point stays visible no matter what the aspect ratio of the containing div is.
An example with a very tall image, used in a div that changes size and shape at different breakpoints: http://www.oc.edu/alumni/vision/summer-2014/oc-grad-lost-on-malaysia-flight/
What you guys are really after is jQuery focus point: http://jonom.github.io/jquery-focuspoint/demos/helper/index.html
Nice! I made that tool for Jonom’s very cool plugin! Glad someone like it!