Documentation CSS

概要

CSSjustify-selfプロパティは、グリッドアイテムを個別に**インライン軸(inline axis)**方向に配置するためのプロパティです。このプロパティを使用することで、コンテナ全体のjustify-items設定を個別のアイテムで上書きできます。例えば、すべてのアイテムが左揃えの中で、特定のアイテムだけを中央に寄せたり、右端に寄せたりといった細かいコントロールが可能になります。

justify-itemsとの違い

justify-selfjustify-itemsは似ていますが、適用先が異なります。

比較表

プロパティ適用先対象優先度
justify-itemsコンテナすべてのアイテム低い(デフォルト値)
justify-selfアイテム個別のアイテム高い(個別設定)

コード例での比較

/* justify-items: すべてのアイテムに適用 */
.container {
  display: grid;
  justify-items: start; /* すべてのアイテムを左揃え */
}

/* justify-self: 個別のアイテムのみ上書き */
.item-special {
  justify-self: end; /* このアイテムだけ右揃え */
}

結果:ほとんどのアイテムは左揃えだが、.item-specialだけは右揃えになります。

FlexboxとGridでの動作の違い

CSS Gridでの動作(完全サポート)

CSS Gridでは、justify-selfは期待通りに動作します。

.grid-container {
  display: grid;
  grid-template-columns: repeat(3, 1fr);
}

.grid-item {
  justify-self: center; /* ✅ 動作する */
}

Flexboxでの動作(主軸では動作しない)

重要:Flexboxの主軸(main axis)では、justify-self動作しません

/* ❌ Flexboxの主軸では効かない */
.flex-container {
  display: flex;
  flex-direction: row; /* 主軸は水平 */
}

.flex-item {
  justify-self: center; /* 効果なし */
}

/* ✅ 代わりにmargin: autoを使用 */
.flex-item {
  margin-left: auto; /* 右に寄せる */
  margin-right: auto; /* 中央に寄せる */
}

理由:Flexboxでは、アイテムの主軸方向の配置はコンテナレベルのjustify-contentで制御するため、個別アイテムへのjustify-selfはサポートされていません。

justify-selfの基本構文

.grid-item {
  justify-self: <値>;
}

適用条件

  • 親要素がdisplay: gridまたはdisplay: inline-gridである必要があります
  • アイテム自身に適用します(コンテナには適用しません)

基本的な使用パターン

/* パターン1: デフォルトは継承、一部だけ変更 */
.container {
  display: grid;
  justify-items: start; /* すべて左揃え */
}

.item-center {
  justify-self: center; /* このアイテムだけ中央揃え */
}

/* パターン2: デフォルトのまま、必要なアイテムだけ配置 */
.container {
  display: grid;
  /* justify-itemsは指定しない(stretchがデフォルト) */
}

.item-end {
  justify-self: end; /* このアイテムだけ右揃え */
}

値の種類と視覚的な説明

基本的な配置値

auto(初期値)

親のjustify-itemsの値を継承します。

.item {
  justify-self: auto; /* 親のjustify-itemsに従う */
}

start

アイテムをセルのインライン軸の始点(通常は左端)に配置します。

.item {
  justify-self: start;
}

視覚的なイメージ(セル内)

[Item]_________

end

アイテムをセルのインライン軸の終点(通常は右端)に配置します。

.item {
  justify-self: end;
}

視覚的なイメージ(セル内)

_________[Item]

center

アイテムをセルのインライン軸の中央に配置します。

.item {
  justify-self: center;
}

視覚的なイメージ(セル内)

____[Item]____

stretch

アイテムをセル幅いっぱいに引き伸ばします。

.item {
  justify-self: stretch;
}

視覚的なイメージ(セル内)

[____Item____]

注意:アイテムにwidthが指定されている場合、stretchは効果がありません。

レガシー値

left

アイテムを左側に配置します。startの使用を推奨します。

.item {
  justify-self: left;
}

