prebid / Prebid.js

Setup and manage header bidding advertising partners without writing code or confusing line items. Prebid.js is open source and free.
https://docs.prebid.org
Apache License 2.0
1.31k stars 2.07k forks source link

Fixed sizes for ads and Responsive Design #9314

Open espen-j opened 1 year ago

espen-j commented 1 year ago

Type of issue

Discussion I guess :)

Description

I've been pounding my head at this topic for a while now and I have not come to any conclusion that is satisfying. So I'd be glad to get any sort of feedback on this.

The business requirement

We have different kinds of formats (Banner ads) with different aspect ratios, that are responsive. Those ads should completely fill out whatever slot is given on a host page.

The technical issue: iFrame vs Responsive layouts

iFrames are not responsive - There's technically no way to get Ads truly responsive inside an iFrame on a host page. There are some corner cases where one could get it working, the best I could come up with is:

(Inspired by How can I make an iframe responsive? from this article) And just a note why this isn't a real solution either: You define a max-width on the Ad inside the iFrame the iFrame will still stretch the whole height. Wasting the space at the bottom.

Prebid's workaround to this problem

By defining fixed dimensions (e.g. 200x150px) for a given slot as part of the bid request (auction). The AdServer can then respond with an ad in the given dimensions and prebid will create/update the iFrame with the requested dimensions. The served Ad is displayed in that fixed slot. But there are still a bunch of problems with this, mainly the lack of responsiveness. Usually a lot of wasted space around the ads.

Our workaround to this problem

First off: We send arbitrary dimensions back (1x1 pixel, read on)

Second: We (others as well) do host page DOM manipulations:

We do that on all sites. Those manipulations are highly dependant on the DOM structure and the layout (CSS). So it's fragile and IMO also quite dangerous and not very scalable.

Responsive Ads: 1x1 pixel convention

(This was my biggest wtf moment.) As mentioned above, we get and return a 1x1 dimension from Prebid. This is apparently a convention for responsive ads. The problems with that: Prebid literally creates a 1x1 pixel iFrame for us and as a consequence we maximize the layout shifts in the hosts page. On top of that, if any of our manipulations fail, we will serve the ad inside a 1x1 pixel frame - so all parties involved lose.

Ideas

AFAICT there's no ideal solution for this, just compromises. Some thoughts:

(Looking into the code I see that native ads have different possibilites compared to banner ads. So maybe just aligning those would do.)

