Skip to Content
Lecture第12回:総合制作②(実装・開発)

第12回:総合制作②(実装・開発)

🎯 学習目標

前回の企画・設計をもとに、実際にWebサイトの実装を進めます。これまで学習した全ての技術を統合して活用します。

  • 実装力: 設計書に基づいて実際にコーディングができる
  • 統合力: HTML、CSS、JavaScriptを適切に組み合わせて使える
  • 問題解決力: 実装中に発生する問題を自分で解決できる
  • 品質意識: 保守性とパフォーマンスを考慮したコードが書ける

📚 導入(10分)

前回の振り返り

  • 企画書の内容確認
  • ワイヤーフレームのレビュー
  • 技術仕様の最終確認

今回の作業フロー

  1. 基本構造の実装(HTML)
  2. スタイリング(CSS)
  3. インタラクション(JavaScript)
  4. テスト・調整
  5. 最適化

💡 理論学習(20分)

1. 実装のベストプラクティス

1.1 セマンティックなHTML構造

<!DOCTYPE html> <html lang="ja"> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <meta name="description" content="サイトの説明"> <title>サイトタイトル</title> <link rel="stylesheet" href="css/reset.css"> <link rel="stylesheet" href="css/style.css"> </head> <body> <header> <nav aria-label="メインナビゲーション"> <ul> <li><a href="#home">ホーム</a></li> <li><a href="#about">アバウト</a></li> <li><a href="#contact">お問い合わせ</a></li> </ul> </nav> </header> <main> <section id="hero"> <h1>メインタイトル</h1> <p>サイトの説明文</p> </section> <section id="content"> <article> <h2>コンテンツタイトル</h2> <p>コンテンツの詳細</p> </article> </section> </main> <footer> <p>&copy; 2024 サイト名</p> </footer> <script src="js/main.js"></script> </body> </html>

1.2 効率的なCSS設計