アイテムを右側に配置します。endの使用を推奨します。

.item {
  justify-self: right;
}

ベースライン配置

baseline

アイテムをベースラインに沿って配置します。

.item {
  justify-self: baseline;
}

グローバル値

.item {
  justify-self: inherit;   /* 親要素の値を継承 */
  justify-self: initial;   /* 初期値(auto)に設定 */
  justify-self: revert;    /* ブラウザのデフォルトに戻す */
  justify-self: unset;     /* 継承値または初期値に設定 */
}

値の比較表

アイテムの位置widthの影響使用場面
auto親の設定に従う-デフォルト動作
startセルの始点受ける左揃え要素
endセルの終点受ける右揃え要素(数値、日付)
centerセルの中央受ける中央揃え要素(ボタン)
stretchセル幅いっぱい受けない幅を揃えたい要素

実践的な使用例

例1:データテーブルの列ごとの配置

テキストは左揃え、数値は右揃え、ステータスは中央揃えにする例です。

<!DOCTYPE html>
<html lang="ja">
<head>
  <meta charset="UTF-8">
  <title>データテーブル</title>
  <style>
    .data-table {
      display: grid;
      grid-template-columns: 200px 100px 100px 120px;
      gap: 1px;
      background-color: #e0e0e0;
      border-radius: 8px;
      overflow: hidden;
      max-width: 600px;
    }

    .table-cell {
      background-color: white;
      padding: 15px;
    }

    .header {
      background-color: #2c3e50;
      color: white;
      font-weight: bold;
      justify-self: stretch; /* ヘッダーは幅いっぱい */
    }

    .text-cell {
      justify-self: start; /* テキストは左揃え */
    }

    .number-cell {
      justify-self: end; /* 数値は右揃え */
      font-variant-numeric: tabular-nums;
    }

    .status-cell {
      justify-self: center; /* ステータスは中央揃え */
    }
  </style>
</head>
<body>
  <div class="data-table">
    <!-- ヘッダー -->
    <div class="table-cell header">商品名</div>
    <div class="table-cell header">数量</div>
    <div class="table-cell header">価格</div>
    <div class="table-cell header">ステータス</div>

    <!-- データ行1 -->
    <div class="table-cell text-cell">ノートPC</div>
    <div class="table-cell number-cell">5</div>
    <div class="table-cell number-cell">¥98,000</div>
    <div class="table-cell status-cell">✅</div>

    <!-- データ行2 -->
    <div class="table-cell text-cell">マウス</div>
    <div class="table-cell number-cell">20</div>
    <div class="table-cell number-cell">¥3,500</div>
    <div class="table-cell status-cell">✅</div>

    <!-- データ行3 -->
    <div class="table-cell text-cell">キーボード</div>
    <div class="table-cell number-cell">0</div>
    <div class="table-cell number-cell">¥15,800</div>
    <div class="table-cell status-cell">❌</div>
  </div>
</body>
</html>

例2:カードグリッドでのアクションボタンの配置

カード内のボタンを個別に配置する例です。

.card-grid {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(280px, 1fr));
  gap: 25px;
  padding: 30px;
}

.card {
  display: grid;
  grid-template-rows: auto 1fr auto;
  background: white;
  border-radius: 12px;
  padding: 25px;
  box-shadow: 0 4px 12px rgba(0,0,0,0.1);
}

.card-title {
  font-size: 20px;
  font-weight: bold;
  margin-bottom: 15px;
  color: #2c3e50;
  justify-self: start; /* タイトルは左揃え */
}

.card-description {
  color: #7f8c8d;
  line-height: 1.6;
  margin-bottom: 20px;
}

.card-button {
  padding: 10px 20px;
  background-color: #3498db;
  color: white;
  border: none;
  border-radius: 6px;
  cursor: pointer;
  transition: background-color 0.3s;
}

.card-button.align-left {
  justify-self: start; /* 左に配置 */
}

