当Webサイト内、Web制作&システム開発サイトの制作実績ページで表示しているWebページのサムネイル。当初はサムネイル自動生成ツールを使用していました。その後、半年前から各々の制作実績のページでレスポンシブ Web デザインによる PC、タブレット、スマホそれぞれの画面を表示するようにしたのですが、サムネイル自動生成ツールではPC画面を縮小して取得することしかできず。仕方なく、それぞれのスクリーンショットを撮って貼り付けてました。

しかし、新しいサイトを追加する度に3種類のスクリーンショットを撮る必要がありますし、時が経つとスクリーンショットが古くなるので定期的に撮り直す必要があり。そこで、少々強引ですが、Webページそのものの PC、タブレット、スマホそれぞれのサイズの画面を、インラインフレーム( iframe タグ)で埋め込んで表示することにしました。

ただ、それぞれのサイズのWebページをサムネイルのように縮小表示する必要があり、更にレスポンシブにも対応させる必要がありました。

まず、HTML で PC、タブレット、スマホそれぞれの画面サイズで iframe にWebページを埋め込みます。iframe で別のWebページを埋め込む場合、widthheight でフレームサイズを指定すれば、その画面サイズで表示したWebページが埋め込まれます。例えば、width="1280" とすればPC画面、width="768" とすればタブレット、width="375" とすればスマホ画面という具合です。

iframe で表示したいサイズが 800px × 500px だからと width="800" とすると、単に 800px の画面幅のWebページが表示されますので、とりあえず取得したい画面サイズで widthheight を指定します。
CSS のコードは省略しますが、外側の div に対して各デバイスの枠の位置や領域、フレーム画像などを設定しています。

<div class="pc">
<div class="frame">
<iframe src="https://www.example.jp/" width="1280" height="800" title="PC画面"></iframe>
</div>
</div>
<div class="tb">
<div class="frame">
<iframe src="https://www.example.jp/" width="768" height="1024" title="タブレット画面"></iframe>
</div>
</div>
<div class="sp">
<div class="frame">
<iframe src="https://www.example.jp/" width="375" height="667" title="スマホ画面"></iframe>
</div>
</div>

これで各サイズのWebページが埋め込み表示されますが、このままでは、埋め込んだWebページが枠から大きくはみ出しますので、CSS3 の transform:scale() を使って iframe を縮小します。その際、transform-origin で起点を左上(0, 0)に設定します。

また、レスポンシブに合わせて枠の高さを幅に比例して縮小する必要があるので、hieght0 にして padding-top で幅との比率による高さを設定し、iframe の位置をネガティブマージンで戻しています。

.frame {
  height: 0;
  overflow: hidden;
}
.pc .frame {
  padding-top: 62.5%;
}
.tb .frame {
  padding-top: 133.33%;
}
.sp .frame {
  padding-top: 177.87%;
}

iframe {
  transform-origin: 0 0;
}
.pc iframe {
  margin-top: -62.5%;
  transform: scale(0.6);
}
.tb iframe {
  margin-top: -133.33%;
  transform: scale(0.5586);
}
.sp iframe {
  margin-top: -177.87%;
  transform: scale(0.6613);
}

これでPCサイズではきれいに表示されますが、さらにレスポンシブ Web デザインに対応させる必要があります。iframe 内に埋め込んだWebページのレスポンシブではなく、iframe を表示した親ページのレスポンシブです。つまり、縮小表示した iframe 内のWebページを画面サイズに連動して更に縮小表示するということです。

transform:scale() の値に calc を使ってどうにかしようと試みましたが、どうもこの場合は計算式に vwpx を使うと正しく機能しません。そもそも計算が複雑すぎます。

そこで、jQuery で動的に transform:scale() を設定することにしました。 PC、タブレット、スマホ画面それぞれの枠の幅を取得し、iframe の幅との比率を transform:scale() の値に代入します。

<script>
jQuery(function($){
  $(window).on('load resize', function(){
    var pc_w = $('.pc .frame').width() / 1280;
    $('.pc iframe').css('transform', 'scale(' + pc_w + ')');
    
    var tb_w = $('.tb .frame').width() / 768;
    $('.tb iframe').css('transform', 'scale(' + tb_w + ')');
    
    var sp_w = $('.sp .frame').width() / 375;
    $('.sp iframe').css('transform', 'scale(' + sp_w + ')');
  });
});
</script>

これで思うような表示になりました。

iframe で表示しているので、この中で表示しているWebページを操作することができます。それはそれで面白いですが、操作させたくない場合は透明画像を被せるなど工夫する必要があります。

なお、https(SSL)のページに http のページを埋め込もうとすると、混在コンテンツとなり表示できません。そのため当サイトでは、埋め込もうとするWebページの URL が https から始まれば iframe で、そうでなければ以前のようにPC画面のみを WordPress API で取得したサムネイル画像を表示するようにしています。(下記は WordPress のテーマでの記述です)

<?php
  $works_url = get_field('works_url');

  if ( substr($works_url, 0, 5) === 'https' ):  // https の場合 iframe で読み込み
?>
(上記の iframe の記述)
<?php
  else:  // http の場合サムネイルを表示(PC画面のみ)
?>
<div class="pc">
<div class="frame">
<img src="https://s.wordpress.com/mshots/v1/<?php echo urlencode($works_url); ?>?w=1280" alt="PC画面" />
</div>
</div>
<?php
  endif;
?>

また、一覧ページで iframe を使うと表示しているサイトの数だけリクエストが発生することになるので、一覧ページでも WordPress API によるサムネイル画像を表示しています。