こんにちは。KOUKIです。
本記事は、Udemyの「50 Projects In 50 Days – HTML, CSS & JavaScript」で学習したことを載せています。
<目次>
実装するもの
今回は、Movieアプリのスタイリングを行います。
demoは「こちら」で確認できます。
ワークスペース
必要なファイルは、以下の通りです。
1 2 3 4 5 6 |
$ tree . ├── index.html ├── script.js └── style.css |
JavaScript版
HTML & JavaScript
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 |
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8" /> <meta name="viewport" content="width=device-width, initial-scale=1.0" /> <link rel="stylesheet" href="style.css" /> <title>Movie App</title> </head> <body> <header> <form id="form"> <input type="text" id="search" class="search" placeholder="Search"> </form> </header> <main id="main"></main> <script src="script.js"></script> </body> </html> |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 |
// 定数 // Discover const API_URL = 'https://api.themoviedb.org/3/discover/movie?sort_by=popularity.desc&api_key=3fd2be6f0c70a2a598f084ddfb75487c&page=1' // Images const IMG_PATH = 'https://image.tmdb.org/t/p/w1280' // Search const SEARCH_API = 'https://api.themoviedb.org/3/search/movie?api_key=3fd2be6f0c70a2a598f084ddfb75487c&query="' // 要素を取得 const main = document.getElementById('main') const form = document.getElementById('form') const search = document.getElementById('search') // 映画情報を取得 getMovies(API_URL) // async/awaitで非同期処理 async function getMovies(url) { // APIヘGETリクエスト const res = await fetch(url) // 取得したデータをJSON形式で取得 const data = await res.json() // Movieを表示 showMovies(data.results) } function showMovies(movies) { // 画面初期化 main.innerHTML = '' movies.forEach((movie) => { // オブジェクトから各変数に格納 const { title, poster_path, vote_average, overview } = movie // Movieパネルを作成 const movieEl = document.createElement('div') movieEl.classList.add('movie') // MoveパネルをHTMLに埋め込む movieEl.innerHTML = ` <img src="${IMG_PATH + poster_path}" alt="${title}"> <div class="movie-info"> <h3>${title}</h3> <span class="${getClassByRate(vote_average)}">${vote_average}</span> </div> <div class="overview"> <h3>Overview</h3> ${overview} </div> ` main.appendChild(movieEl) }) } // 人気順にクラス分けをする function getClassByRate(vote) { if(vote >= 8) { return 'green' } else if(vote >= 5) { return 'orangge' } else { return 'red' } } // formから検索できるようにする form.addEventListener('submit', (e) => { // フォームのデフォルトの動きを禁止 // ここではページのリダイレクトをキャンセルしている e.preventDefault() // 検索文字列取得 const searchTerm = search.value if(search && searchTerm !== '') { // 検索文字列を元に検索をする getMovies(SEARCH_API + searchTerm) // 検索文字列を削除 search.value = '' } else { // ページを再読み込み // 検索キーワードない状態で検索すると初期状態のデータを表示できる // Searchで検索した結果をクリアしたい時などに使える window.location.reload() } }) |