.card-button.align-center {
  justify-self: center; /* 中央に配置 */
}

.card-button.align-right {
  justify-self: end; /* 右に配置 */
}

.card-button:hover {
  background-color: #2980b9;
}
<div class="card-grid">
  <div class="card">
    <h3 class="card-title">サービス A</h3>
    <p class="card-description">詳細な説明文がここに入ります。</p>
    <button class="card-button align-left">詳細を見る</button>
  </div>

  <div class="card">
    <h3 class="card-title">サービス B</h3>
    <p class="card-description">詳細な説明文がここに入ります。</p>
    <button class="card-button align-center">詳細を見る</button>
  </div>

  <div class="card">
    <h3 class="card-title">サービス C</h3>
    <p class="card-description">詳細な説明文がここに入ります。</p>
    <button class="card-button align-right">詳細を見る</button>
  </div>
</div>

例3:フォームラベルとインプットの配置

ラベルを右揃え、入力フィールドを左揃えにする例です。

.form-container {
  display: grid;
  grid-template-columns: 150px 1fr;
  gap: 20px 15px;
  max-width: 600px;
  padding: 30px;
  background-color: #f8f9fa;
  border-radius: 8px;
}

.form-label {
  justify-self: end; /* ラベルを右揃え */
  align-self: center;
  font-weight: 500;
  color: #2c3e50;
}

.form-input {
  justify-self: stretch; /* 入力フィールドは幅いっぱい */
  padding: 10px 15px;
  border: 1px solid #ddd;
  border-radius: 4px;
  font-size: 14px;
}

.form-input:focus {
  outline: none;
  border-color: #3498db;
  box-shadow: 0 0 0 3px rgba(52,152,219,0.1);
}

.form-submit {
  grid-column: 1 / -1;
  justify-self: end; /* 送信ボタンを右揃え */
  padding: 12px 30px;
  background-color: #3498db;
  color: white;
  border: none;
  border-radius: 6px;
  cursor: pointer;
  font-weight: 500;
  transition: background-color 0.3s;
}

.form-submit:hover {
  background-color: #2980b9;
}
<form class="form-container">
  <label class="form-label">お名前:</label>
  <input type="text" class="form-input" placeholder="山田 太郎">

  <label class="form-label">メール:</label>
  <input type="email" class="form-input" placeholder="example@email.com">

  <label class="form-label">電話番号:</label>
  <input type="tel" class="form-input" placeholder="090-1234-5678">

  <button type="submit" class="form-submit">送信</button>
</form>

例4:ダッシュボードウィジェットの見出し

ウィジェットのタイトルとアクションボタンを左右に配置する例です。

.widget {
  display: grid;
  grid-template-columns: 1fr auto;
  gap: 20px;
  background: white;
  border-radius: 12px;
  padding: 25px;
  box-shadow: 0 4px 12px rgba(0,0,0,0.08);
  margin-bottom: 20px;
}

.widget-title {
  justify-self: start; /* タイトルを左に */
  align-self: center;
  font-size: 20px;
  font-weight: bold;
  color: #2c3e50;
}

.widget-action {
  justify-self: end; /* アクションボタンを右に */
  align-self: center;
  padding: 8px 16px;
  background-color: #ecf0f1;
  color: #2c3e50;
  border: none;
  border-radius: 6px;
  cursor: pointer;
  font-size: 14px;
  transition: background-color 0.3s;
}

.widget-action:hover {
  background-color: #bdc3c7;
}

.widget-content {
  grid-column: 1 / -1;
  justify-self: stretch;
  padding: 20px 0;
}
<div class="widget">
  <h3 class="widget-title">売上統計</h3>
  <button class="widget-action">詳細</button>
  <div class="widget-content">
    <p>ウィジェットのコンテンツがここに表示されます。</p>
  </div>
</div>

例5:グリッドギャラリーの特定アイテム強調