/* リセット・基本設定 */ * { box-sizing: border-box; } :root { --primary-color: #3498db; --secondary-color: #2c3e50; --text-color: #333; --background-color: #fff; --max-width: 1200px; } /* レイアウト */ .container { max-width: var(--max-width); margin: 0 auto; padding: 0 1rem; } /* コンポーネント */ .btn { display: inline-block; padding: 0.75rem 1.5rem; background-color: var(--primary-color); color: white; text-decoration: none; border-radius: 4px; transition: background-color 0.3s ease; } .btn:hover { background-color: darken(var(--primary-color), 10%); } /* レスポンシブ */ @media (max-width: 768px) { .container { padding: 0 0.5rem; } }

1.3 モジュラーなJavaScript

// モジュールパターン const WebSite = { // 初期化 init() { this.bindEvents(); this.loadContent(); }, // イベントバインディング bindEvents() { document.addEventListener('DOMContentLoaded', () => { this.setupNavigation(); this.setupForms(); this.setupAnimations(); }); }, // ナビゲーション設定 setupNavigation() { const navLinks = document.querySelectorAll('nav a'); navLinks.forEach(link => { link.addEventListener('click', this.smoothScroll); }); }, // スムーススクロール smoothScroll(e) { e.preventDefault(); const target = document.querySelector(e.target.getAttribute('href')); if (target) { target.scrollIntoView({ behavior: 'smooth' }); } }, // フォーム処理 setupForms() { const forms = document.querySelectorAll('form'); forms.forEach(form => { form.addEventListener('submit', this.handleFormSubmit); }); }, // フォーム送信処理 handleFormSubmit(e) { e.preventDefault(); const formData = new FormData(e.target); console.log('フォームデータ:', Object.fromEntries(formData)); // 実際のAPI送信処理をここに実装 } }; // 初期化実行 WebSite.init();

2. パフォーマンス最適化

2.1 画像最適化

<!-- レスポンシブ画像 --> <img src="image-small.jpg" srcset="image-small.jpg 480w, image-medium.jpg 800w, image-large.jpg 1200w" sizes="(max-width: 480px) 100vw, (max-width: 800px) 50vw, 25vw" alt="画像の説明" loading="lazy">

2.2 CSS・JavaScript最適化

<!-- CSS最適化 --> <link rel="preload" href="css/critical.css" as="style"> <link rel="stylesheet" href="css/critical.css"> <link rel="stylesheet" href="css/non-critical.css" media="print" onload="this.media='all'"> <!-- JavaScript最適化 --> <script src="js/critical.js"></script> <script src="js/non-critical.js" defer></script>

🛠️ 実習(50分)

ステップ1: プロジェクト構造の準備(10分)

ファイル構成の作成

# ディレクトリ構造 project/ ├── index.html ├── css/ ├── reset.css ├── style.css └── responsive.css ├── js/ ├── main.js └── components.js ├── images/ ├── assets/ └── README.md

reset.cssの設定

/* reset.css */ *, *::before, *::after { box-sizing: border-box; margin: 0; padding: 0; } html { font-size: 62.5%; /* 1rem = 10px */ } body { font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, sans-serif; line-height: 1.6; color: #333; } img { max-width: 100%; height: auto; } a { color: inherit; text-decoration: none; } button { border: none; background: none; cursor: pointer; } ul, ol { list-style: none; }

ステップ2: HTMLの実装(15分)

基本構造の作成

<!DOCTYPE html> <html lang="ja"> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <title>マイプロジェクト</title> <meta name="description" content="プロジェクトの説明"> <!-- スタイルシート --> <link rel="stylesheet" href="css/reset.css"> <link rel="stylesheet" href="css/style.css"> <link rel="stylesheet" href="css/responsive.css"> </head> <body> <!-- ヘッダー --> <header class="header"> <div class="container"> <div class="header__logo"> <h1>サイトロゴ</h1> </div> <nav class="nav"> <ul class="nav__list"> <li class="nav__item"> <a href="#home" class="nav__link">ホーム</a> </li> <li class="nav__item"> <a href="#about" class="nav__link">アバウト</a> </li> <li class="nav__item"> <a href="#services" class="nav__link">サービス</a> </li> <li class="nav__item"> <a href="#contact" class="nav__link">お問い合わせ</a> </li> </ul> <!-- ハンバーガーメニュー --> <button class="nav__toggle" aria-label="メニューを開く"> <span></span> <span></span> <span></span> </button> </nav> </div> </header> <!-- メインコンテンツ --> <main> <!-- ヒーローセクション --> <section id="home" class="hero"> <div class="container"> <div class="hero__content"> <h2 class="hero__title">メインキャッチコピー</h2> <p class="hero__text">サイトの説明文がここに入ります。</p> <a href="#contact" class="btn btn--primary">お問い合わせ</a> </div> </div> </section> <!-- その他のセクション --> <section id="about" class="section"> <div class="container"> <h2 class="section__title">アバウト</h2> <p class="section__text">アバウト内容</p> </div> </section> </main> <!-- フッター --> <footer class="footer"> <div class="container"> <p>&copy; 2024 サイト名 All rights reserved.</p> </div> </footer> <!-- JavaScript --> <script src="js/main.js"></script> </body> </html>

ステップ3: CSSスタイリング(15分)

メインスタイル

/* CSS変数 */ :root { --primary-color: #3498db; --secondary-color: #2c3e50; --accent-color: #e74c3c; --text-color: #333; --bg-color: #fff; --border-color: #ddd; --max-width: 1200px; --header-height: 70px; } /* 共通スタイル */ .container { max-width: var(--max-width); margin: 0 auto; padding: 0 2rem; } .section { padding: 6rem 0; } .section__title { font-size: 3.2rem; margin-bottom: 2rem; text-align: center; } .btn { display: inline-block; padding: 1.2rem 2.4rem; border-radius: 4px; font-weight: 600; text-align: center; transition: all 0.3s ease; cursor: pointer; } .btn--primary { background-color: var(--primary-color); color: white; } .btn--primary:hover { background-color: #2980b9; transform: translateY(-2px); } /* ヘッダー */ .header { position: fixed; top: 0; left: 0; right: 0; height: var(--header-height); background-color: var(--bg-color); box-shadow: 0 2px 10px rgba(0, 0, 0, 0.1); z-index: 1000; } .header .container { display: flex; align-items: center; justify-content: space-between; height: 100%; } /* ナビゲーション */ .nav__list { display: flex; gap: 3rem; } .nav__link { font-weight: 500; transition: color 0.3s ease; } .nav__link:hover { color: var(--primary-color); } /* ハンバーガーメニュー */ .nav__toggle { display: none; flex-direction: column; width: 24px; height: 24px; } .nav__toggle span { width: 100%; height: 2px; background-color: var(--text-color); margin: 2px 0; transition: all 0.3s ease; } /* ヒーローセクション */ .hero { padding-top: calc(var(--header-height) + 8rem); padding-bottom: 8rem; background: linear-gradient(135deg, #667eea 0%, #764ba2 100%); color: white; text-align: center; } .hero__title { font-size: 4.8rem; margin-bottom: 2rem; animation: fadeInUp 1s ease-out; } .hero__text { font-size: 1.8rem; margin-bottom: 3rem; animation: fadeInUp 1s ease-out 0.3s both; } /* アニメーション */ @keyframes fadeInUp { from { opacity: 0; transform: translateY(30px); } to { opacity: 1; transform: translateY(0); } } /* フッター */ .footer { background-color: var(--secondary-color); color: white; text-align: center; padding: 3rem 0; }

ステップ4: JavaScript実装(10分)

インタラクション機能

class WebSiteController { constructor() { this.init(); } init() { this.setupEventListeners(); this.setupSmoothScroll(); this.setupMobileMenu(); this.setupScrollEffects(); } setupEventListeners() { document.addEventListener('DOMContentLoaded', () => { console.log('サイトが読み込まれました'); }); window.addEventListener('scroll', () => { this.handleScroll(); }); } setupSmoothScroll() { const navLinks = document.querySelectorAll('.nav__link'); navLinks.forEach(link => { link.addEventListener('click', (e) => { e.preventDefault(); const targetId = link.getAttribute('href'); const targetSection = document.querySelector(targetId); if (targetSection) { const headerHeight = document.querySelector('.header').offsetHeight; const targetPosition = targetSection.offsetTop - headerHeight; window.scrollTo({ top: targetPosition, behavior: 'smooth' }); } }); }); } setupMobileMenu() { const toggleBtn = document.querySelector('.nav__toggle'); const navList = document.querySelector('.nav__list'); if (toggleBtn) { toggleBtn.addEventListener('click', () => { navList.classList.toggle('active'); toggleBtn.classList.toggle('active'); }); } } setupScrollEffects() { const sections = document.querySelectorAll('.section'); const observerOptions = { threshold: 0.1, rootMargin: '0px 0px -100px 0px' }; const observer = new IntersectionObserver((entries) => { entries.forEach(entry => { if (entry.isIntersecting) { entry.target.style.opacity = '1'; entry.target.style.transform = 'translateY(0)'; } }); }, observerOptions); sections.forEach(section => { section.style.opacity = '0'; section.style.transform = 'translateY(20px)'; section.style.transition = 'all 0.6s ease'; observer.observe(section); }); } handleScroll() { const header = document.querySelector('.header'); if (window.scrollY > 50) { header.classList.add('scrolled'); } else { header.classList.remove('scrolled'); } } } // 初期化 const website = new WebSiteController();

📝 まとめ・質疑応答(10分)

実装のポイント

  1. 段階的な実装: HTML → CSS → JavaScript の順序で進める
  2. モバイルファースト: 小さな画面から設計を始める
  3. コンポーネント指向: 再利用可能な部品として作成
  4. パフォーマンス意識: 最適化を考慮した実装

よくある問題と解決策

  • レイアウトの崩れ: Flexbox/Gridの適切な使用
  • JavaScript エラー: console.logでのデバッグ
  • モバイル対応: メディアクエリの調整

Q&A

  • 実装中の技術的な質問
  • デザインの調整について
  • JavaScript機能の追加方法

🏠 宿題

必須課題

  1. サイト実装の完成

    • HTML/CSS/JavaScriptの統合
    • モバイル対応の確認
  2. 機能テスト

    • 全てのリンク動作確認
    • フォーム送信テスト
    • レスポンシブデザイン確認

オプション課題

  1. 追加機能実装

    • アニメーション効果
    • API連携
    • ローディング機能
  2. パフォーマンス最適化

    • 画像圧縮
    • CSS/JavaScript圧縮

提出物

  • 完成したWebサイト(全ファイル)
  • デモ用URL(GitHub Pages等)
  • 実装報告書(機能説明)

次回予告: 第13回では完成したサイトの発表とコース全体の振り返りを行います。自分の作品を自信を持って発表できるよう、今回で完成度を高めましょう!

Last updated on