Make the Facebook Like flyover appear on top and to the left of the Like button
New here? Learn about Bountify and follow @bountify to get notified of new bounties! x

Bountify.co has a Facebook Like button in the footer. Unfortunately, the flyover that appears when the button is clicked is partially offscreen, so users can't click "submit" or "cancel". Please provide the CSS to make the flyover appear on top and to the left of the Like button instead.

I understand that Facebook's iframe contents are out of my control, but I'd like to style its contents nonetheless.

I'll tip $5 if you can make the caret (the triangle thing on the flyover that points to the Like button when it's clicked) appear correctly.

Thanks in advance! Let me know if you have any questions before starting.

Edit

Thanks for the responses. Looks like the same origin policy will make this really hard in practice. No need to submit any more solutions, going to use @sam's solution (to prevent the dialog from opening at all).

@bevan, why not compare popup position + width with currrent page width and then if page width above - change css accordingly? jQuery().offset + jQuery().width, and then change jQuery.top or left
EvgeniS almost 7 years ago
awarded to Wikimedia

Crowdsource coding tasks.

7 Solutions


to the wrapper div

add the appropriate style below
.inline-block{
overflow: hidden;
width: 100px;
}

mostly FB button in footer is rendered via iframe so giving a style for fb element is not a permanent solution. as if something changes on fb side your css will break..so normally we fixed on our website using the above solution.

I understand that the iframe contents are outside of my control. Nevertheless, I'd still like to style it for now, rather than simply prevent the flyover from opening. Thanks.
bevan almost 7 years ago

Try to add this to CSS, then wrote me about results.
Other way, i can access remote iframes with jquery.

.fb _ edge _ comment _ widget {
margin-left: -350px;
}

(remove spaces in selector name please)

Good luck!

Unfortunately this does not seem to have any effect.
bevan almost 7 years ago

If you want such result
http://s18.postimage.org/m4vznhd0p/image.png

here is css

.fb_edge_widget_with_comment{
position: relative!important;
top: -215px!important;
}
.fb_iframe_widget iframe{
height: 235px!important;
}

THIS must be appended to iframe

.fbpfet .fbpfnb {
top: 161px!important;
transform: rotate(180deg);
-ms-transform: rotate(180deg); /* IE 9 /
-webkit-transform: rotate(180deg); /
Safari and Chrome /
-o-transform: rotate(180deg); /
Opera /
-moz-transform: rotate(180deg); /
Firefox */
}

To append css styles to iframe you can use this code

var cssLink = document.createElement("link")
cssLink.href = "style.css";
cssLink .rel = "stylesheet";
cssLink .type = "text/css";
frames['frame1'].document.body.appendChild(cssLink);

that is cool..
sam almost 7 years ago
This is very close to what I want. Can you make it open to the left of the button, instead of to the right? The flyover should still cover the top of the button. Thanks.
bevan almost 7 years ago
ok, np. Will try to do soon.
ssleptsov almost 7 years ago
@ssleptsov The solution doesn't appear to work as in the picture. Right now it looks like this: http://snag.gy/s2VSP.jpg, and the flyover opens as before (bottom right). The facebook iframe isn't being selected. Any ideas?
bevan almost 7 years ago

try to remove from css class
.fb_ iframe _widget
{
position:relative // remove this line
}

then wrote me about results.
Edit
Try also delete

.fb_ edge_ widget_ with _comment
{
position:relative
}

Unfortunately this does not seem to have any effect.
bevan almost 7 years ago
try delete from css .fbedgewidgetwithcomment this position:relative
EvgeniS almost 7 years ago

Now if i delete .fb_ iframe_ widget iframe {position:absolute} , button visible.
Try this, please

@EvgeniS, when I remove that style, the footer is extended and the button becomes visible. However, I'd like the code to make the flyout appear on the top and to the left of the button. Thanks for trying!
bevan almost 7 years ago
Thanks for comment, now i understand what you want)
EvgeniS almost 7 years ago

You probably will not be able to change the position successfully because of Same Origin Policy which makes it (virtually) impossible to change data in the iframe, because you would get an error message similar to this:

Unsafe JavaScript attempt to access frame with URL https://www.fac...text=false from frame with URL https://bountify.co. Domains, protocols and ports must match.

If you can find a way to 'bridge' your site to the iframe this code below should work:

