!!! If anyone can answer this now, I will wait for the bounty period to end, and up it to 150 before awarding it. (Scouts honour!) !!!
I have looked around but can't find an answer to this question:
I am getting event cover images from fb api, and also storing the offset_x and offset_y values. Then I place the images as css background-images like this:
CSS
.event-image {
margin-bottom: 30px;
width: auto;
width: 500px;
height: 178px;
max-width: 100%;
min-width: 300px;
background-size: cover;
background-position: center center;
background-repeat: no-repeat;
outline: none;
}
The height/width is based on the exact ratio used by facebook: 2,8:1
HTML
<div class="event-image" style="background-image: url([url of img]); background-position: [offset_x]% [offset_y]%;" >
(I do have some internal logic that only adds the background-position property if there is one set in the fb api.)
The problem is that this only works 90% of the time. Roughly 10 % of the images are slightly miss-aligned. usually only by a few percentage points :-(
Here is an example.
.event-image {
margin-bottom: 30px;
width: auto;
width: 500px;
height: 178px;
max-width: 100%;
min-width: 300px;
background-size: cover;
background-position: center center;
background-repeat: no-repeat;
outline: none;
}
<div class="event-image" style="background-image: url(https://scontent.xx.fbcdn.net/t31.0-0/p180x540/14566476_1295215523823549_1334771895810946224_o.jpg); background-position: 0% 50%; "> </div>
<!-- Offsets are taken directly from API -->
Now here is the actual event
You can see that actually the offset would be perfect at 46% - so why is fb giving 50%?
The most info I can find is on pixel calculations, but considering I am using percentages, this wasn't useful.
EDIT
New issue implementing elfan's solution:
Here is an event on fb where the image has offset_x in the actual fb page of -7px - but according the api, the offset_x = 50%
{
"cover": {
"offset_x": 50,
"offset_y": 0,
"source": "https://scontent.xx.fbcdn.net/t31.0-8/s720x720/14681104_1307094859330152_7540791723420117074_o.jpg",
"id": "1307094859330152"
},
"id": "544220282434185"
}
So, using the calculation 500px (width of my image) * offset_x % = 250px
What am I doing wrong :-)
I have also noticed that there are some events which have crazy offsets, like 1800 for example. According to fb docs, it should be between 0-100.
There is a problem with the interpretation.
The value 50
from fb api apparently refers to the offset in percentage as when using it in top
, which means percentage of the containing block's height (spec here). And that is different to when using it in background-position
(spec here). There is also an article here that visually shows the difference.
If you want to use background-position
, the solution is to use px
.
Alternatively, you can use top
, either as %
or px
.
I have made the following code to compare your code, fb code, and what the fix should be (for all alternatives):
/* Your original code */
.event-image {
width: 500px;
height: 178px;
background-size: cover;
background-image: url("https://scontent-sit4-1.xx.fbcdn.net/t31.0-0/p600x600/14566476_1295215523823549_1334771895810946224_o.jpg");
background-position: 0 50%; /* "50" is from fb api, but not used correctly */
}
/* FB actual code */
.cover {
width: 826px;
height: 294px;
position: relative;
overflow: hidden;
}
.cover img {
position: absolute;
width: 100%;
left: 0;
top: -147px; /* 294px * 50% = 147px, this is the correct usage of "50" from fb api */
}
/* Your code if showing as big as FB image */
.bigger-image {
width: 826px;
height: 294px;
background-size: cover;
background-image: url("https://scontent-sit4-1.xx.fbcdn.net/t31.0-0/p600x600/14566476_1295215523823549_1334771895810946224_o.jpg");
background-position: 0 50%; /* "50" is from fb api, but not used correctly */
}
/* The correct code using "background-position" */
.correct-image {
width: 500px;
height: 178px;
background-size: cover;
background-image: url("https://scontent-sit4-1.xx.fbcdn.net/t31.0-0/p600x600/14566476_1295215523823549_1334771895810946224_o.jpg");
background-position: 0 -89px; /* 178px * 50% = 89px, this is the correct usage of "50" from fb api */
}
/* The correct code using "top" in pct */
.correct-cover {
width: 500px;
height: 178px;
position: relative;
overflow: hidden;
}
.correct-cover img.pct {
position: absolute;
width: 100%;
left: 0;
top: -50%; /* the correct usage of "50" from fb api */
}
/* The correct code using "top" in px */
.correct-cover img.px {
position: absolute;
width: 100%;
left: 0;
top: -89px; /* 178px * 50% = 89px, this is the correct usage of "50" from fb api */
}
<h3>Your original code</h3>
<div class="event-image"></div>
<br />
<h3>FB actual code</h3>
<div class="cover">
<img src="https://scontent-sit4-1.xx.fbcdn.net/t31.0-0/p600x600/14566476_1295215523823549_1334771895810946224_o.jpg" />
</div>
<br />
<h3>Your code if showing as big as FB image</h3>
<div class="bigger-image"></div>
<br />
<h3>The correct code using "background-position"</h3>
<div class="correct-image"></div>
<br />
<h3>The correct code using "top" in pct</h3>
<div class="correct-cover">
<img class="pct" src="https://scontent-sit4-1.xx.fbcdn.net/t31.0-0/p600x600/14566476_1295215523823549_1334771895810946224_o.jpg" />
</div>
<br />
<h3>The correct code using "top" in px</h3>
<div class="correct-cover">
<img class="px" src="https://scontent-sit4-1.xx.fbcdn.net/t31.0-0/p600x600/14566476_1295215523823549_1334771895810946224_o.jpg" />
</div>
<br />
Additional explanation about why 46% looks correct in your original code:
background-position: 0%
is the same as top: 0px
background-position: 100%
is the same as top: -197px
background-position: 50%
is the same as top: -98.5px
(197 x 50%)
background-position: 46%
is the same as top: -90.62px
(197 x 46%), while the correct one is top: -89px
, so that looks close enough.
Where does 197
come from?
The box size is 500 x 178px. The actual image size is 800 x 600px. The rendered/scaled image size due to background-size: cover
is 500 x 375px.
The image height is 375-178 = 197px larger than the box height. Remember that when using background-position: 100%
, the bottom edge of the image will meet the bottom edge of the box, which means top: -197px
.