通常のアイテムと強調アイテムで配置を変える例です。

.gallery {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(200px, 1fr));
  gap: 20px;
  padding: 30px;
}

.gallery-item {
  justify-self: center; /* 通常アイテムは中央 */
  width: 180px;
  height: 180px;
  border-radius: 8px;
  object-fit: cover;
  transition: transform 0.3s;
}

.gallery-item:hover {
  transform: scale(1.05);
}

.gallery-item.featured {
  justify-self: stretch; /* 強調アイテムは幅いっぱい */
  width: auto;
  height: 300px;
  grid-column: span 2; /* 2列分を占有 */
}
<div class="gallery">
  <img src="photo1.jpg" alt="写真1" class="gallery-item">
  <img src="photo2.jpg" alt="写真2" class="gallery-item featured">
  <img src="photo3.jpg" alt="写真3" class="gallery-item">
  <img src="photo4.jpg" alt="写真4" class="gallery-item">
  <img src="photo5.jpg" alt="写真5" class="gallery-item">
</div>

align-selfとの組み合わせ

justify-self(インライン軸)とalign-self(ブロック軸)を組み合わせることで、完全な2次元配置制御が可能です。

完全な中央揃え

.item-centered {
  justify-self: center; /* 水平方向の中央 */
  align-self: center; /* 垂直方向の中央 */
}

右下への配置

.item-bottom-right {
  justify-self: end; /* 水平方向の右 */
  align-self: end; /* 垂直方向の下 */
}

配置の組み合わせ例

.grid-container {
  display: grid;
  grid-template-columns: repeat(3, 1fr);
  grid-template-rows: repeat(3, 100px);
  gap: 10px;
}

/* 左上 */
.item-top-left {
  justify-self: start;
  align-self: start;
}

/* 中央上 */
.item-top-center {
  justify-self: center;
  align-self: start;
}

/* 右上 */
.item-top-right {
  justify-self: end;
  align-self: start;
}

/* 中央中央 */
.item-center-center {
  justify-self: center;
  align-self: center;
}

/* 右下 */
.item-bottom-right {
  justify-self: end;
  align-self: end;
}

place-selfショートハンド

place-selfを使用すると、align-selfjustify-selfを一度に設定できます。

基本構文

/* 個別指定 */
.item {
  align-self: center;
  justify-self: center;
}

/* ショートハンド(推奨) */
.item {
  place-self: center; /* align-self と justify-self の両方 */
}

/* 異なる値を指定 */
.item {
  place-self: start end; /* align-self: start; justify-self: end; */
}

実用例

/* すべての方向で中央揃え */
.badge {
  place-self: center; /* 最も一般的な使用例 */
}

/* 右下に配置 */
.notification {
  place-self: end; /* 両方ともend */
}

/* 上中央に配置 */
.header-icon {
  place-self: start center; /* align: start, justify: center */
}

実用的なユースケース

ケース1:バッジの配置

通知バッジを親要素の特定の位置に配置する例です。

.icon-container {
  display: grid;
  place-items: center; /* アイコンを中央に */
  width: 60px;
  height: 60px;
  position: relative;
}

.icon {
  width: 40px;
  height: 40px;
}

.badge {
  justify-self: end; /* 右に */
  align-self: start; /* 上に */
  width: 20px;
  height: 20px;
  background-color: #e74c3c;
  color: white;
  border-radius: 50%;
  display: grid;
  place-items: center;
  font-size: 12px;
  font-weight: bold;
}

ケース2:プライシングテーブルのCTAボタン

プランごとにボタンの配置を変える例です。

.pricing-grid {
  display: grid;
  grid-template-columns: repeat(3, 1fr);
  gap: 30px;
}

.pricing-plan {
  display: grid;
  grid-template-rows: auto auto auto 1fr auto;
  background: white;
  border-radius: 12px;
  padding: 30px;
  box-shadow: 0 4px 12px rgba(0,0,0,0.1);
}

