AI先生のロボットキャラクター
第3章 - セクション3

右上に折り目があるカードデザイン

右上に折り目があるカードです。NEW/HOT/CHECKなどのラベル付きで、ホバー時に折り目が開くアニメーションとなります

折り紙のような折り目デザイン

紙の書類やノートの右上を折って目印をつける――そんな日常的な仕草をWebデザインに取り入れたのが、折り目付きカードデザインです。

clip-pathと疑似要素を組み合わせることで、まるで紙を折ったかのようなリアルな表現を実現します。NEW/HOT/CHECKなどのラベルを折り目の中に配置し、ホバー時に折り目が開くアニメーションで、ユーザーの注目を集めながらも主要なコンテンツを邪魔しない絶妙なバランスを生み出します。

作成した折り目付きカードデザイン

HTML
<div class="card-list">

    <!-- Card 1: NEW -->
    <a href="#" class="fold-card card-new" data-label="NEW">
        <!-- アイコン: 星 -->
        <svg class="card-icon" fill="currentColor" viewbox="0 0 24 24">
            <path d="M12 2l3.09 6.26L22 9.27l-5 4.87 1.18 6.88L12 17.77l-6.18 3.25L7 14.14 2 9.27l6.91-1.01L12 2z"></path>
        </svg>
        <h3 class="card-title">New Feature</h3>
        <p class="card-desc">最新の機能をご紹介します。アップデートされたUIと高速化されたパフォーマンスを体験してください。</p>
    </a>

    <!-- Card 2: PICK UP -->
    <a href="#" class="fold-card card-pickup" data-label="HOT">
        <!-- アイコン: 電球 -->
        <svg class="card-icon" fill="currentColor" viewbox="0 0 24 24">
            <path d="M9 21c0 .55.45 1 1 1h4c.55 0 1-.45 1-1v-1H9v1zm3-19C8.14 2 5 5.14 5 9c0 2.38 1.19 4.47 3 5.74V17c0 .55.45 1 1 1h6c.55 0 1-.45 1-1v-2.26c1.81-1.27 3-3.36 3-5.74 0-3.86-3.14-7-7-7z"></path>
        </svg>
        <h3 class="card-title">Recommendation</h3>
        <p class="card-desc">編集部が厳選したおすすめ記事です。今週のトレンドと注目のトピックを深掘りします。</p>
    </a>

    <!-- Card 3: CHECK -->
    <a href="#" class="fold-card card-check" data-label="CHECK">
        <!-- アイコン: チェック -->
        <svg class="card-icon" fill="currentColor" viewbox="0 0 24 24">
            <path d="M12 2C6.48 2 2 6.48 2 12s4.48 10 10 10 10-4.48 10-10S17.52 2 12 2zm-2 15l-5-5 1.41-1.41L10 14.17l7.59-7.59L19 8l-9 9z"></path>
        </svg>
        <h3 class="card-title">Don't Miss It</h3>
        <p class="card-desc">見逃せない重要なお知らせです。キャンペーン情報や期間限定のオファーをご確認ください。</p>
    </a>

</div>
CSS
body {
    display: flex;
    justify-content: center;
    align-items: center;
    min-height: 100vh;
    background-color: #f0f2f5;
    font-family: 'Helvetica Neue', Arial, sans-serif;
    margin: 0;
    padding: 20px;
}

.card-list {
    display: flex;
    gap: 30px;
    justify-content: center;
    padding: 20px;
}

/* 
 * 折り目カードのスタイル 
 */
.fold-card {
    position: relative;
    display: flex;
    flex-direction: column;
    justify-content: flex-start;
    /* コンテンツ位置を上揃えに変更 */
    align-items: center;
    width:240px;
    height: 320px;
    padding: 50px 20px 30px;
    /* 上パディングを多めに設定 */
    box-sizing: border-box;
    background: #ffffff;
    color: #333;
    text-decoration: none;

    /* 黒いボーダー */
    border: 3px solid #333;

    /* 折り目の設定 */
    --fold-size: 60px;
    --fold-color: #333;

    /* 
     * 右上が欠けた形状
     * 親要素自体を切り抜くことで、borderも一緒に切り抜かれる
     * ::before, ::after もこの領域内でしか表示されない
     */
    clip-path: polygon(0 0,
            calc(100% - var(--fold-size)) 0,
            100% var(--fold-size),
            100% 100%,
            0 100%);

    transition: clip-path 0.4s cubic-bezier(0.25, 1, 0.5, 1),
        transform 0.3s ease,
        box-shadow 0.3s ease;

    /* 影(drop-shadow推奨) */
    filter: drop-shadow(0 10px 10px rgba(0, 0, 0, 0.08));
}

