23
13

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 3 years have passed since last update.

amp-listで高さを可変にする裏技 (amp-list with dynamic height)【AMP】

Last updated at Posted at 2019-09-02

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つの指定を行う

  1. クラス名を付与する (ここでは .DynamicList)
  2. layout を flex-item にする
  3. 自身に min-height: 1px; を指定 (※1)
  4. 自身の直下に自動生成される 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-listsrc に 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つの時

JSONのitemsの中身が4つの時

1つの時

JSONのitemsの中身が1つの時

0の時 (カラの時)

JSONのitemsの中身がカラの時

まとめ

amp-list で JSON のコンテンツに応じて高さを可変で利用するための裏技でした。

注意しておくべき点
非同期で初期レンダリング後に高さ可変の DOM が追加されため、ガタっと要素が表示されてしまう問題があります。
この手法を用いる場合は、このようなマイナスなユーザー体験とトレードオフで使うことが好ましいと思います。


AMP の知見を引き続き記事にしていこうと思います。
いいねをしていただけるとモチベーションに繋がりますので押していただけると嬉しいです。

23
13
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
23
13

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?