Twitter埋め込みツイートの表示崩れをCSSセレクタで回避する

Twitterの埋め込みコードが既存のCSSとバッティングすると描画の書き換えが余分に発生することがあります。ガタガタして読みにくいのでCSSセレクタで回避しましょう。

Twitter埋め込みツイートの表示崩れをCSSセレクタで回避する

特定ツイートをWEBサイトに表示させるときは、Twitter公式のツイート埋め込みにて行います。

ただしツイートの全文が <blockquote> タグで囲われているため、既存の引用タグにクラスが割り振られていないとCSSがバッティングして何度もレンダリングすることになります。リソースの無駄だし何となくカッコ悪いことになりがち。

自前のコードにはクラスを割り振って棲み分けるのが一番なんですが、長くサイトをやっていて古い資産がたくさんある場合は遡るのも大変です。

そんなときにCSSセレクタでフィルタリングする方法です。

ツイートの非同期読み込みとCSS描画タイミング

Twitterで埋め込み用のコードを出力すると、以下のような形式のものが得られます。

【HTML】
<blockquote class="twitter-tweet" data-lang="ja">本文</blockquote>
<script async src="//platform.twitter.com/widgets.js" charset="utf-8"></script>

ここで問題になるのは、運営サイトのCSSが <blockquote> 全体にスタイルを効かせている場合です。ページデータのロード中とロード完了後で何度も画面描画を書き換える現象が発生してしまいます。

具体的に症状を確認しましょう。

ページロード中の適用スタイル

例えば、現状で blockquote に次のようなスタイルを適用していたとします。

【CSS】
<style>
blockquote {
  border: 1px dotted #993;
  border-radius: 5px;
}
</style>

引用部分全体のボックスにカーキ色の点線が縁取られる形です。この状態でツイートの埋め込みコードを貼り付けると、まず最初にサイト内のCSSが適用されます。

blockquote指定中のツイート読み込み
サイト読み込み途中でツイートに自サイトのCSSが適用された状態

ページロード完了後の適用スタイル

ページがロードし終わると非同期で読み込まれたJavaScriptが発動してTwitter側のCSSが読み込まれます。

ロード完了後の埋め込みツイート
同じツイートにTwitter側のCSSが適用された状態

貼り付けたツイートが記事の下の方にあるなら良いのですが、ファーストビューに置くとパラパラマンガみたいに何度も描画の書き換えが起こります。これが非常に読みづらい。

以前は引用したツイートにもある程度の指定が効いた気がするのですが、いつのまにか変更出来なくなってました。Twitter社はUXを共通化したいようなので不可逆な流れなのかも知れません。

!important 指定した場合の適用スタイル

ちなみに !important 指定によって無理やりスタイルを固定しようとするとどうなるかというと、絶妙な感じにどうにもなりません。

!imoportant指定した場合のツイート
!important 指定した例

CSS3のセレクタを使ったTwitterの除外指定

幸いにも class="twitter-tweet" というクラスが割り振られているので、 <blockquote> に対する指定のうちTwitterだけ外してしまえばOKです。

【CSS】
<style>
blockquote:not([class="twitter-tweet"]) {
  // お好みの装飾
}
</style>

CSS3 セレクタを使ってるのでモダンブラウザ奨励ですが、事実上問題なく使えるはずです。特定のクラスを除外するためのCSSセレクタですから、他SNSの埋め込み投稿にも流用可能です。

動作確認とデモ

参考までに、このソースでツイート埋め込みと通常引用がどのように表示されるかの動作を確認しておきます。

サンプルソース

【HTML】
<blockquote class="twitter-tweet" lang="ja"> ツイートの中身 </blockquote>
<script async src="//platform.twitter.com/widgets.js" charset="utf-8"></script>

<blockquote> test </blockquote>

引用のブロックを二つ用意します。上部がTwitterの埋め込みコード、下部が通常の引用文です。

これに加えてセレクタでTwitterを除外したスタイルを用意します。

【CSS】
<style>
blockquote:not([class="twitter-tweet"]) {
  border: 1px dotted #993;
  border-radius: 5px;
}
</style>

ページロード中の表示

除外指定した上でのツイート読み込みロード中
読み込み中のツイートと通常引用文

ページロード完了後

除外指定してツイート埋め込み完了
読み込み完了後のツイートと通常引用文

埋め込みツイートが非同期JavaScriptで読み込まれてるため、完全に表示崩れによるガタガタを避けることは出来ません。しかし、ひとまず余分な書き換えは発生しなくなりました。

!important による動作確認

【本章追記:2016/02/12】Twitterがちょいちょい仕様を変えるので、現状の動作確認のために実動デモ置いておきます。

【CSS】
.twitter-tweet {
  border: 1px dotted #993 !important;
  width: 100% !important;
  }

ツイート引用に影響する引用指定
要素 !important 最終結果
blockquote あり Twitter標準
blockquote なし Twitter標準
.twitter-tweet あり 無理やり同居
.twitter-tweet なし Twitter標準

おわりに

…ということでスッキリ表示できるようになりました。ツイート埋め込みのガタガタ感が苦手な方は試してみて下さい。

以上、おち(@02320_ochi)でした!

【 更新履歴等 】

2014/05/21 初稿発表
2016/02/12 改題&動作確認章を追記しました
旧題:.twitter-tweetのみBLOCKQUOTE指定を無効にするCSS
419 / 旧URL /2014/05/21/optout_twitter_tweet/
旧はてブ:.twitter-tweetのみBLOCKQUOTE指定を無効にするCSS2users