CSSでスタイリング
これからCSSでスタイリングをしていきます。項目に出てくるbodyやheaderは、HTMLやJavaScriptで設定した要素です。
全体の設定
全体の設定を行います。
1 2 3 4 5 6 7 8 9 10 11 12 13 |
/* フォント */ @import url('https://fonts.googleapis.com/css2?family=Poppins:wght@200;400&display=swap'); /* 変数 */ :root { --primary-color: #22254b; --secondary-color: #373b69; } * { /* ボックスの大きさを算出 */ box-sizing: border-box; } |
bodyの設定
bodyの設定を行います。
1 2 3 4 5 |
body { background-color: var(--primary-color); font-family: 'Poppins', sans-serif; margin: 0; } |

headerの設定
headerの設定を行います。
1 2 3 4 5 6 7 8 |
header { padding: 1rem; /* flexアイテムにする */ display: flex; /* flexアイテムを末尾に寄せる */ justify-content: flex-end; background-color: var(--secondary-color); } |

searchの設定
searchの設定を行います。
1 2 3 4 5 6 7 8 9 10 11 12 |
.search { background-color: transparent; border: 2px solid var(--primary-color); /* 縁を丸く */ border-radius: 50px; /* 親要素からフォントを引き継ぐ */ font-family: inherit; font-size: 1rem; /* 上下 | 左右 */ padding: 0.5rem 1rem; color: #fff; } |

1 2 3 4 5 6 7 8 |
.search::placeholder { color: #7378c5; } .search:focus { outline: none; background-color: var(--primary-color); } |

mainの設定
mainの設定を行います。
1 2 3 4 5 6 7 |
main { display: flex; /* flexアイテムを複数行に分割して配置 */ flex-wrap: wrap; /* flexアイテムを中央に配置 */ justify-content: center; } |

movieの設定
movieの設定を行います。
1 2 3 4 5 6 7 8 9 10 11 |
.movie { width: 300px; margin: 1rem; background-color: var(--secondary-color); box-shadow: 0 4px 5px rgba(0, 0, 0, 0.2); /* アイテムの配置の起点 */ position: relative; /* はみ出た要素を非表示 */ overflow: hidden; border-radius: 3px; } |


imgの設定
imgの設定を行います。
1 2 3 |
.movie img { width: 100%; } |

movie-infoの設定
movie-infoの設定を行います。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 |
.movie-info { color: #eee; display: flex; /* flex重点に配置 */ align-items: center; /* 各アイテムを均等に配置し 最初のアイテムは先頭に寄せ、 最後のアイテムは末尾に寄せる */ justify-content: space-between; /* 上 | 左右 | 下 */ padding: 0.5rem 1rem 1rem; /* 文字間のスペース */ letter-spacing: 0.5px; } |

h3の設定
h3の設定を行います。
1 2 3 |
.movie-info h3 { margin-top: 0; } |

spanの設定
spanの設定を行います。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 |
.movie-info span { background-color: var(--primary-color); padding: 0.25rem 0.5rem; border-radius: 3px; font-weight: bold; } /* JavaScriptでRate判定 */ .movie-info span.green { color: lightgreen; } .movie-info span.orange { color: orange; } .movie-info span.red { color: red; } |

Movie Rate「8.5」に色がつきました。
overviewの設定
overviewの設定を行います。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 |
.overview { background-color: #fff; padding: 2rem; position: absolute; left: 0; bottom: 0; right: 0; max-height: 100%; /* Y軸方向に移動 */ transform: translateY(101%); /* ボックスに収まらない内容をどう表示するかは、 ユーザーエージェントに依存する。 内容が収まらない場合には、 スクロールバーなどが表示される */ overflow-y: auto; /* アニメーション overviewをゆっくり表示 */ transition: transform 0.3s ease-in; } |

カーソルホバーの設定
カーソルホバーの設定を行います。
1 2 3 4 |
/* カーソルをホバーした時 */ .movie:hover .overview { transform: translateY(0); } |

これで完成です。
おわりに
今回は、映画概要蘭(overview)のtransformで非表示にするスタイリング周りが少し難しかったですね。
何度か練習して、慣れていきましょう^^
それでは、また!
CSSまとめ
CSSソースコード
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 |
/* フォント */ @import url('https://fonts.googleapis.com/css2?family=Poppins:wght@200;400&display=swap'); /* 変数 */ :root { --primary-color: #22254b; --secondary-color: #373b69; } * { /* ボックスの大きさを算出 */ box-sizing: border-box; } body { background-color: var(--primary-color); font-family: 'Poppins', sans-serif; margin: 0; } header { padding: 1rem; /* flexアイテムにする */ display: flex; /* flexアイテムを末尾に寄せる */ justify-content: flex-end; background-color: var(--secondary-color); } .search { background-color: transparent; border: 2px solid var(--primary-color); /* 縁を丸く */ border-radius: 50px; /* 親要素からフォントを引き継ぐ */ font-family: inherit; font-size: 1rem; /* 上下 | 左右 */ padding: 0.5rem 1rem; color: #fff; } .search::placeholder { color: #7378c5; } .search:focus { outline: none; background-color: var(--primary-color); } main { display: flex; /* flexアイテムを複数行に分割して配置 */ flex-wrap: wrap; /* flexアイテムを中央に配置 */ justify-content: center; } .movie { width: 300px; margin: 1rem; background-color: var(--secondary-color); box-shadow: 0 4px 5px rgba(0, 0, 0, 0.2); /* アイテムの配置の起点 */ position: relative; /* はみ出た要素を非表示 */ overflow: hidden; border-radius: 3px; } .movie img { width: 100%; } .movie-info { color: #eee; display: flex; /* flex重点に配置 */ align-items: center; /* 各アイテムを均等に配置し 最初のアイテムは先頭に寄せ、 最後のアイテムは末尾に寄せる */ justify-content: space-between; /* 上 | 左右 | 下 */ padding: 0.5rem 1rem 1rem; /* 文字間のスペース */ letter-spacing: 0.5px; } .movie-info h3 { margin-top: 0; } .movie-info span { background-color: var(--primary-color); padding: 0.25rem 0.5rem; border-radius: 3px; font-weight: bold; } /* JavaScriptでRate判定 */ .movie-info span.green { color: lightgreen; } .movie-info span.orange { color: orange; } .movie-info span.red { color: red; } .overview { background-color: #fff; padding: 2rem; position: absolute; left: 0; bottom: 0; right: 0; max-height: 100%; /* Y軸方向に移動 */ transform: translateY(101%); /* ボックスに収まらない内容をどう表示するかは、 ユーザーエージェントに依存する。 内容が収まらない場合には、 スクロールバーなどが表示される */ overflow-y: auto; /* アニメーション overviewをゆっくり表示 */ transition: transform 0.3s ease-in; } /* カーソルをホバーした時 */ .movie:hover .overview { transform: translateY(0); } |
コメントを残す
コメントを投稿するにはログインしてください。