/* 
 * 折り返しの三角部分 (::before)
 * 右上隅に配置し、親のclip-pathによって「左下の三角部分」だけが残るようにする
 */
.fold-card::before {
    content: '';
    position: absolute;
    top: 0;
    right: 0;
    width: var(--fold-size);
    height: var(--fold-size);
    background: var(--fold-color);
    background-image: linear-gradient(to bottom left, rgba(0, 0, 0, 0.1) 50%, rgba(0, 0, 0, 0.2) 100%);

    /* めくれ感のある影 */
    box-shadow: -2px 2px 5px rgba(0, 0, 0, 0.2);

    transition: width 0.4s cubic-bezier(0.25, 1, 0.5, 1),
        height 0.4s cubic-bezier(0.25, 1, 0.5, 1);

    pointer-events: none;
    z-index: 10;
}

/* 
 * ラベルテキスト (::after)
 * 折り目の中に表示する
 * クリップされた領域の内側(左下の三角形部分)に配置する必要があるため
 * 位置調整を慎重に行う
 */
.fold-card::after {
    content: attr(data-label);
    position: absolute;
    /* 
     * 折り目の正方形サイズ60pxに対して、
     * 左下半分が残る領域。
     * 斜辺の中央付近に来るように調整。
     */
    top: 8px;
    right: 8px;
    width: 60px;
    /* var(--fold-size)と同値 */
    height: 60px;

    display: flex;
    align-items: center;
    justify-content: center;

    text-align: center;
    color: #fff;
    font-size: 11px;
    font-weight: bold;
    letter-spacing: 1px;

    /* 45度回転させて斜辺に沿わせる */
    transform: rotate(45deg);

    z-index: 11;
    pointer-events: none;
    /* 折り目(::before)のアニメーション設定に合わせる */
    transition: opacity 0.4s cubic-bezier(0.25, 1, 0.5, 1),
        top 0.4s cubic-bezier(0.25, 1, 0.5, 1),
        right 0.4s cubic-bezier(0.25, 1, 0.5, 1),
        transform 0.4s cubic-bezier(0.25, 1, 0.5, 1);
}

/* --- ホバー時のアニメーション --- */

.fold-card:hover {
    /* 全体が少し浮き上がる */
    transform: translateY(-5px);
    filter: drop-shadow(0 15px 20px rgba(0, 0, 0, 0.15));

    /* 右上の欠けをなくす(四角に戻す) */
    clip-path: polygon(0 0,
            100% 0,
            100% 0,
            100% 100%,
            0 100%);
}

/* 折り目を消す(サイズ0へ) */
.fold-card:hover::before {
    width: 0;
    height: 0;
}

/* ラベルを消す(右上に縮小しながら移動) */
.fold-card:hover::after {
    opacity: 0;
    top: 0;
    right: 0;
    transform: scale(0) rotate(45deg);
}

/* コンテンツのスタイル */
.card-icon {
    /* アイコンエリアの高さを固定して位置ズレ防止 */
    flex-shrink: 0;
    /* 縮小させない */
    width: 80px;
    /* サイズアップ: 64px -> 80px */
    height: 80px;
    margin-bottom: 25px;
    /* マージンも少し広げてゆとりを持たせる */
    color: #333;
    /* アイコンは白黒(黒) */
    transition: transform 0.4s ease;
}

.fold-card:hover .card-icon {
    transform: scale(1.1);
}

/* タイトルは色替えする */
.card-title {
    font-size: 20px;
    font-weight: bold;
    margin: 0 0 10px 0;
    color: var(--fold-color);
    /* タイトル色を折り目色に合わせる */
}

.card-desc {
    font-size: 14px;
    color: #666;
    line-height: 1.6;
    margin: 0;
}

/* --- カラーバリエーション --- */
/* 
 * 添付画像のようなCMYK風の明るいモダンカラーに変更
 * テキストが白抜きでも読める程度の濃さを維持しつつ、彩度を高める
 */

/* 1. NEW: マゼンタ/ピンク系 */
.card-new {
    --fold-color: #E94576;
}

/* 2. PICK UP: シアン/スカイブルー系 */
.card-pickup {
    --fold-color: #49B4F1;
}

/* 3. CHECK: イエロー/ゴールド系 (白文字が読めるように少しオレンジ寄り) */
.card-check {
    --fold-color: #FCDA33;
}

/* 
 * 下部のアクセントライン
 * 添付画像のボタンのような存在感を出すため、底辺に太いボーダー風の装飾を追加
 * ::after と競合しないよう、box-shadowのinsetを利用するか、border-bottomで対応
 */
