穴埋め問題を解きながら、タスク管理アプリを段階的に完成させて、CSS装飾とJavaScript動作の実装力を身につける
まずは今日作るアプリを実際に触ってみましょう!
やること:
以下のHTMLの空欄を埋めてください:
<!DOCTYPE html>
<html lang="ja">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>学習タスク管理</title>
<link rel="stylesheet" href="_______.css">
</head>
<body>
<!-- ヘッダー部分 -->
<_______ class="_______">
<h1>📚 今日の学習タスク</h1>
<p>目標: CSS装飾とJavaScript動きをマスターしよう!</p>
</_______>
<script src="script.js"></script>
</body>
</html>
選択肢:
<link rel="stylesheet" href="style.css">
<header class="main-header">
<h1>📚 今日の学習タスク</h1>
<p>目標: CSS装飾とJavaScript動きをマスターしよう!</p>
</header>
理由:
style.css
: 一般的なCSS ファイル名header
: ページの見出し部分にはheaderタグが適切main-header
: メインのヘッダーであることを表すclass名<!-- 進捗表示 -->
<_______ class="progress-section">
<h2>📈 学習進捗</h2>
<div class="progress-container">
<div class="_______-bar">
<div class="_______-fill" id="_______Fill"></div>
</div>
<p class="_______-text" id="_______Text">0 / 6 完了 (0%)</p>
</div>
</_______>
🧠 考える問題:
ヒント:
<section class="progress-section">
<h2>📈 学習進捗</h2>
<div class="progress-container">
<div class="progress-bar">
<div class="progress-fill" id="progressFill"></div>
</div>
<p class="progress-text" id="progressText">0 / 6 完了 (0%)</p>
</div>
</section>
理由:
section
: 意味的にまとまった内容なのでprogress-bar
: 進捗バーの枠progress-fill
: 実際に伸びる部分progressFill
, progressText
: JavaScriptで操作しやすい名前<!-- タスクリスト -->
<section class="tasks-section">
<h2>✅ タスクリスト</h2>
<div class="_______-item">
<input type="_______" id="task1" class="_______-checkbox">
<_______ for="_______">HTML基本構造を作成</label>
</div>
<!-- 🎯 チャレンジ: 残り5つのタスクを自分で書いてみよう! -->
</section>
<!-- 完了メッセージ -->
<div class="completion-message" id="_______Message">
<h2>🎉 おめでとうございます!</h2>
<p>全てのタスクが完了しました!</p>
</div>
🧠 自分で考える問題:
🎯 課題: 残り5つのタスクアイテムを自分で作ってみてください! (内容: "CSSで基本レイアウト", "グラデーション背景を追加", "ホバーエフェクト実装", "JavaScriptで進捗バー作成", "完了エフェクト追加")
<div class="task-item">
<input type="checkbox" id="task1" class="task-checkbox">
<label for="task1">HTML基本構造を作成</label>
</div>
<div class="task-item">
<input type="checkbox" id="task2" class="task-checkbox">
<label for="task2">CSSで基本レイアウト</label>
</div>
<!-- 以下同様のパターン -->
<div class="completion-message" id="completionMessage">
/* 基本設定 */
_______ {
margin: _______;
padding: _______;
box-sizing: _______-box;
}
body {
font-family: "Hiragino Sans", "Yu Gothic", sans-serif;
line-height: _____;
color: #___;
min-height: _____vh;
background: _______; /* グレー系の色 */
padding: _______px; /* 全体の余白 */
}
🤝 ペアで話し合い:
box-sizing
の値は?line-height
の適切な値は?color
の値は?(#から始まる)min-height
の値は?ヒント:
#f3f4f6
, #e5e7eb
, #gray
など* {
margin: 0;
padding: 0;
box-sizing: border-box;
}
body {
font-family: "Hiragino Sans", "Yu Gothic", sans-serif;
line-height: 1.6;
color: #333;
min-height: 100vh;
background: #f3f4f6;
padding: 20px;
}
理由:
*
: 全要素選択0
: リセット値border-box
: サイズ計算を簡単に1.6
: 読みやすい行間#333
: 濃いグレーで読みやすく100vh
: 画面の高さ全体#f3f4f6
: 薄いグレー20px
: 適度な余白/* カード型レイアウト */
.main-header, _______ {
background: _______;
padding: _______rem;
border-radius: _______px;
text-align: _______;
margin-bottom: _______rem;
box-shadow: _______ _______ _______px rgba(0,0,0,_______);
border-left: _______px solid #_______; /* 左端のアクセント線 */
}
/* 進捗バー */
.progress-bar {
width: _______;
height: _______px;
background: #e5e7eb;
border-radius: _______px;
overflow: _______;
}
.progress-fill {
height: _______;
background: _______; /* 緑系の色 */
width: _______%; /* 初期値 */
transition: width _______s ease;
}
🧠 考える問題:
text-align
の値は?box-shadow
の構文は 水平 垂直 ぼかし 色
ですが、適切な値は?💡 実験してみよう: 値を変更して効果を確認!
.main-header, section {
background: white;
padding: 2rem;
border-radius: 10px;
text-align: center;
margin-bottom: 2rem;
box-shadow: 0 2px 10px rgba(0,0,0,0.1);
border-left: 4px solid #4f46e5;
}
.progress-bar {
width: 100%;
height: 25px;
background: #e5e7eb;
border-radius: 12px;
overflow: hidden;
margin-bottom: 1rem; /* 進捗バーとテキストの間隔 */
}
.progress-fill {
height: 100%;
background: #10b981;
width: 0%;
transition: width 0.5s ease;
border-radius: 12px; /* 進捗部分の角丸 */
}
/* ヘッダー内のスタイル */
.main-header h1 {
color: #_______; /* メインカラー */
font-size: _______rem;
margin-bottom: _______rem;
}
.main-header p {
color: #____; /* 薄いグレー */
font-size: _______rem;
}
/* セクション見出し */
section h2 {
color: #_______; /* メインカラー */
margin-bottom: _______rem;
font-size: _______rem;
}
/* 進捗コンテナ */
.progress-container {
text-align: _______;
}
.progress-text {
font-weight: _____;
font-size: _______rem;
color: #_______; /* メインカラー */
}
🎯 タイポグラフィチャレンジ:
.main-header h1 {
color: #4f46e5;
font-size: 2rem;
margin-bottom: 0.5rem;
}
.main-header p {
color: #666;
font-size: 1.1rem;
}
section h2 {
color: #4f46e5;
margin-bottom: 1.5rem;
font-size: 1.4rem;
}
.progress-container {
text-align: center;
}
.progress-text {
font-weight: bold;
font-size: 1.1rem;
color: #4f46e5;
}
/* タスクアイテム */
.task-item {
display: _______;
align-items: _______;
padding: 1rem;
background: #f8fafc;
border-radius: 8px;
border: 2px solid #e5e7eb;
cursor: _______;
transition: _______ _______s ease;
}
/* 🎯 チャレンジ: ホバーエフェクトを自分で作ろう! */
.task-item:hover {
background: _______; /* 少し違う色に */
border-color: _______; /* アクセントカラーに */
transform: translateY(_______px); /* 上に移動 */
box-shadow: _______ _______ _______px rgba(79, 70, 229, 0.2);
}
🎯 ホバーエフェクト完全自作チャレンジ:
display
と align-items
でどんなレイアウト?🤝 ペアで実験: 値を変更して一番良い効果を見つけよう!
.task-item {
display: flex;
align-items: center;
padding: 1rem;
margin-bottom: 1rem;
background: #f8fafc;
border-radius: 8px;
border: 2px solid #e5e7eb;
cursor: pointer;
transition: all 0.3s ease;
}
.task-item:hover {
background: #f1f5f9;
border-color: #4f46e5;
transform: translateY(-2px);
box-shadow: 0 4px 12px rgba(79, 70, 229, 0.2);
}
/* チェックボックス */
.task-checkbox {
width: ____px;
height: ____px;
margin-right: ____rem;
cursor: ______;
}
/* ラベルスタイル */
.task-item label {
flex: _; /* 残りスペースを使用 */
cursor: ______;
font-size: ____rem;
color: #___; /* 通常の文字色 */
}
/* 完了状態のスタイル */
.task-item.completed {
background: #_______; /* 薄い緑 */
border-color: #_______; /* 緑 */
}
.task-item.completed label {
text-decoration: _______-______; /* 取り消し線 */
color: #_______; /* グレー */
}
🧠 考える問題:
.task-checkbox {
width: 18px;
height: 18px;
margin-right: 1rem;
cursor: pointer;
}
.task-item label {
flex: 1;
cursor: pointer;
font-size: 1rem;
color: #333;
}
.task-item.completed {
background: #ecfdf5;
border-color: #10b981;
}
.task-item.completed label {
text-decoration: line-through;
color: #6b7280;
}
/* 完了メッセージ(重要!) */
.completion-message {
position: _______; /* 画面に固定 */
top: ___%; /* 縦中央 */
left: ___%; /* 横中央 */
transform: translate(-50%, -50%); /* 完全中央配置 */
background: #_______; /* 緑 */
color: _____; /* 白 */
padding: ____rem;
border-radius: ____px;
text-align: _______;
display: ____; /* 初期状態は非表示 */
box-shadow: _ _px ____px rgba(0, 0, 0, 0.2);
z-index: ____; /* 最前面に表示 */
}
.completion-message h2 {
color: _____; /* 白 */
margin-bottom: ____rem;
}
🎯 モーダル実装チャレンジ:
position
で画面固定にするには?.completion-message {
position: fixed;
top: 50%;
left: 50%;
transform: translate(-50%, -50%);
background: #10b981;
color: white;
padding: 2rem;
border-radius: 10px;
text-align: center;
display: none;
box-shadow: 0 4px 15px rgba(0, 0, 0, 0.2);
z-index: 1000;
}
.completion-message h2 {
color: white;
margin-bottom: 0.5rem;
}
/* レスポンシブ対応 */
@media (max-width: ____px) {
body {
padding: ____px; /* モバイルでは狭く */
}
.main-header,
section {
padding: ____rem; /* 内側余白も調整 */
}
.main-header h1 {
font-size: ____rem; /* 文字サイズ縮小 */
}
.task-item {
padding: ____rem; /* タスクアイテムも調整 */
}
}
🧠 考える問題:
@media (max-width: 600px) {
body {
padding: 10px;
}
.main-header,
section {
padding: 1.5rem;
}
.main-header h1 {
font-size: 1.6rem;
}
.task-item {
padding: 0.8rem;
}
}
document.addEventListener("_______", function () {
// 要素を取得
const taskCheckboxes = document._______("._______-checkbox");
const progressFill = document._______("_______Fill");
const progressText = document._______("_______Text");
const completionMessage = document._______("_______Message");
});
🧠 考える問題:
document.addEventListener("DOMContentLoaded", function () {
const taskCheckboxes = document.querySelectorAll(".task-checkbox");
const progressFill = document.getElementById("progressFill");
const progressText = document.getElementById("progressText");
const completionMessage = document.getElementById("completionMessage");
});
// 各チェックボックスにイベントを追加
taskCheckboxes.forEach(function(checkbox) {
checkbox.addEventListener("change", function() {
handleTaskChange(this);
});
});
function handleTaskChange(checkbox) () {
const taskItem = checkbox._______(".task-item");
if (checkbox._______) {
taskItem.classList._______("completed");
} else {
taskItem.classList._______("completed");
}
updateProgress(); // 進捗更新関数を呼び出し
}
🎯 ロジック理解チャレンジ:
taskCheckboxes.forEach(function(checkbox) {
checkbox.addEventListener("change", function () {
const taskItem = checkbox.closest(".task-item");
if (checkbox.checked) {
taskItem.classList.add("completed");
} else {
taskItem.classList.remove("completed");
}
updateProgress();
});
});
function updateProgress() {
// 🎯 以下を自分で実装してみよう!
// 1. 全タスク数を取得(ヒント: taskCheckboxes.length)
const totalTasks = _______;
// 2. 完了したタスク数を取得(ヒント: :checked セレクタ)
const completedTasks = document.querySelectorAll("_______").length;
// 3. パーセンテージを計算(四捨五入)
const percentage = Math.round((_______ / _______) * 100);
// 4. 進捗バーの幅を更新
progressFill.style._______ = percentage + "%";
// 5. 進捗テキストを更新
progressText._______ = `${_______} / ${_______} 完了 (${_______}%)`;
// 6. 全完了時の判定
if (_______ === _______) {
completionMessage.style.display = "_______";
} else {
completionMessage.style.display = "_______";
}
}
🧠 完全自作問題: この関数を自分で完成させてください!
考えるポイント:
🤝 ペア作業: 一緒に考えて実装しよう!
function updateProgress() {
const totalTasks = taskCheckboxes.length;
const completedTasks = document.querySelectorAll(".task-checkbox:checked").length;
const percentage = Math.round((completedTasks / totalTasks) * 100);
progressFill.style.width = percentage + "%";
progressText.textContent = `${completedTasks} / ${totalTasks} 完了 (${percentage}%)`;
if (completedTasks === totalTasks) {
completionMessage.style.display = "block";
} else {
completionMessage.style.display = "none";
}
}
基本機能が完成したら、以下の機能を追加してみよう!
🎯 チャレンジミッション(難易度別):
初級: 完了メッセージをクリックで閉じる機能
completionMessage.addEventListener("_______", function() {
// ここに処理を書こう
});
中級: タスク完了時に背景色を変える機能
/* 問題2-5で学習済み! */
.task-item.completed {
background: #ecfdf5; /* 薄い緑 */
border-color: #10b981; /* 緑 */
}
.task-item.completed label {
text-decoration: line-through; /* 取り消し線 */
color: #6b7280; /* グレー */
}
上級: 進捗バーの色をパーセンテージで変える機能
// ヒント: パーセンテージに応じて色を変更
if (percentage < 50) {
progressFill.style.background = "_______"; // 赤系
} else if (percentage < 100) {
progressFill.style.background = "_______"; // 黄系
} else {
progressFill.style.background = "_______"; // 緑系
}
🤝 ペアで挑戦: どのレベルまでできるか試してみよう!
🤝 ペアで話し合い:
❌ 「書けばいいと思った」 ✅ 「この理由でこの答えにした」
❌ 「なんとなく選んだ」 ✅ 「〇〇の効果を狙ってこれを選んだ」
写経との違い:
能動性の向上:
Think, Fill, Code! 🧩 穴埋めで理解を深めて、本当の実装力を身につけよう!