画像にキャプションを重ねよう(Gridとアニメーション)

  • figure + figcaption で、画像にキャプションを重ねて表示
  • GridやFlexを使ってレイアウトを統一させる
  • ::before / ::after を使って見出しにデザインを加える
  • :root に色指定を集約してテーマ化を進める

作成ファイル・保存場所

  • css-basic フォルダに下記の2ファイルを作成
    • HTML: 12.htmlHTMLファイルはコピーして使用可
    • CSS: style12.cssスタイルシートのファイルは作成
htmlは下記からコピー
<!DOCTYPE html>
<html lang="ja">

<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>HTML課題12</title>
    <link rel="stylesheet" href="style12.css">
</head>

<body>

    <!-- サイト全体のヘッダー -->
    <header>
        <div class="header-top">
            <h1>My Portfolio</h1>
            <nav>
                <ul>
                    <li><a href="#services">About</a></li>
                    <li><a href="#works">Works</a></li>
                    <li><a href="#profile">Profile</a></li>
                </ul>
            </nav>
        </div>
    </header>

    <!-- メインコンテンツ -->
    <main>
        <section id="services">
            <h2>About</h2>
            <p>
                Webデザインとフロントエンド開発を学びながら、個人で制作活動を行っています。<br>
                HTML / CSS / JavaScript を中心に、ユーザーにとってわかりやすく、伝わりやすいデザインを意識しています。
            </p>
        </section>

        <section id="works">
            <h2>Works</h2>
            <p>FigmaでデザインしたLPをコーディングしました</p>
            <div class="works-list">
                <figure>
                    <img src="https://dummy.kobeya.com/?width=600&height=375&text=Work+A" alt="作品Aのサムネイル画像">
                    <figcaption>作品A - Webサイトデザイン(2025年)</figcaption>
                </figure>

                <figure>
                    <img src="https://dummy.kobeya.com/?width=600&height=375&text=Work+B" alt="作品Bのサムネイル画像">
                    <figcaption>作品B - スマホアプリUI設計</figcaption>
                </figure>

                <figure>
                    <img src="https://dummy.kobeya.com/?width=600&height=375&text=Work+A" alt="作品Aのサムネイル画像">
                    <figcaption>作品C - Webサイトデザイン(2024年)</figcaption>
                </figure>

                <figure>
                    <img src="https://dummy.kobeya.com/?width=600&height=375&text=Work+B" alt="作品Bのサムネイル画像">
                    <figcaption>作品D - スマホアプリUI設計</figcaption>
                </figure>
            </div>
        </section>

        <section id="profile">
            <h2>Profile</h2>
            <ul class="profile-list">
                <li>名前:Y. Nakamura</li>
                <li>居住地:福岡県</li>
                <li>学習歴:約1年(独学+職業訓練)</li>
                <li>得意分野:レスポンシブデザイン、HTML/CSSの構造設計</li>
                <li>今後の目標:WordPressやFigmaを活用したWeb制作にも取り組みたいと考えています。
            </ul>
        </section>


    </main>

    <!-- サイト全体のフッター -->
    <footer>
        <p><small>&copy; 2025 MySite</small></p>
    </footer>

</body>

</html>

チェックポイント

  • PC は hover するとキャプションが漏れなく表示される
  • SP は最初から表示されている
  • Gridレイアウトはスマホ/パソコンで整合されている
  • 色は :root で管理され、CSSに縦線的な継承がある
  • 見出し h2 には ::before / ::after が適切に使われている

今回使うCSSプロパティのポイント

CSS変数に関するプロパティ

プロパティ・構文説明
:rootCSS変数(カスタムプロパティ)を定義するセレクタ。全体共通の値を設定するのに使用。例:テーマカラーなど。
var(--変数名):root で定義した変数を呼び出して使用する構文。例:color: var(--color-text);

overflow の指定

プロパティ・値説明
overflow: hidden;はみ出た部分を完全に隠す。ホバー演出や画像の切り抜きによく使われる。
overflow: auto;はみ出したときだけ自動的にスクロールバーを表示する。
overflow: scroll;常にスクロールバーを表示する(たとえ不要でも)。