.plan-name {
  justify-self: center;
  font-size: 24px;
  font-weight: bold;
}

.plan-price {
  justify-self: center;
  font-size: 48px;
  margin: 20px 0;
}

.plan-features {
  justify-self: stretch;
}

.plan-cta {
  padding: 15px 30px;
  border: none;
  border-radius: 6px;
  cursor: pointer;
  font-weight: bold;
  transition: transform 0.2s;
}

.plan-cta.basic {
  justify-self: start; /* ベーシックは左 */
  background-color: #95a5a6;
  color: white;
}

.plan-cta.standard {
  justify-self: center; /* スタンダードは中央 */
  background-color: #3498db;
  color: white;
}

.plan-cta.premium {
  justify-self: end; /* プレミアムは右 */
  background-color: #e74c3c;
  color: white;
}

.plan-cta:hover {
  transform: translateY(-2px);
}

ケース3:タイムライン

タイムラインイベントを左右交互に配置する例です。

.timeline {
  display: grid;
  grid-template-columns: 1fr 4px 1fr;
  gap: 40px 20px;
  padding: 40px 20px;
  max-width: 800px;
  margin: 0 auto;
}

.timeline-line {
  grid-column: 2;
  grid-row: 1 / -1;
  background: linear-gradient(to bottom, #3498db, #2ecc71);
  border-radius: 2px;
}

.timeline-event {
  background: white;
  padding: 20px;
  border-radius: 8px;
  box-shadow: 0 4px 12px rgba(0,0,0,0.1);
}

.timeline-event.left {
  grid-column: 1;
  justify-self: end; /* 左側イベントは右揃え */
}

.timeline-event.right {
  grid-column: 3;
  justify-self: start; /* 右側イベントは左揃え */
}

.timeline-date {
  font-size: 14px;
  color: #3498db;
  font-weight: bold;
  margin-bottom: 10px;
}

.timeline-title {
  font-size: 18px;
  font-weight: bold;
  margin-bottom: 8px;
  color: #2c3e50;
}

.timeline-description {
  color: #7f8c8d;
  line-height: 1.6;
}

ケース4:ステータスインジケーター

ステータスに応じて配置を変える例です。

.status-grid {
  display: grid;
  grid-template-columns: 200px 1fr auto;
  gap: 15px;
  align-items: center;
  padding: 15px;
  background: white;
  border-radius: 8px;
  margin-bottom: 10px;
  box-shadow: 0 2px 4px rgba(0,0,0,0.05);
}

.status-label {
  justify-self: start;
  font-weight: 500;
  color: #2c3e50;
}

.status-bar-container {
  justify-self: stretch;
  height: 8px;
  background-color: #ecf0f1;
  border-radius: 4px;
  overflow: hidden;
}

.status-bar {
  height: 100%;
  border-radius: 4px;
  transition: width 0.5s ease;
}

.status-bar.success {
  background: linear-gradient(90deg, #2ecc71, #27ae60);
}

.status-bar.warning {
  background: linear-gradient(90deg, #f39c12, #e67e22);
}

.status-bar.error {
  background: linear-gradient(90deg, #e74c3c, #c0392b);
}

.status-value {
  font-weight: bold;
  min-width: 60px;
  text-align: right;
}

.status-value.high {
  justify-self: end;
  color: #2ecc71;
}

.status-value.medium {
  justify-self: center;
  color: #f39c12;
}

.status-value.low {
  justify-self: start;
  color: #e74c3c;
}

ブラウザサポート

justify-selfプロパティは、CSS Gridをサポートするモダンブラウザで使用できます。

ブラウザCSS Gridjustify-self
Chrome57+57+
Firefox52+52+
Safari10.1+10.1+
Edge16+16+
Opera44+44+

機能検出とフォールバック

/* フォールバック:Gridがサポートされていない場合 */
.item {
  margin: 0 auto; /* 中央揃えのフォールバック */
}

/* Gridがサポートされている場合 */
@supports (display: grid) {
  .item {
    margin: 0; /* marginをリセット */
    justify-self: center; /* justify-selfを使用 */
  }
}
// JavaScriptでの機能検出
if (CSS.supports('justify-self', 'center')) {
  console.log('justify-selfがサポートされています');
} else {
  console.log('justify-selfは非サポートです');
  // フォールバック処理
}

パフォーマンスとベストプラクティス

1. stretchの条件を理解する

widthが指定されている場合、stretchは効果がありません。

/* ❌ stretchが効かない */
.item {
  width: 200px;
  justify-self: stretch;
}

/* ✅ stretchが効く */
.item {
  /* widthを指定しない */
  justify-self: stretch;
}

2. place-selfショートハンドの活用

コードを簡潔に保つためにplace-selfを使用します。

/* ❌ 冗長 */
.item {
  justify-self: center;
  align-self: center;
}

/* ✅ 簡潔 */
.item {
  place-self: center;
}

3. autoの活用

デフォルト動作で十分な場合は、明示的に指定しません。

/* 不要な指定 */
.item {
  justify-self: auto; /* デフォルトなので不要 */
}

/* 必要な時だけ指定 */
.item-special {
  justify-self: end; /* デフォルトと異なる場合のみ */
}

4. セマンティックなクラス名の使用

/* ❌ 見た目に依存したクラス名 */
.align-right {
  justify-self: end;
}

/* ✅ セマンティックなクラス名 */
.price-value {
  justify-self: end; /* 価格は右揃え */
}

.status-badge {
  justify-self: center; /* バッジは中央 */
}

トラブルシューティング

問題1:justify-selfが効かない

原因1:親要素がdisplay: gridではない

解決策

/* ❌ 効果なし */
.container {
  display: block;
}

.item {
  justify-self: center; /* 効かない */
}

/* ✅ 正しい */
.container {
  display: grid;
}

.item {
  justify-self: center; /* 効く */
}

原因2:Flexboxの主軸で使用している

解決策

/* ❌ Flexboxの主軸では効かない */
.flex-container {
  display: flex;
  flex-direction: row;
}

.flex-item {
  justify-self: center; /* 効かない */
}

/* ✅ margin: autoを使用 */
.flex-item {
  margin: 0 auto; /* 中央揃え */
}

問題2:stretchが効かない

原因:アイテムに固定幅が設定されている

解決策

/* ❌ stretchが効かない */
.item {
  width: 200px;
  justify-self: stretch;
}

/* ✅ 幅を削除 */
.item {
  /* widthを指定しない */
  justify-self: stretch;
}

問題3:中央揃えがうまくいかない

原因:アイテムのサイズがセルと同じ

解決策

.container {
  display: grid;
  grid-template-columns: 200px; /* セルサイズ */
}

.item {
  width: 100px; /* セルより小さくする */
  justify-self: center;
}

問題4:place-selfの値の順序を間違える

原因align-selfjustify-selfの順序が逆

解決策

/* ❌ 順序が逆 */
.item {
  place-self: center start; /* justify: center, align: start? */
}

/* ✅ 正しい順序 */
.item {
  place-self: start center; /* align: start, justify: center */
  /* 順序: align-self justify-self */
}

注意点とベストプラクティス

1. CSS Grid専用プロパティ

justify-selfは主にCSS Gridで使用します。Flexboxでは主軸方向では動作しません。

/* Grid: ✅ 使用可能 */
.grid-item {
  justify-self: center;
}

/* Flexbox主軸: ❌ 効果なし */
.flex-item {
  justify-self: center; /* 動作しない */
  /* 代わりにmargin: autoを使用 */
}

2. justify-itemsとの使い分け

すべてのアイテムに同じ配置を適用する場合はjustify-itemsを使用します。

/* すべてのアイテムを中央に */
.container {
  display: grid;
  justify-items: center; /* ✅ 効率的 */
}

/* ❌ 非効率 */
.item {
  justify-self: center; /* すべてのアイテムに個別指定は非効率 */
}

3. インライン軸の理解

書字方向によってインライン軸の方向が変わります。

/* 横書き(LTR): インライン軸 = 水平 */
.item {
  writing-mode: horizontal-tb;
  justify-self: end; /* 右に配置 */
}

/* 縦書き: インライン軸 = 垂直 */
.item {
  writing-mode: vertical-rl;
  justify-self: end; /* 下に配置 */
}

4. アクセシビリティへの配慮

視覚的な配置と論理的な順序を一致させることが重要です。

/* 視覚的な順序を変更する場合、HTMLの順序も検討 */
.item-visual-first {
  justify-self: start;
  /* HTMLでも最初に配置することを検討 */
}

関連プロパティ

justify-selfと一緒に使用されることが多いプロパティです。

個別アイテム配置

  • align-self:個別アイテムのブロック軸配置
  • place-selfalign-selfjustify-selfのショートハンド
.item {
  /* 個別指定 */
  justify-self: center; /* インライン軸 */
  align-self: start; /* ブロック軸 */

  /* ショートハンド */
  place-self: start center; /* align justify */
}

コンテナレベル配置

  • justify-items:すべてのアイテムのインライン軸配置
  • align-items:すべてのアイテムのブロック軸配置
  • place-itemsalign-itemsjustify-itemsのショートハンド
.container {
  display: grid;

  /* すべてのアイテムのデフォルト配置 */
  justify-items: start; /* インライン軸 */
  align-items: start; /* ブロック軸 */

  /* ショートハンド */
  place-items: start; /* 両方をstart */
}

.item-special {
  /* 特定のアイテムだけ上書き */
  justify-self: end;
  align-self: center;
}

コンテンツ配置

  • justify-content:グリッドトラック全体のインライン軸配置
  • align-content:グリッドトラック全体のブロック軸配置

コードサンプル:実践的な実装

レスポンシブカードグリッド with 個別配置

<!DOCTYPE html>
<html lang="ja">
<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>カスタム配置カードグリッド</title>
  <style>
    * {
      margin: 0;
      padding: 0;
      box-sizing: border-box;
    }

    body {
      font-family: 'Segoe UI', Tahoma, Geneva, Verdana, sans-serif;
      background-color: #f5f5f5;
      padding: 40px 20px;
    }

    .card-grid {
      display: grid;
      grid-template-columns: repeat(auto-fit, minmax(300px, 1fr));
      gap: 30px;
      max-width: 1200px;
      margin: 0 auto;
    }

    .card {
      display: grid;
      grid-template-rows: auto auto 1fr auto;
      gap: 15px;
      background: white;
      border-radius: 12px;
      padding: 30px;
      box-shadow: 0 4px 12px rgba(0,0,0,0.08);
      transition: transform 0.3s, box-shadow 0.3s;
    }

    .card:hover {
      transform: translateY(-5px);
      box-shadow: 0 8px 20px rgba(0,0,0,0.12);
    }

    .card-category {
      justify-self: start; /* カテゴリーは左揃え */
      font-size: 12px;
      text-transform: uppercase;
      color: #3498db;
      font-weight: 600;
      letter-spacing: 0.5px;
      padding: 4px 12px;
      background-color: rgba(52,152,219,0.1);
      border-radius: 4px;
    }

    .card-title {
      justify-self: stretch;
      font-size: 24px;
      font-weight: bold;
      color: #2c3e50;
    }

    .card-description {
      justify-self: stretch;
      color: #7f8c8d;
      line-height: 1.6;
    }

    .card-footer {
      display: grid;
      grid-template-columns: 1fr auto;
      gap: 15px;
      align-items: center;
      padding-top: 15px;
      border-top: 1px solid #ecf0f1;
    }

    .card-price {
      justify-self: start; /* 価格は左揃え */
      font-size: 28px;
      font-weight: bold;
      color: #2c3e50;
    }

    .card-button {
      justify-self: end; /* ボタンは右揃え */
      padding: 12px 24px;
      background-color: #3498db;
      color: white;
      border: none;
      border-radius: 6px;
      cursor: pointer;
      font-weight: 600;
      transition: background-color 0.3s, transform 0.2s;
    }

    .card-button:hover {
      background-color: #2980b9;
      transform: scale(1.05);
    }

    .card.featured .card-category {
      justify-self: center; /* 注目カードはカテゴリーを中央に */
      background-color: rgba(231,76,60,0.1);
      color: #e74c3c;
    }

    .card.featured .card-title {
      justify-self: center; /* タイトルも中央に */
      text-align: center;
    }

    .card.featured .card-description {
      justify-self: center; /* 説明文も中央に */
      text-align: center;
    }

    .card.featured .card-button {
      justify-self: center; /* ボタンも中央に */
    }

    /* レスポンシブ調整 */
    @media (max-width: 768px) {
      .card-grid {
        grid-template-columns: 1fr;
      }

      .card-footer {
        grid-template-columns: 1fr;
      }

      .card-price {
        justify-self: center; /* モバイルでは中央 */
      }

      .card-button {
        justify-self: stretch; /* モバイルでは幅いっぱい */
      }
    }
  </style>
</head>
<body>
  <div class="card-grid">
    <div class="card">
      <span class="card-category">Basic</span>
      <h3 class="card-title">スタータープラン</h3>
      <p class="card-description">個人利用に最適なベーシックプラン。必要最低限の機能を提供します。</p>
      <div class="card-footer">
        <span class="card-price">¥980/月</span>
        <button class="card-button">選択</button>
      </div>
    </div>

    <div class="card featured">
      <span class="card-category">Popular</span>
      <h3 class="card-title">ビジネスプラン</h3>
      <p class="card-description">最も人気のプラン。ビジネスに必要なすべての機能が含まれています。</p>
      <div class="card-footer">
        <span class="card-price">¥4,980/月</span>
        <button class="card-button">選択</button>
      </div>
    </div>

    <div class="card">
      <span class="card-category">Premium</span>
      <h3 class="card-title">エンタープライズ</h3>
      <p class="card-description">大規模組織向けの最上位プラン。専任サポート付き。</p>
      <div class="card-footer">
        <span class="card-price">お問い合わせ</span>
        <button class="card-button">選択</button>
      </div>
    </div>
  </div>
</body>
</html>

まとめ

justify-selfプロパティは、CSS Gridレイアウトにおいて個別のアイテムをインライン軸方向に配置するための重要なプロパティです。

主な特徴

  1. 個別制御:コンテナのjustify-items設定を特定のアイテムで上書き
  2. 柔軟な配置:start、end、center、stretchなど多様な配置オプション
  3. Grid専用:CSS Gridで完全サポート(Flexboxの主軸では動作しない)

よく使われる値

使用場面
autoデフォルト(親のjustify-itemsに従う)
start左揃え(テキスト、ラベル)
end右揃え(数値、価格、ボタン)
center中央揃え(アイコン、バッジ、強調要素)
stretch幅揃え(カード、パネル)

覚えておくべきポイント

  • アイテムに適用:コンテナではなくアイテム自身に設定
  • justify-itemsより優先:コンテナの設定を上書きできる
  • align-selfと組み合わせplace-selfショートハンドで簡潔に記述
  • stretchの条件:アイテムにwidthが指定されていると効果なし
  • Flexbox注意:Flexboxの主軸では動作しない(margin: autoを使用)

justify-selfプロパティを活用することで、CSS Gridレイアウトにおいて個別アイテムの配置を精密に制御し、柔軟で美しいデザインを実現できます。

参考リンク

円