<!DOCTYPE html>
<html lang="ja-JP">
<head>
<meta charset="UTF-8" />
<title>ライブコードサンプル</title>
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<link rel="preconnect" href="https://fonts.googleapis.com" />
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin />
<link
rel="stylesheet"
href="https://fonts.googleapis.com/css2?family=Roboto&family=Noto+Sans+JP&family=Noto+Color+Emoji&display=swap"
/>
<link rel="stylesheet" href="lib/style.css" />
</head>
<body>
<section>
<h1>PR</h1>
<p>このサイトをご覧の方は、こちらの商品も見ています。</p>
</section>
<script type="module" src="lib/script.js"></script>
</body>
</html>
export {};
const response = await fetch('assets/items.json');
const json = await response.json();
const data = json.data;
/** @type {HTMLUListElement} */
const articles = document.createElement('ul');
articles.classList.add('grid-container');
for (const item of data) {
const paragraph = item.text !== '' ? `<p>${item.text}</p>` : '';
const dl = item.info?.length ? makeDataList(item.info) : '';
const li = document.createElement('li');
li.innerHTML = `
<article class="grid-item">
<img
src="${item.image}"
height="130"
alt=""
/>
<header>
<h2>${item.title}</h2>
${paragraph}
</header>
<dl>
${dl}
</dl>
<address>
<p>${item.owner.name}</p>
<p>TEL: ${item.owner.tel}</p>
</address>
</article>
`;
articles.appendChild(li);
}
document.querySelector('section').appendChild(articles);
/**
*
* @param {{title:string,data:string}[]} info
* @returns
*/
function makeDataList(info) {
const innerHtml = info.reduce(
(prev, current) =>
prev +
`
<div>
<dt>${current.title}</dt>
<dd>${current.data}</dd>
</div>
`,
''
);
return innerHtml;
}
/** ボックスサイズを `border-box` にそろえる */
html {
box-sizing: border-box;
}
*,
*::before,
*::after {
box-sizing: inherit;
font-style: normal;
}
/** サイトの土台を定義 */
html,
body {
font-family: 'Roboto', 'Noto Sans JP', sans-serif;
font-size: 16px;
font-weight: normal;
margin: 0;
padding: 0;
}
section {
padding: 2rem;
background-color: #eee;
}
/** グリッドコンテナ */
.grid-container {
display: grid;
grid-template-columns: repeat(auto-fill, 12rem);
justify-content: center;
gap: 1rem;
padding: 0;
list-style: none;
// 注意!
li {
display: contents;
}
}
/** グリッドアイテム */
.grid-item {
display: grid;
// 「縦方向へのサブグリッドを持つ」という宣言
grid-template-rows: subgrid;
// 「縦方向へのサブグリッドは、4段だ」という意味
grid-row: span 4;
row-gap: 0.5rem;
border: 1px solid #000;
border-radius: 3px;
margin: 0;
padding: 0.5rem;
background: #fff;
font-size: 0.8rem;
img {
width: 100%;
}
header {
// サブグリッドのグリッドアイテム
align-self: center;
h2 {
font-size: 1rem;
margin: 0;
font-weight: normal;
}
p {
margin: 0.2rem 0 0;
}
}
p {
margin: 0.1rem 0;
}
dl {
display: flex;
flex-direction: column;
justify-content: space-between;
gap: 0.2rem;
border-top: 1px dashed #555;
margin: 0;
dd {
margin-left: 1rem;
}
}
address {
border-top: 1px dashed #555;
}
}
{
"success": true,
"data": [
{
"id": 1,
"title": "札幌温泉めぐり 2泊3日",
"category": "travel",
"image": "https://picsum.photos/175/130/",
"text": "",
"info": [
{ "title": "料金", "data": "¥24,000(税別、お一人様)" },
{ "title": "最低催行人数", "data": "10名様" }
],
"owner": {
"name": "ビーアクト観光",
"tel": "xxx-xxxx-xxxx"
}
},
{
"id": 2,
"title": "ガーデニングに! 移植ごて",
"category": "gardening",
"image": "https://picsum.photos/175/130/",
"text": "",
"info": [{ "title": "価格", "data": "¥1,200(税別)" }],
"owner": {
"name": "ビーアクト園芸",
"tel": "xxx-xxxx-xxxx"
}
},
{
"id": 3,
"title": "ステンレスマグ",
"category": "utensils",
"image": "https://picsum.photos/175/130/",
"text": "真空2層式で冷たさ長持ち!",
"info": [{ "title": "価格", "data": "¥1,900(税別)" }],
"owner": {
"name": "アクトビー",
"tel": "xxx-xxxx-xxxx"
}
},
{
"id": 4,
"title": "トレッキングシューズ",
"category": "shoes",
"image": "https://picsum.photos/175/130/",
"text": "",
"info": [
{ "title": "価格", "data": "¥19,800~(税別)" },
{ "title": "サイズ", "data": "24~28cm" }
],
"owner": {
"name": "ビーアクト靴店",
"tel": "xxx-xxxx-xxxx"
}
},
{
"id": 5,
"title": "ボールペン10本セット",
"category": "stationary",
"image": "https://picsum.photos/175/130/",
"text": "ゲル状インクで裏ににじまず書き味なめらか!",
"info": [
{ "title": "価格", "data": "¥900(税別)" },
{ "title": "色", "data": "黒・赤・青" }
],
"owner": {
"name": "文房具ビーアクト",
"tel": "xxx-xxxx-xxxx"
}
}
]
}
{
"name": "plunker-project",
"dependencies": {
"sass": "^1.52.3"
}
}