こんにちは。KOUKIです。
本記事は、Udemyの「50 Projects In 50 Days – HTML, CSS & JavaScript」で学習したことを載せています。
今回で、いよいよ最後の講義です。
<目次>
実装するもの
今回は、虫取りゲームのスタイリングをしましょう。
demoは「こちら」で確認できます。
ワークスペース
必要なファイルは、以下の通りです。
1 2 3 4 5 |
$ 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 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 |
<!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>Catch The Insect</title> </head> <body> <div class="screen"> <h1>Catch The Insect</h1> <button class="btn" id="start-btn">Play Game</button> </div> <div class="screen"> <h1>What is your "favorite" insect?</h1> <ul class="insects-list"> <li> <button class="choose-insect-btn"> <p>Fly</p> <img src="http://pngimg.com/uploads/fly/fly_PNG3946.png" alt="fly"> </button> </li> <li> <button class="choose-insect-btn"> <p>Mosquito</p> <img src="http://pngimg.com/uploads/mosquito/mosquito_PNG18175.png" alt="mosquito" /> </button> </li> <li> <button class="choose-insect-btn"> <p>Spider</p> <img src="http://pngimg.com/uploads/spider/spider_PNG12.png" alt="spider" /> </button> </li> <li> <button class="choose-insect-btn"> <p>Roach</p> <img src="http://pngimg.com/uploads/roach/roach_PNG12163.png" alt="roach" /> </button> </li> </ul> </div> <div class="screen game-container" id="game-container"> <h3 id="time" class="time">Time: 00:00</h3> <h3 id="score" class="score">Score: 0</h3> <h5 id="message" class="message"> Are you annnoyed yet? <br> You are playing an impossible game!! </h5> </div> <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 92 93 94 95 96 97 98 99 100 101 102 103 104 105 |
// 要素の取得 const screens = document.querySelectorAll('.screen'); const choose_insect_btns = document.querySelectorAll('.choose-insect-btn'); const start_btn = document.getElementById('start-btn') const game_container = document.getElementById('game-container') const timeEl = document.getElementById('time') const scoreEl = document.getElementById('score') const message = document.getElementById('message') // プロパティ let seconds = 0 let score = 0 let selected_insect = {} // Play Gameボタンにクリックイベントを登録 start_btn.addEventListener('click', () => screens[0].classList.add('up')) // 虫のキャッチボタンにclickイベントを登録 choose_insect_btns.forEach(btn => { btn.addEventListener('click', () => { // HTMLからインセクト情報を取得 const img = btn.querySelector('img') const src = img.getAttribute('src') const alt = img.getAttribute('alt') // {src, alt}形式のオブジェクトにする selected_insect = { src, alt } // upクラスを付与 screens[1].classList.add('up') // 1秒後にcreateInsectを実行 setTimeout(createInsect, 1000) // ゲームを実行 startGame() }) }) function startGame() { // 1秒ごとにincreaseTimeを実行 setInterval(increaseTime, 1000) } // 時間を進める function increaseTime() { let m = Math.floor(seconds / 60) let s = seconds % 60 m = m < 10 ? `0${m}` : m s = s < 10 ? `0${s}` : s // 時間更新 timeEl.innerHTML = `Time: ${m}:${s}` seconds++ } // 虫を増やす function createInsect() { // div要素を作成 const insect = document.createElement('div') // insectクラスを付与 insect.classList.add('insect') const { x, y } = getRandomLocation() // スタイルをつける insect.style.top = `${y}px` insect.style.left = `${x}px` insect.innerHTML = `<img src="${selected_insect.src}" alt="${selected_insect.alt}" style="transform: rotate(${Math.random() * 360}deg)" />` // 作成した要素がクリックされた時、catchInsectを実行 insect.addEventListener('click', catchInsect) // 子要素として追加 game_container.appendChild(insect) } // 虫を表示させる場所をランダムに取得 function getRandomLocation() { const width = window.innerWidth const height = window.innerHeight const x = Math.random() * (width - 200) + 100 const y = Math.random() * (height - 200) + 100 return { x, y } } // 虫を捕まえる function catchInsect() { increaseScore() this.classList.add('caught') setTimeout(() => this.remove(), 2000) addInsects() } // 虫を追加 function addInsects() { setTimeout(createInsect, 1000) setTimeout(createInsect, 1500) } // スコアを追加 function increaseScore() { score++ if(score > 19) { message.classList.add('visible') } scoreEl.innerHTML = `Score: ${score}` } |

