📄astro-notion-blogでコードブロックからHTML要素を挿入する
前回の記事⬆でHTMLを記事に埋め込むことができるようにしたので、試しにYouTubeの埋め込み機能を試してみました。色々調べるとレスポンシブ対応にする方法が書いてあって、なるほど~となったのですが、astro-notion-blogには標準でYouTubeの埋め込み機能があります。
astro-notion-blogでは、NotionにYouTubeを埋め込むと記事にもそのまま埋め込まれます。そういえばこれまでの記事で使ったことが無いなと思い、試してみました。
16:9よりも細長いです。サムネイルは上下が見切れています。再生すると左右に黒枠が出てきます。
これを2列に配置するとこうなります。
今度は上下に黒枠が出現しています。
標準の埋め込みと16:9の縦横比かつレスポンシブ対応のHTMLを並べてみます。
<div style="position: relative; padding-bottom: 56.25%;">
<iframe
style="position: absolute; top: 0; left: 0; width: 100%; height: 100%;"
src="https://www.youtube.com/embed/[YouTubeの動画ID]"
frameborder="0"
allow="autoplay; encrypted-media"
allowfullscreen>
</iframe>
</div>
1行目の56.25%が肝で、16:9の高さを横幅に対する割合で決めるということになります。9÷16=0.5625ですね
CSSの
aspect-ratio
というプロパティによって直接的に縦横比を指定できることを知ったので、これを使うように更新しました。僕はドンピシャで16:9にしたいのでastro-notion-blogのコードを書き換えることにします。
YouTubeの埋め込みのための処理はsrc\components\notion-blocks\Video.astro
にあります。
<div class="video">
<div>
{
isYouTubeURL(url) && (
<iframe
src={`https://www.youtube.com/embed/${parseYouTubeVideoId(url)}`}
title="YouTube video player"
frameborder="0"
allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share"
allowfullscreen
/>
)
}
</div>
<Caption richTexts={block.Video.Caption} />
</div>
<style>
.video div:first-child {
width: 100%;
}
.video div:first-child iframe {
width: 100%;
height: 340px;
}
@media (max-width: 640px) {
.video div:first-child iframe {
height: 220px;
}
}
</style>
このコードは上がHTML、下がCSSとなっています。
処理を読み込むと、iframe
は大体同じ形で、変数としてYouTubeのURLを入れているようです。
style
は下に別記。src
・frameborder
・allowfullscreen
は同じ。allow
の内容が少し多い。
ということで、style
を同じように変更すれば良さそうです。
旧バージョン
<style>
.video div:first-child {
width: 100%;
}
.video div:first-child iframe {
width: 100%;
height: 340px;
}
@media (max-width: 640px) {
.video div:first-child iframe {
height: 220px;
}
}
</style>
<div style="position: relative; padding-bottom: 56.25%;">
<iframe
style="position: absolute; top: 0; left: 0; width: 100%; height: 100%;"
src="https://www.youtube.com/embed/[YouTubeの動画ID]"
frameborder="0"
allow="autoplay; encrypted-media"
allowfullscreen>
</iframe>
</div>
Video.astro
のCSS部分では、.video
クラス内における3つの項目についてstyle
を指定しています。具体的には、幅は全て100%(ビューポート幅)で、状況に応じて高さをpxで指定しています。
上から
- 最初の子div要素
- 最初の子div要素内のiframe要素
- ビューポートの幅が640px以下の場合の最初の子div要素内のiframe要素
です。
縦横比を保ったまま横幅に合わせて変形してほしいため、ビューポートの幅が640px以下になったとき(サイドバーがサイドから消えて記事のメインカラムだけが表示されるようになったとき)でも同じようにしたいです。16:9にするコードではビューポートの横幅に対して高さを50.25%という割合で指定することによって縦横比を維持しています。なので、2と3の処理は同じになり、ビューポートの幅によって処理を分岐させる必要もなくなります。
これで何がどうすればいいのか分かったので書き換えます。3. の項目はコメントアウトします。
<style>
.video div:first-child {
position: relative;
padding-bottom: 56.25%;
}
.video div:first-child iframe {
position: absolute;
top: 0;
left: 0;
width: 100%;
height: 100%;
}
/*@media (max-width: 640px) {
.video div:first-child iframe {
height: 220px;
}
}*/
</style>
Video.astro
のCSS部分では、.video
クラス内における3つの項目についてstyle
を指定しています。具体的には、幅は全て100%(ビューポート幅)で、状況に応じて高さをpxで指定しています。
<style>
.video div:first-child {
width: 100%;
}
.video div:first-child iframe {
width: 100%;
height: 340px;
}
@media (max-width: 640px) {
.video div:first-child iframe {
height: 220px;
}
}
</style>
上から
- 最初の子div要素
- 最初の子div要素内のiframe要素
- ビューポートの幅が640px以下の場合の最初の子div要素内のiframe要素
です。外側から順に指定されています。
aspect-ratio
の指定は、16:9であればaspect-ratio: 16 / 9;
のようにします。
2.と3.では高さが固定値によって設定されていますが、今回はビューポート幅に関係なく縦横比を保ったままレスポンシブに対応させたいので、2.に統合します。
そして、1.の.video div:first-child
に縦横比を指定、2.の.video div:first-child iframe
は1.の幅と高さの100%とすることで、縦横比を保ったまま埋め込み動画のサイズがレスポンシブに対応します。
<style>
.video div:first-child {
width: 100%;
aspect-ratio: 16 / 9;
}
.video div:first-child iframe {
width: 100%;
height: 100%;
}
</style>
この下のやつは実際に再生される埋め込みの動画です。上のGIFと同じ配置になっています。