はてなブログのスマホ版(モバイル版)で、横幅320pxのAdsenseとlinkwithin(レコメンドエンジン)がはみ出て、横スクロールが出てしまう問題(通称スマートフォン横スクロールガクガク問題)の対処法です。
ネットで引っかかる対応策が、情報が古いのもあるのか「?」な対応なものが多かったもので、わりとまじめに考えました。
結論
8/18 2:00 ブコメで指摘があったので、レスポンシブル対応に1行追加*1。このブログのスマホ版フッター(プロフィールの上)をレスポンシブルにしてみましたので参考までに*2
「ダッシュボード→設定→詳細設定→headに要素を追加」と選択
<style>
/* 342px(320px/93.75%)未満の横幅のとき、adsenseを10pxずらす */
@media screen and (max-width: 341px) {
.mobile-adsense {
position: relative;
width: 320px;
left: -10px;
}
}/* 382px(358px/93.75%)未満の横幅のとき、幅を100%にしてスクロールバーを出す */
@media screen and (max-width: 381px) {
div.linkwithin_outer {
width:100%;
overflow:scroll;
}
}
</style>
その上で、320pxのAdsenseを貼付けるときは、以下のように、コード全体をmobile-adsenseというクラスがついたdivで囲むこと(本文中でも記事上でも下でも同様の記述でOK)。レスポンシブルコードを貼付けた場合は、320pxのサイズも対象になります。
<div class="mobile-adsense">
adsenseの貼り付け用コード
</div>
これだけでOK!お試しあれ!
ここから下は面倒な解説なので読まなくてもOK
320pxのAdsenseはなんではみ出るのか
320pxのAdsense広告ユニット(モバイル バナー:320x50、ラージ モバイル バナー:320x100)を貼付けてiPhone4,5などの横幅320pxのデバイスでアクセスすると、微妙にバナーがはみ出て、そのために微妙な横スクロールが発生します。
そもそも横幅320pxのデバイスでアクセスして、なぜ320pxのコンテンツがズレるのか。
はてなブログモバイル版は、本文、ヘッダー、フッター含め、あらゆる箇所にwidth93.75%のsectionというcssクラスがつけられています。この93.75%、横幅が320pxの場合は300pxとなります。左右のmarginがautoなので、左右に10pxの余白ができます。
要するに、10px余白がある300pxの枠に無理やり320pxの要素をぶっこんでるので、結果として10px分が「はみ出る」状態になります*3。
まあそんな訳で、対処としては単純で「画面幅の93.75%が320px以下の場合」に無理矢理10px左にずらしてあげればよい、ということになり
/* 342px(320px/93.75%)未満の横幅のとき、adsenseを10pxずらす */
@media screen and (max-width: 341px) {
.mobile-adsense {
position: relative;
left: -10px;
}
}
こんな感じのコードになる訳です*4。
ネット上では、10pxの余白自体をなくすという意図のコードがいくつかありましたが、余白がないと画面端ぴったりで文章がはじまり、違和感がかなりあったのでよくないかと思います。(下図参照)
linkedwithinはなぜはみ出るのか
320pxのデバイスでアクセスしても、linkedwithinが幅358pxの要素をぶっ込んでくるからですww
いったいなぜww
358pxとは3記事分(118x3+4)の幅です。linkedwithinの埋め込みコードは、埋め込み場所の幅に応じて記事数をコントロールしているようです。たとえば、横幅420px(3記事は表示できるが、4記事は表示できない幅)の場合、正しく3記事表示され、4記事分がはみ出て埋め込まれるようなことはありません。
が、なぜか最低3記事は出すように制御されているようです。なんらかの矜持なのでしょうかw
ということで、親要素の幅を画面幅と合わせ、はみ出た分は(そこだけを)スクロールするという
/* 382px(358px/93.75%)未満の横幅のとき、幅を100%にしてスクロールバーを出す */
@media screen and (max-width: 381px) {
div.linkwithin_outer {
width:100%;
overflow:scroll;
}
}
このようなコードになります。
別案として、
/* 382px(358px/93.75%)未満の横幅のとき、内要素の幅を100%にする */
@media screen and (max-width: 381px) {
div.linkwithin_inner {
width:100% !important;
}
}
このように設定すると以下のような見た目になります。358px設定されている要素の幅を強制的に上書きして、(ブラウザの機能で)折り返しを実現してます。
この見た目にするんなら、どうせなら4つ出したくなりますよね?出せませんのでw
ネット上には237px、override:hiddenという設定がありますが、これは記事2つがちょうど表示される幅(237px)にあわせる設定です。3つめが途切れるくらいなら2つしか出さないようにするという意図です。
が、メディアクエリーをちゃんと指定しないと、4つ出せる幅がある(iPhone5横持ち時など)のに2つしか出ない、なんてことがおこるのでおすすめできません。
おわりに
ほかの人のブログ見ててもAdsenseに限らず、結構盛大にはみ出してたりするので、こんな細かいことを気にする人はあんまりいないのかもしれないですね。
Adsenseに限っていえば、10pxずれてても本文が見えなくなるってこともないですし。
このようなカスタマイズは親(はてなやlinkedwithin)側の仕様がいつ変更されるかわからないため、シンプルに短く、なるべく影響が及ばないように書くことをメインに考えました。
なにかの参考になれば幸いです。かしこ