Let’s say you have an element with a `background-image`, where only part of the image is visible, because the image is bigger than the element itself. The rest is cropped away, outside the element.

Now you want to move that `background-image` such that you’re focusing the center of the element on a specific point in it. You also want to do that with percentage values rather than pixels. We’re going to have to get clever.

### This is going to involve some math.

Let’s use this as our image, which has markers for sizing:

And here’s our element, with that `background-image` applied. Notice we can only see the (top) left of the image:

See the Pen Background Focus: no position by Jay (@jsit) on CodePen.

Now let’s say we want to align a specific point on the image with the center of that element. Say, the point at 300px in from the left.

Since we’re asking for this position in pixels, it’s straightforward. With no position defined, the `background-image` “starts” with the point at 100 pixels at the center, so you need to move it to the left by 200 pixels:

See the Pen Background Focus: pixel position by Jay (@jsit) on CodePen.

### Let’s formalize it.

The `x` value you’re using for `background-position` is calculated like so:

````(0.5 × ````[bounding box width]) - [x-coordinate]
0.5 × 200px -              300px
100px -              300px = -200px``````

It takes a second to figure out, but it’s nothing too taxing. You could have probably figured that out intuitively without needing to use a formula.

But what if you wanted to (or had to) express `background-position` as a percentage? Shouldn’t be too hard, right? Let’s try using a percentage to get ourselves centered at 300px again. We had a `background-position-x` of `-200px`, so let’s convert that to percent: -200 / 800 = -25%, so:

See the Pen Background Focus: percentage (1st attempt) by Jay (@jsit) on CodePen.

Hm. That didn’t work at all. Maybe we need to use a positive value?

See the Pen Background Focus: percentage (2nd attempt) by Jay (@jsit) on CodePen.

That’s better, but it’s centered at, like… 250px? How about as a percentage of the bounding box width: 300 / 200 = 150%. That can’t be right…

See the Pen Background Focus: percentage (3rd attempt) by Jay (@jsit) on CodePen.

Yeah, that’s not right.

Let’s back up. What happens if we do this?

See the Pen Background Focus: percentage (4th attempt) by Jay (@jsit) on CodePen.

That feels like it kind of makes sense; `background-position: 100% 0;` makes the `background-image` flush-right and centered at 700px, or 7/8 the width of the image. But what if we wanted to center it at 100%? I guess we’d have to do… 9/8?

See the Pen Background Focus: percentage (5th attempt) by Jay (@jsit) on CodePen.

At this point, I’m not surprised that didn’t work.

This doesn’t feel like the right path. Let’s back up.

### What does the spec say?

For example, with a value pair of ‘0% 0%’, the upper left corner of the image is aligned with the upper left corner of, usually, the box’s padding edge. A value pair of ‘100% 100%’ places the lower right corner of the image in the lower right corner of the area. With a value pair of ‘75% 50%’, the point 75% across and 50% down the image is to be placed at the point 75% across and 50% down the area.

### Maybe we can reverse-engineer this.

On that last one, 112.5%, it was aligning the point at 112.5% across the `background-image` with the point at 112.5% across the bounding box. That kind makes sense. The spec seems written to make it easy for only three values: 0%, 50%, and 100%. Any other value isn’t so intuitive.

With `background-position: 0;`, we were focused on 100px, or 12.5%. With `background-position: 100% 0;`, we were focused on 700px, or 87.5%. How does `background-position: 50% 0;` look, exactly?

See the Pen Background Focus: percentage (6th attempt) by Jay (@jsit) on CodePen.

50% is kind of like our “anchor” here; it’s the point at which our desired focal point and the corresponding `background-position` values are equal.

Let’s pretend we want to focus on 700px or 87.5%. We go 100% of the way from the center: 50% + 50%.

See the Pen Background Focus: percentage (4th attempt) by Jay (@jsit) on CodePen.

With `background-position` set to `100%`, the center of our bonding box has “panned” from the center of the image, 3/4 of the way to the rightmost edge (from 400px to 700px). If we want to “pan” to the rightmost edge, we need to go that extra 1/4, or 200px. 1/4 is 1/3 of 3/4, so we need to go a third more than we did a moment ago, or a total of 66.667% from the center:

See the Pen Background Focus: percentage (7th attempt) by Jay (@jsit) on CodePen.

Whew! So to focus on the rightmost edge of a `background-image` that is 4 times the size of our bounding box, we need to set `background-position: 116.667% 0;`.

How the heck are we supposed to figure that out?

It’s a difference of 16.667% from the 100% we might expect. So if we wanted to focus on our original goal of 300px (or, 37.5%), we’d, uh, add 16.667%? There’s no way this is going to work:

See the Pen Background Focus: percentage (8th attempt) by Jay (@jsit) on CodePen.

Nope.

If we wanted to focus on the leftmost edge, we’d probably subtract 16.667% from 0%, right? That sounds like it could be right.

See the Pen Background Focus: percentage (9th attempt) by Jay (@jsit) on CodePen.

Cool!

### To focus at 100% or 0%, you have to “overshoot” those values by a certain amount, when measured from the center.

