position「fixed」でAMPコンポーネントが正常に動作しない時の対応
最近はAMPに対応しているサイトがだいぶ増えてきて、私もちょくちょく手を出しているのですが、AMPは制約が厳しく決まり事が多いので、未だに開発で躓くことが多いです。
今回は、cssでpositionに「fixed」を指定した場合に、AMPコンポーネントが動作しない時があったので、その時に対応した内容のメモになります。
目次
- 問題のあったコード
- 問題の状態を回避する方法
- 参考リンク
問題のあったコード
問題のあったコードは、左側と右側でそれぞれ「position:fixed」を指定した要素を並べた単純なHTMLです。
<!DOCTYPE html>
<html lang="ja">
<head>
<meta charset="utf-8" />
<title>サンプル(変更前)
<meta name="keywords" content="AMP,コンポーネント,CSS,position,fixed">
<meta name="description" content="サンプルコード(変更前)。positionで「fixed」を指定するとAMPコンポーネントが正常に読み込まれない不具合の検証。">
<meta name="robots" content="noindex,nofollow">
<script async src="https://cdn.ampproject.org/v0.js"></script>
<script async custom-template="amp-mustache" src="https://cdn.ampproject.org/v0/amp-mustache-0.2.js"></script>
<script async custom-element="amp-list" src="https://cdn.ampproject.org/v0/amp-list-0.1.js"></script>
<style amp-custom>
.menu{
position:fixed;
top:0;
left:0;
width:200px;
height:100%;
background-color:#aaa;
}
.main{
position:fixed;
top:0;
left:200px;
width:calc(100% - 200px);
height:100%;
overflow-y:auto;
}
.main .contents{
height:5000px;
}
</style>
</head>
<body>
<nav class="menu">
<div>リスト1</div>
<div>リスト2</div>
<div>リスト3</div>
</nav>
<div class="main">
<div class="contents">
一番下でAMPコンポーネント(amp-list)を呼び出しています。
</div>
<amp-list height="100"
layout="fixed-height"
src="./sample.json">
<template type="amp-mustache">
<div class="item">
<span class="item-id">{{id}}</span>
<span class="item-name">{{name}}</span>
</div>
</template>
</amp-list>
</div>
</body>
</html>
変更前のサンプルはこちら。
AMPコンポーネント(amp-list)で読み込んでいるJSONデータの中身は以下の通りです。
{
"items": [
{
"id": 1,
"name": "Item A"
},
{
"id": 2,
"name": "Item B"
},
{
"id": 3,
"name": "Item C"
}
]
}
状態としては、「main」クラスで指定した要素のかなり下の方にAMPコンポーネントを配置した場合、該当コンポーネントの表示箇所までスクロールすると、初回アクセス時はAMPコンポーネントの内容が表示されますが、F5などでページを再表示すると、なぜかデータを読み込んでくれなくなります。
スクロールの状態やキャッシュなどが影響しているのかとも思いましたが、調べてもよく分からず、試しに表示可能エリアやそのちょっと下にAMPコンポーネントを配置した場合は、問題なく正常に表示されました。
問題の状態を回避する方法
AMPコンポーネント(amp-list)の属性値を変更して対応できれば一番良かったのですが、そういった方法は見つからなかったので、上記の状態を回避するために、HTMLとCSSを修正します。
修正したコードは以下の通り。
<!DOCTYPE html>
<html lang="ja">
<head>
<meta charset="utf-8" />
<title>サンプル(変更後)
<meta name="keywords" content="AMP,コンポーネント,CSS,position,fixed">
<meta name="description" content="サンプルコード(変更前)。positionで「fixed」を指定するとAMPコンポーネントが正常に読み込まれない不具合の検証。">
<meta name="robots" content="noindex,nofollow">
<script async src="https://cdn.ampproject.org/v0.js"></script>
<script async custom-template="amp-mustache" src="https://cdn.ampproject.org/v0/amp-mustache-0.2.js"></script>
<script async custom-element="amp-list" src="https://cdn.ampproject.org/v0/amp-list-0.1.js"></script>
<style amp-custom>
.layout{
display:table;
width:100%;
table-layout:fixed;
}
.menu-area{
display:table-cell;
background-color:#aaa;
width:200px;
}
.menu{
position:fixed;
top:0;
left:0;
width:200px;
height:100%;
}
.main{
display:table-cell;
width:calc(100% - 200px);
height:100%;
}
.main .contents{
height:5000px;
}
</style>
</head>
<body>
<div class="layout">
<div class="menu-area">
<nav class="menu">
<div>リスト1</div>
<div>リスト2</div>
<div>リスト3</div>
</nav>
</div>
<div class="main">
<div class="contents">
一番下でAMPコンポーネント(amp-list)を呼び出しています。
</div>
<amp-list height="100"
layout="fixed-height"
src="./sample.json">
<template type="amp-mustache">
<div class="item">
<span class="item-id">{{id}}</span>
<span class="item-name">{{name}}</span>
</div>
</template>
</amp-list>
</div>
</div>
</body>
</html>
変更後のサンプルはこちら。
修正内容としては、左側と右側の要素を「display:table-cell」にして、左側の要素の下のみ「position:fixed」を設定しています。
AMPコンポーネントを使用している要素(mainクラス)はfixedを使わなくなったので、一番下までスクロールすると、正常にデータが表示されるようになりました。
[2020年1月20日 追記]
layoutクラスのスタイルに「table-layout:fixed;」を追加しました。
追加した理由は、このスタイルを設定していない場合、配下の要素で「overflow:hidden」でスクロール有りで表示しているのに、なぜか上の要素が影響を受けてデザインが崩れてしまったからです。(影響があるのは配下のpreタグのみ? 詳しくはこちらを確認)