スタイリング
これからCSSでスタイリングを行います。項目に出てくるbodyやaは、HTMLの要素です。
全体の設定
1 2 3 4 5 6 7 8 |
/* フォント */ @import url("https://fonts.googleapis.com/css?family=Press+Start+2P&display=swap"); * { /* ボックスの大きさを算出 padding/borderをwidth/heightに含める */ box-sizing: border-box; } |
bodyの設定
1 2 3 4 5 6 7 8 9 |
body { background-color: #516dff; color: #fff; font-family: "Press Start 2P", sans-serif; height: 100vh; overflow: hidden; margin: 0; text-align: center; } |

h1の設定
1 2 3 |
h1 { line-height: 1.4; } |

btnの設定
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 |
.btn { border: 0; background-color: #fff; color: #516dff; padding: 15px 20px; font-family: inherit; cursor: pointer; } /* カーソルを乗せた時 */ .btn:hover { /* 透明にする */ opacity: 0.9; } /* ボタンを押下時 */ .btn:focus { /* ボタンの青線をなくす */ outline: 0; } |


screenの設定
1 2 3 4 5 6 7 8 9 10 11 12 13 14 |
.screen { /* flexアイテムにする */ display: flex; /* flexアイテムを積み重ねるように配置 */ flex-direction: column; /* flex重点にアイテムを配置 */ align-items: center; /* flex横軸中央にアイテムを配置 */ justify-content: center; height: 100vh; width: 100vw; /* アニメーションをつける */ transition: margin 0.5s ease-out; } |

insects-listの設定
1 2 3 4 5 6 7 8 9 |
.insects-list { display: flex; /* フレックスアイテムを複数行に分割 */ flex-wrap: wrap; justify-content: center; /* リストの黒ポチを消す */ list-style: none; padding: 0; } |

insects-list liの設定
1 2 3 |
.insects-list li { margin: 10px; } |

choose-insect-btnの設定
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 |
.choose-insect-btn { background-color: transparent; border: 2px solid #fff; color: #fff; cursor: pointer; font-family: inherit; width: 150px; height: 150px; } .choose-insect-btn:hover { background-color: #fff; color: #516dff; } .choose-insect-btn:active { background-color: rgba(255, 255, 255, 0.7); } |

choose-insect-btn imgの設定
1 2 3 4 5 6 7 8 |
.choose-insect-btn img { width: 100px; height: 100px; /* 置換要素(img要素やvideo要素など)を ボックスサイズに合わせて縦横比を維持しながら リサイズして、全体が見えるようにはめ込む */ object-fit: contain; } |

game-containerの設定
1 2 3 |
.game-container { position: relative; } |
screen.upの設定
1 2 3 4 |
.screen.up { /* ボタンをクリックしたら画面を100vh移動 */ margin-top: -100vh; } |

time/scoreの設定
1 2 3 4 5 6 7 8 9 10 11 12 13 |
.time, .score { position: absolute; top: 20px; } .time { left: 20px; } .score { right: 20px; } |

messageの設定
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 |
.message { line-height: 1.7; background-color: rgba(0, 0, 0, 0.5); width: 100%; padding: 20px; z-index: 100; text-align: center; opacity: 0; position: absolute; top: 0; left: 50%; transform: translate(-50%, -150%); transition: transform 0.4s ease-in; } .message.visible { transform: translate(-50%, 150%); opacity: 1; } |

insectの設定
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 |
.insect { cursor: pointer; display: flex; align-items: center; justify-content: center; width: 100px; height: 100px; position: absolute; transform: translate(-50%, -50%) scale(1); transition: transform 0.3s ease-in-out; } .insect.caught { transform: translate(-50%, -50%) scale(0); } .insect img { width: 100px; height: 100px; } |

これで、完成です。
おわりに
本記事で「50 Projects In 50 Days – HTML, CSS & JavaScript」でのCSS学習は以上です。だいぶCSSにも慣れてきましたね^^
仕事では、管理画面の作成に関わることが多いので、管理画面のデザインを考えたり、CSSで実装していきたいですね。
フルスタックエンジニアを目指して、がんばります^^
それでは、また!
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 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 |
/* フォント */ @import url("https://fonts.googleapis.com/css?family=Press+Start+2P&display=swap"); * { /* ボックスの大きさを算出 padding/borderをwidth/heightに含める */ box-sizing: border-box; } body { background-color: #516dff; color: #fff; font-family: "Press Start 2P", sans-serif; height: 100vh; overflow: hidden; margin: 0; text-align: center; } h1 { line-height: 1.4; } .btn { border: 0; background-color: #fff; color: #516dff; padding: 15px 20px; font-family: inherit; cursor: pointer; } /* カーソルを乗せた時 */ .btn:hover { /* 透明にする */ opacity: 0.9; } /* ボタンを押下時 */ .btn:focus { /* ボタンの青線をなくす */ outline: 0; } .screen { /* flexアイテムにする */ display: flex; /* flexアイテムを積み重ねるように配置 */ flex-direction: column; /* flex重点にアイテムを配置 */ align-items: center; /* flex横軸中央にアイテムを配置 */ justify-content: center; height: 100vh; width: 100vw; /* アニメーションをつける */ transition: margin 0.5s ease-out; } .insects-list { display: flex; /* フレックスアイテムを複数行に分割 */ flex-wrap: wrap; justify-content: center; /* リストの黒ポチを消す */ list-style: none; padding: 0; } .insects-list li { margin: 10px; } .choose-insect-btn { background-color: transparent; border: 2px solid #fff; color: #fff; cursor: pointer; font-family: inherit; width: 150px; height: 150px; } .choose-insect-btn:hover { background-color: #fff; color: #516dff; } .choose-insect-btn:active { background-color: rgba(255, 255, 255, 0.7); } .choose-insect-btn img { width: 100px; height: 100px; /* 置換要素(img要素やvideo要素など)を ボックスサイズに合わせて縦横比を維持しながら リサイズして、全体が見えるようにはめ込む */ object-fit: contain; } .game-container { position: relative; } .time, .score { position: absolute; top: 20px; } .time { left: 20px; } .score { right: 20px; } .screen.up { /* ボタンをクリックしたら画面を100vh移動 */ margin-top: -100vh; } .message { line-height: 1.7; background-color: rgba(0, 0, 0, 0.5); width: 100%; padding: 20px; z-index: 100; text-align: center; opacity: 0; position: absolute; top: 0; left: 50%; transform: translate(-50%, -150%); transition: transform 0.4s ease-in; } .message.visible { transform: translate(-50%, 150%); opacity: 1; } .insect { cursor: pointer; display: flex; align-items: center; justify-content: center; width: 100px; height: 100px; position: absolute; transform: translate(-50%, -50%) scale(1); transition: transform 0.3s ease-in-out; } .insect.caught { transform: translate(-50%, -50%) scale(0); } .insect img { width: 100px; height: 100px; } |
コメントを残す
コメントを投稿するにはログインしてください。