opacity に関する指定

プロパティ・値説明
opacity: 1;不透明(通常表示)
opacity: 0;完全に透明。要素は見えないが、存在はしている

transform + transition に関する指定

プロパティ・構文説明
transform: translateY();要素を上下(Y軸)や左右(X軸)に移動させる指定。translateY(-100%) で上に非表示、translateY(0) で元位置へ。
transition: all 0.4s ease;状態変化(例:hover)のときにスムーズに変化する演出。対象全体(all)に0.4秒の変化を適用。

補足:擬似要素 ::before, ::after

主な特徴

項目内容
対象要素通常の HTML 要素(例:h2, button, p など)に適用できる
表示位置::before は要素の最初に、::after最後に追加される
必須指定content プロパティが 必須(ないと何も表示されない)
表現用途飾り線、アイコン、記号、バッジ、フレームなど
h2::before,
h2::after {
  content: "";
  display: block;
  width: 30%;
  height: 1px;
  background-color: #ccc;
  position: absolute;
  top: 50%;
}

h2::before {
  left: 0;
}

h2::after {
  right: 0;
}

この例では、h2 の左右に線を引くような見た目になります(中央に見出し、両端に水平線)。

指示

  1. html12.html のレイアウトに、figure と figcaption を使った作品表示を追加
  2. figcaptionは、PCは hover でスライド表示、SPは最初から表示
  3. h2 には ::before / ::after を使って左右線を付ける
  4. 色指定は :root で変数化

スタイルの指定内容

1. リセットと基本設定

  • * { box-sizing: border-box; }margin: 0; padding: 0; でリセット
  • html { font-size: 100%; scroll-behavior: smooth; }
  • body に "Meiryo", sans-seriffont-size: 0.9375rembackground-color: var(--color-bg) などを指定

2. 色の変数化 (:root)

  • :root でカラーバリエーションを管理
    例: --color-bg--color-text--color-accent--color-footer-bg, など
  • コード全体で var(--color-****) を使い統一的に配色

3. ヘッダーとナビゲーション

  • .header-top はスマホで縦並び、PC (min-width: 768px) で flex-direction: row
  • nav ul : display: flex; gap: 1rem; list-style: none;
  • nav a : 強調色 (--color-accent)、hover で下線

4. 見出し (h2) に ::before / ::after

  • 中央揃え: text-align: center;
  • ::before / ::after を使い、h2 左右に水平線を入れる
  • 線の色は --color-line; 幅や位置は自由に調整

5. 作品リスト (.works-list)

  • display: grid; grid-template-columns: repeat(auto-fit, minmax(300px, 1fr));
  • gap: 2rem; で作品間に余白
  • figure { position: relative; overflow: hidden; }

6. figcaption のアニメーション

  • PC (min-width: 768px): hover で opacity と transform によりスライド表示
  • SP (max-width: 767px): そのまま表示 (opacity: 1; transform: none;)
  • 背景は --color-overlay (例: rgba(0,0,0,0.6))、文字色は --color-footer-text などを使用

7. プロフィールリスト

  • .profile-list に border: 1px solid var(--color-border); と padding: 1rem;
  • リストマーカー位置を list-style-position: inside; に

8. フッター

  • 背景: --color-footer-bg, 文字色: --color-footer-text
  • text-align: center; padding: 2rem 1rem;

rootの書き方例

下記コードはCSSにコピーしてもOK

:root {
  --color-bg: #fefefe;
  --color-text: #333;
  --color-heading: #444;
  --color-accent: #032579;
  --color-border: #ddd;
  --color-overlay: rgba(0, 0, 0, 0.6);
  --color-footer-bg: #333;
  --color-footer-text: #fff;
  --color-line: #ccc;
}

h2 {
  position: relative;
  font-size: 1.25rem;
  text-align: center;
  color: var(--color-heading);
  margin: 2rem 0 1rem;
}

h2::before,
h2::after {
  content: "";
  position: absolute;
  top: 50%;
  width: 30%;
  height: 1px;
  background-color: var(--color-line);
}

