HTML/CSSでプロフィールサイトを作ってみよう(総合演習)
ここまでの HTML/CSS レッスンで学んだことを全部つないで、1枚のプロフィールサイトを完成させます。新しいタグやプロパティは出てきません。見出し・リスト・クラス・Flexbox・Grid・メディアクエリ——すでに練習したものだけで作れます。
各ステップの枠は画像ではなく本物のブラウザ表示です。コードを書き換えて「表示結果を更新」を押せば、その場で見た目が変わります。
写真は1枚も使いません。アイコンはSVGで描いた自作のものです。外部の画像に頼らないので、どこに置いてもそのまま動きます。
完成イメージ
最後まで進むと、こう表示されるところまで作ります。下の枠は本物のブラウザ表示で、画像ではありません。
STEP 1文章の骨組みを作る
🎯 このステップのゴール: 見出し・段落・リストで、意味のある構造を先に作る
いきなり見た目から入りたくなりますが、まずは中身の構造からです。デザインを当てるのは後で、先に「何が書いてあるか」を決めます。
使うタグにはそれぞれ意味があります。<h1>はページで一番大事な見出し、<h2>はその下の区切り、<p>は段落、<ul>と<li>は箇条書きです。見た目のために選ぶのではなく、意味で選びます。これをセマンティック(意味のある)HTMLと呼びます。
意味どおりに書いておくと、検索エンジンが内容を理解しやすくなり、読み上げソフトも正しく読めます。見た目はCSSでいくらでも変えられるので、構造で妥協する理由がありません。
この段階では飾りが一切ないので味気なく見えますが、これで正しい状態です。ブラウザの既定のスタイルだけで表示されています。
STEP 2カードの見た目にする
🎯 このステップのゴール: クラスとCSSで、色・余白・角丸・影をつける
ここからCSSです。<style>の中に書いていきます。
まずclass="card"という名前を付けて、その名前に対してスタイルを当てます。.cardのように先頭にドットを付けるとクラス名を指すという約束です。タグ名で指定すると同じタグ全部に効いてしまうので、クラスで狙いを定めるのが基本になります。
ここで効いているのがボックスモデルです。paddingが内側の余白、marginが外側の余白。margin: 0 autoは「上下は0、左右は自動」という意味で、幅を決めた要素を中央に置く定番の書き方です。
そして* { box-sizing: border-box; }——これはほぼ全てのサイトが最初に書く1行です。既定ではwidthにpaddingが含まれず、余白を足すと箱が膨らみます。この指定でwidthが見たままの幅になります。
box-shadowで薄い影を落とすと、白いカードが背景から浮いて見えます。
STEP 3アイコンと名前を横に並べる
🎯 このステップのゴール: SVGでアイコンを自作し、Flexboxで横並びにする
プロフィールらしくアイコンを置きます。写真ファイルは使いません。<svg>でその場で図形を描きます。
やっていることは単純で、円を2つと、半円のような図形を1つ重ねているだけです。<circle cx="48" cy="48" r="48">は「中心が(48,48)で半径48の円」という意味です。SVGは拡大しても粗くならないので、アイコンにはうってつけです。ファイルを用意しなくていいのも利点です。
横に並べるのがFlexboxです。並べたい要素そのものではなく、その「親」にdisplay: flexを書く——ここが最初につまずくところです。親が「中身を横に並べる箱」に変わる、と考えると分かりやすくなります。
align-items: centerで高さの中央に揃え、gap: 20pxで間隔をあけます。gapは要素の間にだけ空きますので、marginのように端の余白まで増えません。
flex: noneをアイコンに付けているのは、幅が足りないときに潰されないようにするためです。これが無いと文章に押されて楕円になります。
STEP 4スキル一覧をタイル状に並べる
🎯 このステップのゴール: CSS Gridで、画面幅に応じて自動で折り返す一覧を作る
できることの一覧をタイル状に並べます。ここでCSS Gridを使います。
要になるのがこの1行です。
grid-template-columns: repeat(auto-fit, minmax(140px, 1fr));
読み下すと「最小140px、最大は均等割りの列を、入るだけ並べる」となります。auto-fitが「入るだけ」の部分で、画面が広ければ4列、狭ければ2列、もっと狭ければ1列と、メディアクエリを1行も書かずに勝手に折り返します。
Flexboxとの違いはここです。Flexboxは1方向に並べるのが得意、Gridは行と列の両方を扱うのが得意。この「自動で折り返す一覧」はGridの独壇場で、CSSでいちばん気持ちよく効く場面のひとつです。
箇条書きのlist-style: noneとpadding: 0は、ブラウザが既定でつける中黒と字下げを消すためです。<ul>を使いつつ見た目だけ変えたいときの定番で、意味(箇条書き)は保ったままにできます。
STEP 5スマホでも崩れないようにする
🎯 このステップのゴール: メディアクエリとclamp()で、狭い画面に合わせる
スマホで見ると、アイコンと名前の横並びが窮屈になります。狭いときだけ縦に積むようにしましょう。
使うのがメディアクエリです。@media (max-width: 480px) { ... }と書くと、画面幅が480px以下のときだけ中のCSSが効きます。ここではflex-direction: columnに切り替えて縦積みにし、中央揃えにしています。
忘れてはいけないのが<head>の中のこの1行です。
<meta name="viewport" content="width=device-width, initial-scale=1.0">
これが無いと、スマホは「PC用の広い画面」のふりをして全体を縮小表示します。メディアクエリを書いても効きません。レスポンシブ対応が効かないときは、まずここを疑うのが鉄則です。
見出しにはclamp()を使っています。clamp(1.3rem, 5vw, 1.8rem)は「基本は画面幅の5%、ただし1.3remより小さくせず、1.8remより大きくしない」という意味です。これ1行で、狭い画面から広い画面までなめらかに変わります。段階ごとにメディアクエリを書く必要がありません。
右上の枠の幅を狭めて確かめたいときは、ブラウザの幅を変えてみてください。
STEP 6CSS変数と動きをつけて仕上げる
🎯 このステップのゴール: 色を変数にまとめ、リンクにhoverの反応を足す
最後の仕上げです。ここまで#3b82f6という色コードをあちこちに書いてきました。テーマ色を変えたくなったら、全部探して直すことになります。
そこでCSS変数(カスタムプロパティ)にまとめます。:rootの中に--accent: #3b82f6;と定義し、使うときはvar(--accent)と書きます。これで色の変更は1か所で済みます。--accentの値を#ef4444にでも書き換えて、「表示結果を更新」を押してみてください。サイト全体の印象が一度に変わります。
リンクには:hoverとtransitionを組み合わせます。:hoverはマウスが乗っているときの見た目、transitionはその変化を何秒かけて行うかです。
transitionは:hoverのほうではなく、元の状態に書きます。ここを間違えると、乗せたときだけなめらかで離すと一瞬で戻る、という不自然な動きになります。
transform: translateY(-2px)でボタンがわずかに浮きます。2pxで十分で、大きく動かすと落ち着かない印象になります。
完成です。名前・肩書き・スキルを自分のものに書き換えれば、そのまま自分のプロフィールサイトになります。
よくある質問
自分の写真を使いたいのですが
できます。<svg>のかたまりを<img src="photo.jpg" alt="プロフィール写真" class="avatar">に置き換え、CSSに.avatar { border-radius: 50%; object-fit: cover; }を足すと丸く切り抜けます。object-fitで画像の表示方法を調整しようで詳しく扱っています。
なおこの演習で写真を使っていないのは、外部の画像に頼らずどこでも動くようにするためです。alt属性は目に見えませんが、読み上げソフトのために必ず書いてください。
このサイトをインターネットに公開するには?
完成したコードをindex.htmlという名前で保存すれば、それがもうWebサイトです。無料で公開できる場所がいくつもあるので、ファイルを置くだけで world wide に見えるようになります。
公開するならメタタグとSEOの基本でdescriptionを書いておくと、検索結果に出る説明文を自分で決められます。
表示が思ったとおりになりません
多いのは閉じタグの書き忘れです。</div>がひとつ足りないだけで、それ以降のレイアウトが総崩れになります。
CSSではセミコロンの書き忘れが定番です。color: redのあとの;を忘れると、その次の行まで巻き込んで無視されます。「1行だけでなく2行効かない」ときは、その手前のセミコロンを確認してください。
🚩 次はこのカテゴリへ
見た目ができたら、次は動きです。ボタンを押したら表示が変わる、入力した内容で計算する——そこからがJavaScriptの領域になります。JavaScriptカテゴリの最終演習では、電卓の計算エンジンを作ります。
JavaScriptのレッスンへ進む