(There was also seamless frames: https://stackoverflow.com/a/5632609)

dgirardi commented 1 year ago

Prebid literally creates a 1x1 pixel iFrame for us

I am not sure that this is necessary (here's the logic) - but I'll need to try and dig into the reason why we're doing it.

If Prebid (and PUC) rendered directly inside the body of the "top" iframe, I believe you could achieve this with pure CSS (and maybe some GPT config).

espen-j commented 1 year ago

Thanks for your response. We mostly have friendly iframes, and not using PUC as it seems. Instead, this seems to be our entry to rendering: https://github.com/prebid/Prebid.js/blob/master/src/prebid.js#L555 We have Creative ${bid.creativeId} served by ${bid.bidder} Prebid.js Header Bidding above our ads usually.

If Prebid (and PUC) rendered directly inside the body of the "top" iframe, I believe you could achieve this with pure CSS (and maybe some GPT config).

That would be awesome, so far I haven't found a way.. I might be lacking some parts of the complete picture as well..

There's also bannerSize validation vs native formats. Which makes me wonder why native and banner ads are treated differently, after all the technical challenge is the same.

Then there's an additional module for size mappings, but that seems to be pushing a lot of complexity into the page layout definition: https://docs.prebid.org/dev-docs/modules/sizeMappingV2.html

Given the complexity of this topic, I think just solving that 1x1 pixel issue would already be of great help or just pointing me towards some official guidelines on how others solve this without doing black magic on the publishers sites.

I can also try to put together a Pull Request, but I'd like to have some sort of agreement before :)

patmmccann commented 1 year ago

Given the complexity of this topic, I think just solving that 1x1 pixel issue

Could you restate this issue succinctly? Is the issue that renderAd function create layout shifts?

The typical solution to this is to reserve space for the ad. For example, see Mediavine site dinner then dessert or Cafemedia site CafeDelites.

patmmccann commented 1 year ago

there's an additional module for size mappings, but that seems to be pushing a lot of complexity into the page layout definition: https://docs.prebid.org/dev-docs/modules/sizeMappingV2.html

Is this a different issue? we're debating how to react to your post because it seems to be a plethora of issues.

espen-j commented 1 year ago

Is the issue that renderAd function create layout shifts?

Not directly. It's that it in the case of banner ads, fixed width and height are mandatory attributes for prebid to create the iframe: https://github.com/c-wire/Prebid.js/blob/bd4a6703b43f25168865ef6eea18efbabb9bda8f/src/prebid.js#L559

This contradicts responsive designs IMO.

Could you restate this issue succinctly?

What I think would make this at least a bit less cumbersome is to have a way to opt out of the #setRenderSize function and instead just set width:100% on the iFrame, and leave the height calculation to the Ad.

Is this a different issue? we're debating how to react to your post because it seems to be a plethora of issues.

No, it seems to be a related module to this issue? But solving it with more configuration options. Generally, I feel like this topic is not very clearly documented. Also the fact that native ads have other options compared to banner ads.. even though it's technically the same issue.

dgirardi commented 1 year ago

I started looking into how to render with just one iframe so that you could make it "stretchy" more easily, but I stopped when I realized that you would need the cooperation of the creative itself (I think). The content of the iframe is, in general, arbitrary html; I'm not sure it's possible to say "I want you to fill out the whole iframe" without knowing a priori how it will be structured.

If in your particular case, if the iframe really is the show stopper, you can work around it by not using pbjs.renderAd and doing your own rendering directly from bidsBackHandler. The other options are native - which lets you ask directly for an image (for example) which you can style yourself; or sizeMapping, which lets you say "for these given viewport dimensions, I want my banners to be of this size".

espen-j commented 1 year ago

you would need the cooperation of the creative itself (I think). The content of the iframe is, in general, arbitrary html; I'm not sure it's possible to say "I want you to fill out the whole iframe" without knowing a priori how it will be structured.

That is correct. I tried to summarize this under The technical issue: iFrame vs Responsive layouts.

As for the alternatives you mentioned. I'll have a closer look, but generally, we do not control the sites we're embedded in. We provide a Prebid Adapter, that the publisher will embed in their pages. We have very little control over what can be done on that side, including whether we're embedded in Friendly iFrames or Safe Frames.

My conclusion on how this could work (in an ideal world, where iFrames are still needed):

Instead (or additionally) to defining fixed sized slots for the ads, e.g. sizes: [[200, 300], [350, 450]], Prebid.js could calculate the real dimensions of the given slot before sending the bid Requests to the ad servers. That way, the generated iFrame will fill out the complete parent HTML element (slot, as defined by bid.adUnitCode). And the responsive Ad and take whatever space given.

The caveats:

This would obviously need some collaboration from the publisher side.

I have this working in a prototype, implemented in the adapter and ad server.

dgirardi commented 1 year ago

I'll admit I did not realize you are coming from the POV of a buyer (or a creative author)? The issue I see with this then is, even if we manage to make it work for your particular creatives, a publisher could only rely on it only if every other buyer they deal with agrees to the same non-standardized banner format. I think it would make a lot more sense for them to ask for (and for you to provide) native instead, which is standardized and meant for finer control over the layout.

Even your last proposal - dynamically generating sizes - would not work in practice in most situations; a lot of exchanges can only deal with a predefined set of sizes.

espen-j commented 1 year ago

This was a topic in 2017 already: https://www.iab.com/wp-content/uploads/2017/07/IABNewAdPortfolio_Transition_Guide_2017-07.pdf

And there I see where this 1x1 pixel convention comes from :)

I think it would make a lot more sense for them to ask for (and for you to provide) native instead, which is standardized and meant for finer control over the layout.

I had a look at how native is implemented. With the dynamic renderer it might be a possibility. But our creatives are more complex than just static HTML and some template replacements.

Even your last proposal - dynamically generating sizes - would not work in practice in most situations; a lot of exchanges can only deal with a predefined set of sizes.

Doesn't have to be either or. It can be an additional flag/property that sends the calculated dimensions as payload. Or just allow to set the iframe width to 100%. With a ResizeObserver on the iframe > body the height of the iframe could be calculated as well.