skip to Main Content

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

2

Answers


  1. I have seen this method being used in regards to offsets from FB.

    FB.api(artist, function (data) {
        $('.ed-cover img').attr('src', data.cover.source)
        .css("top", (-1 * data.cover.offset_y) + '%');
    });
    
    Login or Signup to reply.
  2. 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.

    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search