2004142326360のリリース以降、こちらの裏技は塞がれてしまった可能性があります
https://github.com/ampproject/amphtml/releases/tag/2004142326360
amp-list で高さを可変にする裏技
amp-list
は、高さを事前に指定する必要があります。
しかし、高さを固定すると自由度が下がってしまうため、JSON のコンテンツに応じて高さを可変で利用するための裏技を紹介します。
amp-list とは
Fetches content dynamically from a CORS JSON endpoint and renders it using a supplied template
Documentation: <amp-list> - amp.dev
JSON のエンドポイントからコンテンツを取得し、テンプレートからクライアントサイドで DOM を生成できるコンポーネント
amp-list の特徴
-
JSON から非同期にデータを取得して DOM を生成できる
-
amp-mustache
による mustache 構文のテンプレートベース
-
-
placeholder の付与だけで JSON 取得中に表示する要素を指定できる
- skeleton も簡単に実現できる
-
fallback の付与だけで JSON 取得失敗時に表示する要素を指定できる
-
レスポンスの JSON で次のエンドポイントも指定することで、無限スクロールも実現可能
など
amp-list の問題
amp-list
では事前に高さを指定しなければならない
そのため高さが可変になる UI の実現が難しい
amp-list で高さを可変にする裏技
amp-list
に対して以下の4つの指定を行う
- クラス名を付与する (ここでは
.DynamicList
) - layout を
flex-item
にする - 自身に
min-height: 1px;
を指定 (※1) - 自身の直下に自動生成される
role="lis"
が付与されたDOMに対して以下のスタイルを指定
CSSを書き出すと以下のようになります
.DynamicList {
min-height: 1px;
}
.DynamicList [role=list] {
position: relative;
width: auto;
height: auto;
}
※1: 1px 以上の指定がない場合、amp-list
が動作しないため必ず 1px 以上で指定してください
サンプル
以下のような構造の JSON に対して高さ可変でリストを表示
JSON
{
"items": [
{
"text": "Yahoo! JAPAN",
"href": "https://www.yahoo.co.jp/"
},
{
"text": "Yahoo!ショッピング",
"href": "https://shopping.yahoo.co.jp/"
},
{
"text": "ヤフオク!",
"href": "https://auctions.yahoo.co.jp/"
},
{
"text": "Yahoo!トラベル",
"href": "https://travel.yahoo.co.jp/"
}
]
}
HTML
amp-list
の src
に JSON のエンドポイントを指定してください
(HTMLは一部省略しています)
<head>
<style amp-boilerplate>body{-webkit-animation:-amp-start 8s steps(1,end) 0s 1 normal both;-moz-animation:-amp-start 8s steps(1,end) 0s 1 normal both;-ms-animation:-amp-start 8s steps(1,end) 0s 1 normal both;animation:-amp-start 8s steps(1,end) 0s 1 normal both}@-webkit-keyframes -amp-start{from{visibility:hidden}to{visibility:visible}}@-moz-keyframes -amp-start{from{visibility:hidden}to{visibility:visible}}@-ms-keyframes -amp-start{from{visibility:hidden}to{visibility:visible}}@-o-keyframes -amp-start{from{visibility:hidden}to{visibility:visible}}@keyframes -amp-start{from{visibility:hidden}to{visibility:visible}}</style>
<noscript><style amp-boilerplate>body{-webkit-animation:none;-moz-animation:none;-ms-animation:none;animation:none}</style></noscript>
<style amp-custom></style>
<script async src="https://cdn.ampproject.org/v0.js"></script>
<script async custom-element="amp-list" src="https://cdn.ampproject.org/v0/amp-list-0.1.js"></script>
<script async custom-template="amp-mustache" src="https://cdn.ampproject.org/v0/amp-mustache-0.2.js"></script>
</head>
<body>
<template id="yahoo-list" type="amp-mustache">
<ul>
<li><a href="{{href}}">{{text}}</a></li>
</ul>
</template>
<amp-list layout="flex-item" template="yahoo-list" src="JSON_END_POINT" class="DynamicList"></amp-list>
</body>
CSS
本来はインラインで上記 HTML の <style amp-custom>
内に書く
.DynamicList {
min-height: 1px;
}
.DynamicList [role=list] {
position: relative;
width: auto;
height: auto;
}
動作確認
JSON の items
の中身の個数に応じて、可変の高さになっているか確認
4つの時
1つの時
0の時 (カラの時)
まとめ
amp-list
で JSON のコンテンツに応じて高さを可変で利用するための裏技でした。
注意しておくべき点
非同期で初期レンダリング後に高さ可変の DOM が追加されため、ガタっと要素が表示されてしまう問題があります。
この手法を用いる場合は、このようなマイナスなユーザー体験とトレードオフで使うことが好ましいと思います。
AMP の知見を引き続き記事にしていこうと思います。
いいねをしていただけるとモチベーションに繋がりますので押していただけると嬉しいです。