Search code examples
javascripthtmlcssmedia-queriesgoogle-tag-manager

Change css property of a widget added via the google tag manager and loaded aynchronously in an iframe


I have added a widget on my web site that shows on the lower-right corner of the screen, but I'd rather it appeared on the bottom-left side. The google tag is a script like this

<script src="https://leadbooster-chat.pipedrive.com/assets/loader.js" async></script>

And after loading the script generates an iframe with appropriate css positioning

HTML

<iframe role="complementary" scrolling="no" id="LeadboosterContainer" class="proactiveChat" style="height:100px !important"></iframe>

CSS

@media (min-width: 576px)
<style>
html body #LeadboosterContainer {
    bottom: 28px !important;
    right: 28px !important;
}

It turns out the widget is not configurable via their interface to appear on the left hand screen (I'll send them a suggestion), but I have discovered that simply changing the right: 28px !important; to a left is enough to produce a quite acceptable behavior.

I'm aware that the developers may change this property in the future, and that the solution I'm thinking of would be a bit dirty, but is it possible to accurately target the CSS generated AFTER the widget is loaded via the script, and change the right to a left ? As you can see, the challenges here

  • The script is loading the HTML asynchronously
  • There is is a media query (and actually there are several rules that would need changing)
  • there is a !important flag which makes it harder to override this CSS rule in a brand new stylesheet
  • this is an iframe on another website... so we cannot do anything we want since security policies apply inside the iframe, and we only have the control on the iframe element itself for positioning

How can I do this ? I need to trigger an event after an async script has started, and then find a way to target media queries.

An example of what I'm thinking of adding to my google tag

// TODO : find a way to fire this code after the script has loaded / implement runAfterChatBotHasLoaded
runAfterChatBotHasLoaded( function() {
  var pipedriveBot = document.getElementById("LeadboosterContainer");
  // TODO : find a way to target each media query
  position = pipedriveBot.getAttribute('right');
  pipedriveBot.setAttribute('left', position)
  pipedriveBot.removeProperty('right'));
});

I have also tried


Solution

  • If the widget is in the iframe then you require either:

    • GTM in the iframe, not just the parent window
    • The post message api to securely call functions between the iframe and parent window (the parent window being where GTM is loading)

    If the css you are targeting is in the iframe then you need to treat it as a different website that doesn't have your GTM container loaded on it.

    If you're trying to move the iframe to the bottom left then this is working for me in a jsfiddle:

    var pipedriveBot = document.getElementById("LeadboosterContainer");
    
    // remove the styling
    pipedriveBot.style.setProperty('bottom', '0', 'important');
    
    // Add your own
    pipedriveBot.style.position = "fixed";
    pipedriveBot.style.left = "0px";
    

    See also this article on removing css properties that are set with !important: How can you remove an important CSS property?

    Let me know if I have understood correctly. If you need to wait until the DOM contains LeadboosterContainer then you can set a function to check the DOM periodically and then fire a function.