So if we want to focus on 0%, or “100% of the way to the left of the center,” we have to subtract 66.667% from 50%. If we want to focus on 100%, or “100% of the way to the right of the center,” we have to add 66.667% to 50%.

I might have expected to have to add or subtract 50% to or from 50% to get to those edges: a 1:1 ratio of “how far I want to go from the center” to “what my `background-position` value should be.” But instead, we have to use a 4:3 ratio. In other words, we have to use a value four-thirds more “away from the center.”

Things are getting a little hairy here, so let’s introduce some terms:

• c: Desired focal point (in percent) from leftmost edge of background image
• z: Zoom factor (background width ÷ bounding box width)
• p: `background-position`, to focus on c, given z

So we take a focal point’s distance from the center (c − 50), multiply it by 4/3, then add that result to “the center,” or 50.

If you wanted to focus on the point at 600px (or 75%), my `background-position` value should be:

``(75% − 50%) × 4/3 + 50% = 83.333%``

See the Pen Background Focus: percentage (10th attempt) by Jay (@jsit) on CodePen.

Awesome!

And if you wanted to focus on 200px, or 25%, you would do:

``(25% − 50%) × 4/3 + 50% = 16.667%``

See the Pen Background Focus: percentage (11th attempt) by Jay (@jsit) on CodePen.

Wow.

### Let’s generalize this:

``(c − 50%) × 4/3 + 50% = p``

So why 4/3? 4 is the ratio of our `background-image` width to our bounding box width; and 3 is… 1 less than 4. Could it be that simple? Let’s try a larger `background-image`, this time 1000px wide, or 5 times the width of our bounding box. And let’s again try to focus on the point at 200px. Here our equation would be:

``(20% − 50%) × 5/4 + 50% = 12.5%``

See the Pen Background Focus: percentage (12th attempt) by Jay (@jsit) on CodePen.

Oh my god. It works!

``(c − 50%) × z/(z − 1) + 50% = p``

### Let’s turn this into English:

Given a point on a `background-image` at location c…

1. with c expressed as a percentage of the width of the image
2. where c is intended to lie in the horizontal center of the background image’s bounding box
3. and where the `background-image` is z times as wide as its bounding box

the correct `background-position` p (expressed as a percentage) is given by the following formula:

``(c − 50%) × z/(z − 1) + 50% = p``

### Can we generalize this even more?

What if we wanted to align the point at 25% of the `background-image` with the point at 75% of the bounding box? Yikes!

``(c − 50%) × z/(z − 1) + 50% = p``

Now let’s introduce some new terms:

• b: Desired focal point (in percent) from the leftmost edge of the bounding box. Earlier we had assumed this to always be 50% so that the center of the bounding box would be focused on our target in the `background-image`.
• d: `background-image` focal point (in percent) to align to bounding box’s midpoint in order to get c to align to b in the bounding box; if d of the `background-image` aligns with 50% of the bounding box, then c of the `background-image` will align with b of the bounding box.

### Let’s think of it this way

To want to align position c of a `background-image` with position b of a bounding box is to want to align some other position, d, of a `background-image` with the center of the bounding box – and we already know how to do that. So can we figure out a way to derive d, the spot we need to be at 50%, from c, b, and z? Sure!

With our 800px wide `background-image`, in a 200px-wide bounding box (z = 4), if we want to focus the rightmost edge of the bounding box (b = 100%) on the position at 600px (c = 75%) in the image, we would want the center of the bounding box to be focused on the point at 500px (d = 62.5%).

How do we get from c (75%) to d (62.5%)? Where does that -12.5% difference come from?

Well, our b was 100%, 50% greater than our old “default” b of 50%. And 12.5% is 1/4 of that; 1/4 is the inverse of our z of 4. Is that where our d comes from? That would be:

``d = c + (50% - b)/z``

Looks promising. Now we can substitute d in for c in the original formula:

``(d − 50%) × z/(z − 1) + 50% = p``

Or:

``(c + (50% − b)/z - 50%) × z/(z − 1) + 50% = p``

Whew! Let’s test this. Let’s try to align the position at 25% in our `background-image` (200px) with the position at 75% in our bounding box. This would be:

``````p = (25% + (50% - 75%)/4 - 50%) × 4/(4 - 1) + 50%
p = -31.25% × 1.333 + 50%
p = 8.333%``````

See the Pen Background Focus: percentage (13th attempt) by Jay (@jsit) on CodePen.

Unbelievable! Let’s double check. How about the point at 87.5% in our `background-image` (700px) aligned with the position at 33.333% in our bounding box:

``````p = (87.5% + (50% - 33.333%)/4 - 50%) × 4/(4 - 1) + 50%
p = 41.6667% × 1.333 + 50%
p = 105.555%``````

See the Pen Background Focus: percentage (14th attempt) by Jay (@jsit) on CodePen.

Looks good enough to me!

I’m sure there is something intuitive about this to certain types of people, but I am not one of those people.

### Let’s build a Sass function that will do all this ridiculous math for us.

See the Pen Background Focus: percentage (final Sass function) by Jay (@jsit) on CodePen.