h2::before {
  left: 0;
}

h2::after {
  right: 0;
}

表示例(画面イメージ)

解答例(CSS)

/* --- 色を変数で管理 --- */
:root {
    --color-bg: #fefefe;
    --color-text: #333;
    --color-heading: #444;
    --color-accent: #032579;
    --color-border: #ddd;
    --color-overlay: rgba(0, 0, 0, 0.6);
    --color-footer-bg: #333;
    --color-footer-text: #fff;
    --color-line: #ccc;
}

/* --- リセットと基本 --- */
* {
    margin: 0;
    padding: 0;
    box-sizing: border-box;
}

html {
    font-size: 100%;
    scroll-behavior: smooth;
}

body {
    font-family: "メイリオ", sans-serif;
    font-size: 0.9375rem;
    line-height: 1.7;
    background-color: var(--color-bg);
    color: var(--color-text);
}

/* --- ヘッダー部分 --- */
header {
    background-color: #f2f2f2;
    padding: 1.5rem 2rem;
    border-bottom: 2px solid var(--color-border);
}

.header-top {
    display: flex;
    flex-direction: column;
    flex-wrap: wrap;
    justify-content: space-between;
    align-items: center;
}

@media (min-width: 768px) {
    .header-top {
        flex-direction: row;
    }
}

h1 {
    font-size: 1.5rem;
    color: var(--color-text);
}

/* --- ナビゲーションメニュー --- */
nav ul {
    display: flex;
    gap: 1rem;
    list-style: none;
}

nav a {
    text-decoration: none;
    color: var(--color-accent);
    font-weight: bold;
}

nav a:hover {
    text-decoration: underline;
}

/* --- メインコンテンツ --- */
main {
    max-width: 960px;
    width: calc(100% - 2rem);
    margin: 2rem auto;
}

section {
    margin-bottom: 4rem;
}

h2 {
    position: relative;
    font-size: 1.25rem;
    margin: 2rem 0 1rem;
    color: var(--color-heading);
    text-align: center;
}

h2::before,
h2::after {
    content: "";
    position: absolute;
    top: 50%;
    width: 30%;
    height: 1px;
    background-color: var(--color-line);
}

h2::before {
    left: 0%;
}

h2::after {
    right: 0%;
}

section p {
    margin-bottom: 1rem;
}

/* --- works構造 --- */
.works-list {
    display: grid;
    grid-template-columns: repeat(auto-fit, minmax(300px, 1fr));
    gap: 2rem;
}

.works-list figure {
    position: relative;
    overflow: hidden;
}

.works-list figure img {
    width: 100%;
    height: auto;
    display: block;
}

/* --- PC(ホバーで表示) --- */
@media (min-width: 768px) {
    .works-list figcaption {
        position: absolute;
        top: 0;
        left: 0;
        right: 0;
        bottom: 0;
        background-color: var(--color-overlay);
        color: var(--color-footer-text);
        font-size: 0.875rem;
        padding: 1rem;
        display: flex;
        align-items: center;
        justify-content: center;
        text-align: center;
        opacity: 0;
        transform: translateY(-100%);
        transition: all 0.4s ease;
    }

    .works-list figure:hover figcaption {
        opacity: 1;
        transform: translateY(0);
    }
}

/* --- SP(常時表示) --- */
@media (max-width: 767px) {
    .works-list figcaption {
        position: absolute;
        left: 0;
        right: 0;
        bottom: 0;
        background-color: var(--color-overlay);
        color: var(--color-footer-text);
        font-size: 0.875rem;
        padding: 1rem;
        display: flex;
        align-items: center;
        justify-content: center;
        text-align: center;
        opacity: 1;
        transform: translateY(0);
    }
}

/* --- Profileリスト --- */
.profile-list {
    list-style-position: inside;
    border: 1px solid var(--color-border);
    padding: 1rem;
}

/* --- フッター --- */
footer {
    background-color: var(--color-footer-bg);
    color: var(--color-footer-text);
    text-align: center;
    padding: 2rem 1rem;
}