<CodeLearn/>
実践プロジェクト レッスン1

ポートフォリオサイト

HTML/CSS/JavaScriptで自己紹介サイトを作ろう

プロジェクト概要

最初のプロジェクトとして、自分のスキルや作品を紹介するポートフォリオサイトを作ります。 HTML/CSS/JavaScriptの基礎を組み合わせて、レスポンシブで見た目の良いサイトを完成させましょう。

必要なスキル

  • HTML の基本構造とセマンティック要素
  • CSS のFlexbox/Grid レイアウト
  • レスポンシブデザイン
  • JavaScript のDOM操作(任意)

完成物のイメージ

  • ヒーローセクション(名前・肩書き)
  • 自己紹介セクション
  • スキル一覧
  • 作品紹介(カード形式)
  • お問い合わせフォーム

ステップ1: HTMLの骨組みを作る

まずはセマンティック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="style.css" />
</head>
<body>
  <header class="hero">
    <nav class="nav">
      <a href="#about">自己紹介</a>
      <a href="#skills">スキル</a>
      <a href="#works">作品</a>
      <a href="#contact">お問い合わせ</a>
    </nav>
    <div class="hero-content">
      <h1>山田太郎</h1>
      <p>Webエンジニア / フロントエンド開発者</p>
    </div>
  </header>

  <main>
    <section id="about" class="section">
      <h2>自己紹介</h2>
      <p>こんにちは!Webエンジニアを目指して学習中の山田太郎です。</p>
    </section>

    <section id="skills" class="section">
      <h2>スキル</h2>
      <div class="skills-grid">
        <!-- スキルカードをここに追加 -->
      </div>
    </section>

    <section id="works" class="section">
      <h2>作品</h2>
      <div class="works-grid">
        <!-- 作品カードをここに追加 -->
      </div>
    </section>

    <section id="contact" class="section">
      <h2>お問い合わせ</h2>
      <form class="contact-form">
        <input type="text" name="name" placeholder="お名前" required />
        <input type="email" name="email" placeholder="メールアドレス" required />
        <textarea name="message" placeholder="メッセージ" rows="5" required></textarea>
        <button type="submit">送信</button>
      </form>
    </section>
  </main>

  <footer>
    <p>&copy; 2026 山田太郎</p>
  </footer>
</body>
</html>

ステップ2: CSSでデザインを整える

/* リセットと基本スタイル */
* { margin: 0; padding: 0; box-sizing: border-box; }
body { font-family: "Noto Sans JP", sans-serif; color: #333; }

/* ヒーローセクション */
.hero {
  background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
  color: white;
  min-height: 100vh;
  display: flex;
  flex-direction: column;
  justify-content: center;
  align-items: center;
  text-align: center;
}
.hero h1 { font-size: 3rem; margin-bottom: 0.5rem; }
.hero p { font-size: 1.2rem; opacity: 0.9; }

/* ナビゲーション */
.nav {
  position: fixed;
  top: 0;
  width: 100%;
  padding: 1rem 2rem;
  display: flex;
  gap: 2rem;
  justify-content: center;
  background: rgba(0, 0, 0, 0.2);
  backdrop-filter: blur(10px);
}
.nav a { color: white; text-decoration: none; }

/* セクション */
.section {
  max-width: 900px;
  margin: 0 auto;
  padding: 4rem 1.5rem;
}
.section h2 {
  font-size: 2rem;
  margin-bottom: 1.5rem;
  text-align: center;
}

/* スキル・作品グリッド */
.skills-grid, .works-grid {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(250px, 1fr));
  gap: 1.5rem;
}

/* レスポンシブ */
@media (max-width: 768px) {
  .hero h1 { font-size: 2rem; }
  .nav { gap: 1rem; font-size: 0.9rem; }
}

ステップ3: スキルカードを作る

<!-- スキルカードのHTML -->
<div class="skill-card">
  <div class="skill-icon">&#128187;</div>
  <h3>HTML / CSS</h3>
  <div class="skill-bar">
    <div class="skill-fill" style="width: 90%"></div>
  </div>
</div>

<div class="skill-card">
  <div class="skill-icon">&#9889;</div>
  <h3>JavaScript</h3>
  <div class="skill-bar">
    <div class="skill-fill" style="width: 75%"></div>
  </div>
</div>

<!-- スキルバーのCSS -->
<style>
.skill-card {
  background: white;
  border-radius: 12px;
  padding: 1.5rem;
  box-shadow: 0 2px 8px rgba(0,0,0,0.1);
  text-align: center;
}
.skill-icon { font-size: 2rem; margin-bottom: 0.5rem; }
.skill-bar {
  height: 8px;
  background: #e0e0e0;
  border-radius: 4px;
  margin-top: 0.8rem;
  overflow: hidden;
}
.skill-fill {
  height: 100%;
  background: linear-gradient(90deg, #667eea, #764ba2);
  border-radius: 4px;
  transition: width 1s ease;
}
</style>

ステップ4: JavaScriptでインタラクションを追加

// スムーズスクロール
document.querySelectorAll('.nav a').forEach(link => {
  link.addEventListener('click', (e) => {
    e.preventDefault();
    const target = document.querySelector(link.getAttribute('href'));
    target.scrollIntoView({ behavior: 'smooth' });
  });
});

// スクロール時のフェードインアニメーション
const observer = new IntersectionObserver((entries) => {
  entries.forEach(entry => {
    if (entry.isIntersecting) {
      entry.target.classList.add('visible');
    }
  });
}, { threshold: 0.1 });

document.querySelectorAll('.section').forEach(section => {
  section.classList.add('fade-in');
  observer.observe(section);
});

// フォーム送信の処理
document.querySelector('.contact-form').addEventListener('submit', (e) => {
  e.preventDefault();
  const formData = new FormData(e.target);
  const data = Object.fromEntries(formData);
  console.log('送信データ:', data);
  alert('送信しました(デモ)');
  e.target.reset();
});

まとめ

  • セマンティックHTMLで意味のある構造を作る
  • CSS Flexbox/Grid でレスポンシブなレイアウトを実現
  • グラデーションや shadow でリッチなデザインに仕上げる
  • IntersectionObserver でスクロールアニメーションを追加
  • 完成したら GitHub Pages や Vercel でデプロイして公開しよう