実践プロジェクト レッスン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>© 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">💻</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">⚡</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 でデプロイして公開しよう