.fold-card {
    /* 
     * 下部のアクセントラインを削除し、
     * シンプルな黒枠統一に戻して全体のバランスを整える
     */
    border: 3px solid #333;
}

このカードの特徴

  • clip-pathで折り目を表現 五角形のポリゴンでカード右上を切り取り、紙を折ったような形状を実現
  • 疑似要素で立体感 ::beforeで折り返し部分を、::afterでラベルテキストを配置し、リアルな折り目を表現
  • data属性でラベル管理 HTMLのdata-label属性でラベルテキストを指定し、CSS側でattr()関数で取得
  • CSS変数でカラーバリエーション --fold-colorでカード種類ごとに色を管理し、保守性を向上
  • ホバーで折り目が開く ホバー時に折り目がスムーズに消え、カードが四角形に戻るアニメーション

コードのポイント

clip-pathで五角形を作る:
.fold-card {
    --fold-size: 60px;
    clip-path: polygon(
        0 0,                             /* 左上 */
        calc(100% - var(--fold-size)) 0, /* 右上(折り目の始点) */
        100% var(--fold-size),           /* 右上(折り目の終点) */
        100% 100%,                       /* 右下 */
        0 100%                           /* 左下 */
    );
}
  • polygon()で5つの座標を指定し、五角形を作成
  • 右上の2点で折り目の斜辺を表現
  • --fold-sizeで折り目のサイズを一元管理
折り目の三角形(::before):
.fold-card::before {
    content: '';
    position: absolute;
    top: 0;
    right: 0;
    width: var(--fold-size);
    height: var(--fold-size);
    background: var(--fold-color);
    background-image: linear-gradient(
        to bottom left, 
        rgba(0, 0, 0, 0.1) 50%, 
        rgba(0, 0, 0, 0.2) 100%
    );
    box-shadow: -2px 2px 5px rgba(0, 0, 0, 0.2);
}
  • 親のclip-pathで切り取られて、左下の三角形だけが表示される
  • グラデーションで折り返し部分の影を表現
  • box-shadowでめくれ上がった感じを演出
ラベルテキスト(::after):
.fold-card::after {
    content: attr(data-label); /* data属性から取得 */
    position: absolute;
    top: 8px;
    right: 8px;
    width: 60px;
    height: 60px;
    
    display: flex;
    align-items: center;
    justify-content: center;
    
    color: #fff;
    font-size: 11px;
    font-weight: bold;
    
    transform: rotate(45deg); /* 45度回転で斜辺に沿わせる */
}
  • attr(data-label)でHTMLから動的にテキストを取得
  • transform: rotate(45deg)で斜辺の角度に合わせる
  • flexboxで中央配置し、読みやすく表示
ホバーアニメーション:
.fold-card:hover {
    /* 四角形に戻す */
    clip-path: polygon(
        0 0, 
        100% 0, 
        100% 0,  /* 折り目の始点と終点を同じに */
        100% 100%, 
        0 100%
    );
}

.fold-card:hover::before {
    width: 0;
    height: 0; /* 折り目を縮小 */
}

.fold-card:hover::after {
    opacity: 0;
    transform: scale(0) rotate(45deg); /* ラベルを縮小 */
}
  • clip-pathの座標を変化させて折り目を消す
  • 疑似要素のサイズを0にして折り目とラベルを非表示
  • cubic-bezier(0.25, 1, 0.5, 1)で滑らかなアニメーション

まとめ

折り目付きカードデザインは、clip-pathと疑似要素を巧みに組み合わせた、リアルで印象的なUIパーツです。紙を折るという身近な仕草をデジタル空間に再現することで、ユーザーに親しみやすさと新鮮さの両方を提供します。NEW/HOT/CHECKなどのラベルを折り目の中に配置することで、重要な情報を目立たせつつ、ホバー時には邪魔にならないよう消えるという、機能性とデザイン性を両立した設計になっています。

折り目付きカード作成のポイント
  • clip-pathで形状を作る polygon()で五角形を定義し、折り目の形状を実現
  • 疑似要素で立体表現 ::beforeで折り返し部分、::afterでラベルを配置
  • グラデーションと影で奥行き 折り目に陰影をつけてリアルな立体感を演出
  • CSS変数で保守性向上 折り目サイズや色を変数で管理し、カスタマイズを容易に
  • data属性で柔軟性 HTMLからラベルテキストを指定でき、再利用性が高い

学習チェック

このレッスンを理解できたら「完了」をクリックしてください。
後で見直したい場合は「未完了に戻す」で進捗をリセットできます。

レッスン完了!🎉

お疲れさまでした!