😸
microCMSで出力されるiframeをレスポンシブ対応させてみた話
こんにちは、ebii(de)と申します。
先日、Nuxt.js + microCMS + Netlifyでブログを作成しました。
(大したこと書いてないけど、こちら)
そのときにmicroCMSで埋め込んだiframeがスマホの画面をはみ出てしまう問題に遭遇したので、どう解決したのかをまとめます。
問題点
microCMSでは、リッチエディタにてiframe埋め込みをすると、以下のフォーマットで出力されます。
例:YouTube
<iframe width=\"480\" height=\"270\" src=\"https://www.youtube.com/embed/41Ia291KIvI?feature=oembed\" frameborder=\"0\" allow=\"accelerometer; autoplay; encrypted-media; gyroscope; picture-in-picture\" allowfullscreen></iframe>
(参考記事)
たぶん、width
とheight
を直接指定してるのが悪さしてるんだと思います。
さて、どうしたものか。
解決編
以下の記事が参考になりました。
この記事では、microCMSから取得したHTMLをcheerioで弄っております。
これと同じことをiframeに適用すればいいと思いつきました。(多少強引ではありますが……。)
そして、asyncDataを以下のように修正しました。
async asyncData ({ params, $config, error }) {
try {
const { data } = await axios.get(
$config.apiBaseUrl + `/api/v1/blog/${params.slug}`,
{
headers: { 'X-API-KEY': $config.apiKey }
}
)
const $ = cheerio.load(data.body)
$('pre code').each((_, elm) => {
const result = hljs.highlightAuto($(elm).text())
$(elm).html(result.value)
$(elm).addClass('hljs')
})
$('iframe').each((_, elm) => {
const wrapDiv =
$('<div style="left: 0; width: 100%; height: 0; position: relative; padding-bottom: 56.25%;"></div>')
$(elm).wrap(wrapDiv)
$(elm).attr('width', null)
.attr('height', null)
.attr('style', 'border: 0; top: 0; left: 0; width: 100%; height: 100%; position: absolute;')
})
return {
...data,
body: $.html()
}
} catch (err) {
error({
statusCode: err.response.status
})
}
}
みてほしいのは$('iframe').each((_, elm) => {...})
の部分です。
やっていることは以下の通り。
- iframeタグの部分を取得
- iframeをdivタグで囲む
- iframタグに定義されている
width
、height
を削除 - iframeタグにstyle追加
これでうまくいきました。
div、iframeタグに追加しているstyleはおまじないみたいなもので、私もしっかり理解はしておりません……。
ただ、divタグのstyleに書いてあるpadding-bottomの数値は結構重要です。
YouTubeの画面比率を16:9に固定するための値なので、ここは必ずこの数値にしておきましょう。
(つまり、他の比率に変更したい場合はここをいじればよいはず。)
これで、無事にYouTubeがレスポンシブ表示されました!
参考になれば幸いです。
Discussion