$("iframe.fb_ltr").css("top", "-200px").css("left", "-420px").css("height", "189px").css("width", "600px");
$("iframe.fb_ltr").contents().find("table.pluginConnectButtonLayoutRoot div").css("position", "relative").css("top", "200px").css("left", "420px");
$("iframe.fb_ltr").contents().find("div.fbpfnb").css("position", "relative").css("top", "161px").css("left", "420px").css("-webkit-transform", "rotate(180deg)").css("-moz-transform", "rotate(180deg)").css("-ms-transform", "rotate(180deg)").css("-o-transform", "rotate(180deg)").css("transform", "rotate(180deg)");

Here is a "pretty" version of the CSS appended.

iframe.fb_ltr {
    top: -200px;
    left: -420px;
    height: 189px;
    width: 600px;
}

table.pluginConnectButtonLayoutRoot tbody tr td div {
    position: relative;
    top: 200px;
    left: 420px;
}

div.fbpfnb {
    left: 420px;
    top: 161px; 
    -webkit-transform: rotate(180deg);
    -moz-transform: rotate(180deg);
    -ms-transform: rotate(180deg);
    -o-transform: rotate(180deg);
    transform: rotate(180deg);
}

Notes

@alex, thanks for the attempt and the clear explanation. Couldn't get it working in FF or Chrome, the css moves the actual button to the upper left: http://snag.gy/GO2bK.jpg. Anyway, looks like the SOP is going to be problematic so I'll just implement @sam's solution above (preventing the flyover from opening) or possibly relocate the button later. Thanks for your help!
bevan almost 7 years ago
@bevan Anytime!
alex almost 7 years ago

Actually, it's possible.

Our solution do more than just having the Facebook Like dialog appear above, it's also fully asynchronous, thus non blocking for the page, it automatically create the right url entry so the same javascript is used in all our pages, and it update and show it only after the actual size is known, thus killing 3 birds with one stone.

1) we include in all our pages an "empty" div that is than filled in javascript:
<div id="social-media-bar"><div id="social-media"></div></div>

PS: the reason for 2 levels of div is because I will later extend this to google+, twitter etc

2) we load facebook asynchronously

using LazyLoad loader but any will do and you can also do synchronous if you want:
LazyLoad.js(('https:' == document.location.protocol ? 'https://' : 'http://') +
'connect.facebook.net/en_US/all.js');

3) in the facebook init, we:

- fill the dedicated div,

- ask fb to parse the inserted tags

- use a timeout after parsing to ensure display has been refreshed and thus widht and height are correct.

window.fbAsyncInit = function() { 
        var d = document,n,nn,url,url_ref,i;`

        // due to bug in facebook need to delay the actual access to data after parse
        function FBUpdateSize(){
            var h,str;
            // show facebook entry using actual element size
            h = nn.firstChild.clientHeight;
            str = h+'px';
            nn.style.height= str;
            n.style.height= str;
            n.style.overflow='visible';
        }

        FB.init({   channelUrl : 'http://www.plixo.com.sg/channel.html',
                    //appId : '228760567272221', 
                    status     : false,
                    xfbml      : false}); 

        // create facebook entries in the DOM
        n = d.getElementById('social-media');
        url = d.URL;
        i = url.lastIndexOf('/')+1;
        url_ref = url.slice(i,url.indexOf('.',i));
        nn = d.createElement('fb-like');
        nn.innerHTML = '<div id="fb_like_bottom"><fb:like href="' + url + '" ref="' + url_ref + '" send="false" layout="standard" width="360px" show_faces="false"></fb:like></div>';
        nn = n.appendChild(nn);

        // call facebook to fill DOM entries
        // use a timeout in callback to ensure browser has refreshed internal clientHeight
        FB.XFBML.parse(nn,function(){setTimeout(FBUpdateSize,50)});
    };`

4) and only 3 dedicated css styles:

#social-media{position:relative;display:block;width:auto;z-index:200;overflow:hidden;height:0;
background-color:#f2f2f2;border:1px solid #bdc7d8}


#fb_like_bottom{padding:4px;position:absolute}

#fb_like_bottom .fb_iframe_widget_lift{bottom:0;background-color:#f2f2f2;border:1px solid #bdc7d8
!important;margin:-5px;padding:4px}

You can look at an example in any of our website pages, ex, http://www.plixo.com.sg/large-format-printing-services.html.

Feel free to reuse/modify etc, will just appreciate if you link to any of our page ;-)

View Timeline