Adsense広告がはみ出る問題とその対処法
8分目次
結論
先に結論から言うとWordPressでこの問題に直面している場合、どうしても広告を途切れさせたくない人はテーマの変更がオススメです。十中八九、原因となっているのはflex
と言う技術によるものです。
解決策一覧
- こちらの方法を用いる
- テーマを変更する
- flexを取り除く
問題確認環境
- Chrome
- Mac
👆Adsense広告がはみ出てしまう問題を観測した 👆Firefox/Safariでは上手く動作しており、問題が起こっていないものの…… 👆Chromeでは何度やっても確認される。シークレットモードでも問題を確認した。
ただし、ChromeとMacの組み合わせだとしても、ブラウザの横幅サイズによっては正しく表示される。使用しているテーマによるが『十二単』においては体感900〜1000px前後の横幅の時にのみ問題が確認された。ブレークポイントが960pxで設定されており、タブレットでは確認されなかったため、961px以上〜1000px前後あたり。
手取り早く直したい人向けの対処方法
1. 広告をレスポンシブではなくす
Adsense広告を挿入する時に赤線の部分のtrue
をfalse
に書き換えます。
<!-- 例 -->
<ins class="adsbygoogle"
== 省略 ==
data-full-width-responsive="false"></ins>
<script>
(adsbygoogle = window.adsbygoogle || []).push({});
</script>
これはAdsenseが公式に承認している方法です。これをすることによって横幅目一杯に広告が広がる機能がなくなります。ただし、その分広告が小さくなると言うことなので収益が落ちてしまう可能性もあります。
2. 親要素を付け加える
広告を貼り付ける際に広告をhtml±<div class="ad_hidden">ここに広告コード</div>
こんなふうに囲んであげましょう。
<!-- 例 -->
<div class="ad_hidden">
<ins class="adsbygoogle"
== 省略 ==
(adsbygoogle = window.adsbygoogle || []).push({});
</script>
</div>
👆続いて、外観>カスタマイズ>追加CSS に下記コードを追加します。
.ad_hidden {
width: 100%;
overflow: scroll;
}
スクロールバーを表示したくない場合はコチラ👇を使用しましょう。
.ad_hidden{
width: 100%;
overflow: scroll;
-ms-overflow-style: none;
scrollbar-width: none;
}
.ad_hidden::-webkit-scrollbar {
display:none;
}
すると、はみ出た部分はスクロールで見れるようになります。
問題がなぜ起こっているか
まず『なぜ起こっているか』の前に『どこで起こっているか』だが、Adsenseの広告コードは、
<ins>
<ins id="aswift_X_expand">
<ins id="aswift_X_anchor">
<iframe>ここに広告が挿入される</iframe>
</ins>
</ins>
</ins>
<!-- Xの部分はページ内にある何番目の広告かを示す数字 -->
と言う構造で成り立っている。
ins
はinsert(挿入)された要素であることを示すタグですね
二層目のins#aswift_X_expand
で親要素ins
のscrollWidth
から横幅を取得し、多分その横幅をstyleとしてタグ内に追記している。
<!-- 👆のイメージが 👇 -->
<ins>
<ins id="aswift_X_expand" style="display:inline-table;border:none;height:90px;margin:0;padding:0;position:relative;visibility:visible;width:651px;background-color:transparent;">
<!-- ✂︎SNIP -->
</ins>
で、このとき、ins
タグのscrollWidth
が実際の横幅と異なっているとAdsenseの広告がずれると言う問題が発生する。
おまけに、ins#aswift_X_expand
タグ以下の階層のタグはins#aswift_X_expand
タグの横幅にしたがって横幅が決定していくからここが修正の肝になる。
図解
少し文字による説明が多くなったので図を挟む。
👆 まず一つ目のinsタグで実際の横幅と異なる横幅が内部的に取得される
👆 左画像矢印部分が件の内部的に異なる値。offsetWidth
とclientWidth
は実際の横幅と同じ560pxが取得できている。scrollWidth(=765)
が実際の横幅と異なる。
👆 そして、実際の横幅と異なる値(ここでは765)が次の階層のins#aswift_X_expand
にwidthとして挿入されてしまう。
offsetWidthとclientWidthとscrollWidthについて
offsetWidth
等々これらは全て要素の横幅を取得するものだ。
offsetWidth | width + padding + border |
clientWidth | width + padding ( + 擬似要素) |
scrollWidth | width + padding |
上記のルールに従うと、擬似要素がない場合において通常scrollWidth
はclientWidth
と同じになる(のが本来の正しい在り方)。
参考: http://jsfiddle.net/y8Y32/25/
ただ、今回僕のケースでは横スクロール部分があったわけではないし、おそらく多くの人のケースでもそうだろう。じゃあなぜ今回scrollWidth
の値がバグったかと言うとflex
の存在だ。display:flex;
を指定すれば横幅の値がよしなに設定される。今回のケースでいうと僕はmain
とaside
をflex
の子要素としていた。
<div class="wrap">
<main>ここに記事などのコンテンツ</main>
<aside>サイドバー</aside>
</div>
<style>
.wrap {
display: flex;
}
main {
width: 75%;
}
aside {
width: 25%;
}
</style>
これ自体にはおそらく問題はないのだが、asideの方は広告を設定することや25%だと場合によっては見栄えが悪くなることを見通し、min-widthを指定していた。
<div class="wrap">
<main>ここに記事などのコンテンツ</main>
<aside>サイドバー</aside>
</div>
<style>
.wrap {
display: flex;
}
main {
width: 75%;
}
aside {
width: 25%;
min-width: 320px;
}
</style>
すると、当然main
は横幅75%を確保できず縮む場合がある。この縮みこそがflex
の柔軟性もとい強みでもあるのだが今回のケースのようにscrollWidth
をバグらせることもあるらしい。
When you use display:flex on some element that acts as a container, the elements inside that container will shrink in width to fit the container's width. This is actually the essence of flexbox and it is important is you want to make a responsive layout.
However, you can use flex-shrink: 0 to prevent this for some particular element, but I'm not sure why you would want that.
https://stackoverflow.com/questions/56470839/incorrect-scrollwidth-on-child-of-flex-container
原因はわかったものの、flexを除く対処方法を取ると、メインエリアとサイドバーの値を決められる機能がなくなると言うデメリットがあるに加え、問題の起こる環境がChromeの960px〜1000px前後までと限られることを踏まえ、ウィジェットを追加することで対処した。
余談
記事冒頭でFirefoxやSafariでは問題が確認されなかった、と記述しています。これはブラウザによってscrollWidth
など各種の仕様が若干異なることに起因するそう。なんて面倒な……。
まとめ
いろいろ対応させすぎるとこういう問題に直面するんだなぁ~