【完全ガイド】CSSで丸の中に文字を中央に!正円・楕円・画像対応のコピペOK実装例

css-circle-with-text css
記事内に広告が含まれています。

WebデザインやUI制作で「丸の中にテキストを綺麗に入れてほしい」と頼まれたことはありませんか?

見た目はシンプルなのに、いざ実装しようとすると文字がズレたり、レスポンシブ対応がうまくいかなかったり、意外と手間取ってしまうのがこの「CSSで丸の中に文字を中央配置する」実装です。

特に、1行のテキストだけならまだしも、2行・3行と増えたときや、スマホとPCの両方でレイアウトが崩れないように調整するのは、CSSの知識がないとかなり厄介。しかも、画像やアイコンを一緒に入れたい場合や、楕円・中抜きのような変形パターンまで対応しようとすると、ますます混乱しがちです。

この記事では、そんな「CSSで丸の中に文字を入れる」ためのテクニックを、基本から応用まで段階的にわかりやすくご紹介します。再利用しやすいコード例もたっぷり掲載していますので、実務でもすぐに役立ちますよ。

この記事を読んでわかること

  • 正円・楕円の中に1行または複数行の文字をCSSだけで中央揃えにする方法
  • 丸の中に画像・アイコン・テキストを同時に配置する実装テクニック
  • 楕円、中抜き、アニメーションなど応用的な丸型UIの作り方
  • 再利用可能なCSSコンポーネント化や、Tailwind・SCSSを活用した効率的な管理方法
  • 丸型デザインでよくあるレイアウト崩れの原因とその解決方法

「クライアントに見せられる美しいUIを、スマートにCSSだけで実装したい」という方は、ぜひ最後までご覧ください。

CSSだけで作る正円・楕円の中に文字を中央配置する基本テクニック

Webデザインにおいて、「丸の中に文字を中央配置する」という表現は、アバター、ボタン、バッジなど様々なUIパーツで頻繁に使われます。一見シンプルに見えるこの実装ですが、実際にコードを書いてみると「縦方向のセンタリングが上手くいかない」「複数行のテキストでレイアウトが崩れる」といった問題に直面することがあります。

このセクションでは、CSSだけを使って確実に丸の中に文字を美しく中央配置する方法を、基本から応用まで段階的に解説します。モダンCSSの機能を最大限活用した効率的なテクニックを身につけることで、どんなプロジェクトでも即座に実装できるスキルを習得できます。

正円に1行テキストを中央揃えで入れる最小コード例

まず、最もシンプルで汎用性の高い、1行テキストを正円の中央に配置するCSSコードから始めましょう。以下に3つの確実な方法を紹介します。

方法1: Flexboxを使った王道アプローチ

.circle-text {
  width: 100px;
  height: 100px;
  border-radius: 50%;
  background-color: #3498db;
  color: white;
  display: flex;
  align-items: center;
  justify-content: center;
  font-size: 16px;
  font-weight: bold;
}

<div class="circle-text">CSS</div>

See the Pen css-circle-with-text-01 by watashi-xyz (@watashi-xyz) on CodePen.

なぜこの方法が効果的なのか:

  • border-radius: 50%により、正方形の要素を完全な円に変換
  • display: flexでFlexboxコンテナを作成
  • align-items: centerで垂直方向の中央揃え
  • justify-content: centerで水平方向の中央揃え

メリット: 最も確実で、ブラウザサポートも優秀。コードも直感的で理解しやすい。 デメリット: IE10以前では対応していない(現在では問題なし)。

方法2: CSS Gridを使ったモダンアプローチ

.circle-text-grid {
  width: 100px;
  height: 100px;
  border-radius: 50%;
  background-color: #e74c3c;
  color: white;
  display: grid;
  place-items: center;
  font-size: 16px;
  font-weight: bold;
}

<div class="circle-text-grid">Grid</div>

See the Pen Untitled by watashi-xyz (@watashi-xyz) on CodePen.

なぜこの方法が効果的なのか:

  • display: gridでGridコンテナを作成
  • place-items: centeralign-items: centerjustify-items: centerの短縮記法
  • より簡潔なコードで同等の結果を実現

メリット: コードが最も簡潔。Grid特有の強力な配置機能を活用。 デメリット: IE11以前では対応していない。

方法3: 従来の方法(line-height + text-align)

.circle-text-traditional {
  width: 100px;
  height: 100px;
  border-radius: 50%;
  background-color: #9b59b6;
  color: white;
  line-height: 100px;
  text-align: center;
  font-size: 16px;
  font-weight: bold;
}

<div class="circle-text-traditional">Text</div>

なぜこの方法が効果的なのか:

  • line-heightを要素の高さと同じ値に設定することで垂直中央揃えを実現
  • text-align: centerで水平中央揃え
  • 古いブラウザでも確実に動作

メリット: 非常に古いブラウザでも動作する。軽量なコード。 デメリット: 複数行のテキストでは使用できない。高さとline-heightの値を同期する必要がある。

複数行・改行テキストを綺麗に配置する方法(2行・3行対応)

実際のプロジェクトでは、「長いテキスト」や「改行を含むテキスト」を丸の中に配置したいケースが頻繁にあります。従来のline-height方法では対応できないため、Flexboxまたは Gridを使った堅牢なアプローチが必要です。

2行テキストに対応したFlexboxアプローチ

.circle-multiline {
  width: 120px;
  height: 120px;
  border-radius: 50%;
  background-color: #2ecc71;
  color: white;
  display: flex;
  align-items: center;
  justify-content: center;
  font-size: 14px;
  font-weight: bold;
  text-align: center;
  padding: 10px;
  box-sizing: border-box;
}

<div class="circle-multiline">
  複数行<br>テキスト
</div>

See the Pen Untitled by watashi-xyz (@watashi-xyz) on CodePen.

重要なポイント:

  • padding: 10pxで内側の余白を確保し、テキストが円の端に接触しないようにする
  • box-sizing: border-boxでpaddingを含めたサイズ計算を行う
  • text-align: centerで改行後も中央揃えを維持

動的な文字数に対応する柔軟なアプローチ

.circle-flexible {
  width: 150px;
  height: 150px;
  border-radius: 50%;
  background-color: #f39c12;
  color: white;
  display: flex;
  align-items: center;
  justify-content: center;
  font-size: 13px;
  font-weight: bold;
  text-align: center;
  padding: 15px;
  box-sizing: border-box;
  line-height: 1.3;
}

<div class="circle-flexible">
  長いテキストでも<br>自動的に調整<br>されます
</div>

See the Pen css-circle-with-text-04 by watashi-xyz (@watashi-xyz) on CodePen.

なぜこの方法が効果的なのか:

  • line-height: 1.3で行間を調整し、読みやすさを向上
  • 十分なpaddingにより、テキスト量が増えても美しいレイアウトを維持
  • font-sizeを調整することで、様々な文字数に対応可能

実装時の注意点:

  1. 文字数の制限: 円のサイズに対して適切な文字数を設定する
  2. 改行位置の調整: 意図しない場所での改行を防ぐため、適切な単語区切りを意識
  3. フォントサイズの調整: 文字数に応じてフォントサイズを動的に調整する仕組みを検討

楕円やカスタムシェイプ(Ellipse)に中央配置する方法

正円だけでなく、楕円や独自の形状に文字を配置したい場合も多くあります。特に、ヘッダーナビゲーションやカードデザインで楕円形のUIが求められることがあります。

楕円への文字配置

.ellipse-text {
  width: 200px;
  height: 100px;
  border-radius: 50%;
  background-color: #8e44ad;
  color: white;
  display: flex;
  align-items: center;
  justify-content: center;
  font-size: 16px;
  font-weight: bold;
}

<div class="ellipse-text">楕円テキスト</div>

See the Pen Untitled by watashi-xyz (@watashi-xyz) on CodePen.

カスタムシェイプでの応用

.custom-ellipse {
  width: 180px;
  height: 80px;
  border-radius: 90px / 40px;
  background-color: #34495e;
  color: white;
  display: flex;
  align-items: center;
  justify-content: center;
  font-size: 14px;
  font-weight: bold;
}

<div class="custom-ellipse">カスタム楕円</div>

See the Pen Untitled by watashi-xyz (@watashi-xyz) on CodePen.

なぜこの方法が効果的なのか:

  • border-radius: 90px / 40pxにより、水平方向と垂直方向に異なる半径を指定
  • Flexboxの中央揃えは形状に関係なく機能する
  • 幅と高さの比率を変更することで、様々な楕円形を作成可能

clip-pathを使った高度なシェイプ

.clip-path-shape {
  width: 150px;
  height: 150px;
  background-color: #e67e22;
  color: white;
  display: flex;
  align-items: center;
  justify-content: center;
  font-size: 14px;
  font-weight: bold;
  clip-path: ellipse(40% 50% at 50% 50%);
}

<div class="clip-path-shape">Clip Path</div>

See the Pen Untitled by watashi-xyz (@watashi-xyz) on CodePen.

clip-pathの利点:

  • より複雑で精密な形状を作成可能
  • アニメーションとの組み合わせで動的な表現が可能
  • CSS3の先進的な機能を活用した表現力

実装時の考慮事項:

  1. ブラウザサポート: clip-pathは比較的新しい機能のため、対象ブラウザを確認
  2. パフォーマンス: 複雑な形状はレンダリングに負荷がかかる可能性
  3. アクセシビリティ: 非標準的な形状でも文字の可読性を保つ

この基本テクニックをマスターすることで、様々なデザイン要求に対応できる確実な実装力が身につきます。次のセクションでは、これらの基本を応用してより表現豊かなUIを作成する方法について詳しく解説します。

デザイン性と拡張性を高める丸型UIの応用CSS

基本的な丸型UIの実装をマスターしたら、次はデザイン性と拡張性を高める応用テクニックに挑戦しましょう。このセクションでは、単純な「丸の中に文字」から一歩進んで、画像・アイコン・テキストを組み合わせた複合的なUIコンポーネントや、視覚的インパクトを与えるアニメーション効果、そして様々な形状バリエーションを作成する方法を解説します。

これらのテクニックをマスターすることで、プロフェッショナルなWebサイトやアプリケーションで使用されるような、洗練されたUIコンポーネントを自在に作成できるようになります。

丸の中に画像・SVGアイコン・テキストを一緒に入れる方法

現代のWebデザインでは、丸の中に文字だけでなく、プロフィール画像、アイコン、テキストを組み合わせたリッチなUIコンポーネントが頻繁に使用されます。SNSのプロフィール表示、チームメンバー紹介、スキルバッジなど、様々な場面で活用できる実装方法を見ていきましょう。

プロフィール画像とテキストの組み合わせ

.profile-circle {
  width: 120px;
  height: 120px;
  border-radius: 50%;
  background-color: #3498db;
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  color: white;
  font-weight: bold;
  overflow: hidden;
  position: relative;
}

.profile-circle .avatar {
  width: 60px;
  height: 60px;
  border-radius: 50%;
  object-fit: cover;
  margin-bottom: 8px;
}

.profile-circle .name {
  font-size: 12px;
  text-align: center;
  line-height: 1.2;
}

<div class="profile-circle">
  <img src="//i.pravatar.cc/200?u=test@example.com" alt="プロフィール画像" class="avatar">
  <div class="name">田中太郎</div>
</div>

See the Pen Untitled by watashi-xyz (@watashi-xyz) on CodePen.

なぜこの方法が効果的なのか:

  • flex-direction: columnで縦方向のレイアウトを実現
  • object-fit: coverで画像のアスペクト比を保ちながら円形にトリミング
  • overflow: hiddenで要素がはみ出すことを防止

SVGアイコンとテキストの組み合わせ

.skill-badge {
  width: 100px;
  height: 100px;
  border-radius: 50%;
  background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  color: white;
  font-weight: bold;
  box-shadow: 0 4px 15px rgba(102, 126, 234, 0.4);
}

.skill-badge .icon {
  width: 32px;
  height: 32px;
  margin-bottom: 6px;
}

.skill-badge .label {
  font-size: 11px;
  text-align: center;
}

<div class="skill-badge">
  <svg class="icon" viewBox="0 0 24 24" fill="currentColor">
    <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"/>
  </svg>
  <div class="label">JavaScript</div>
</div>

See the Pen Untitled by watashi-xyz (@watashi-xyz) on CodePen.

実装のポイント:

  • linear-gradientでグラデーション背景を作成し、視覚的魅力を向上
  • box-shadowで奥行きを表現
  • SVGアイコンのfill="currentColor"で親要素の文字色を継承

複数要素の水平配置

.info-circle {
  width: 140px;
  height: 140px;
  border-radius: 50%;
  background-color: #e74c3c;
  display: flex;
  align-items: center;
  justify-content: center;
  color: white;
  font-weight: bold;
  padding: 15px;
  box-sizing: border-box;
}

.info-circle .content {
  display: flex;
  flex-direction: column;
  align-items: center;
  text-align: center;
}

.info-circle .number {
  font-size: 24px;
  line-height: 1;
  margin-bottom: 4px;
}

.info-circle .unit {
  font-size: 10px;
  opacity: 0.9;
}

<div class="info-circle">
  <div class="content">
    <div class="number">85</div>
    <div class="unit">完了率</div>
  </div>
</div>

See the Pen Untitled by watashi-xyz (@watashi-xyz) on CodePen.

CSSだけで楕円や中抜き円を作る!形のバリエーションまとめ

基本的な円形から発展させて、より表現豊かなデザインバリエーションを作成する方法を解説します。これらのテクニックをマスターすることで、デザイナーの要求に柔軟に応えられるようになります。

枠線のみの円(アウトライン円)

.outline-circle {
  width: 100px;
  height: 100px;
  border: 3px solid #3498db;
  border-radius: 50%;
  background-color: transparent;
  display: flex;
  align-items: center;
  justify-content: center;
  color: #3498db;
  font-weight: bold;
  font-size: 14px;
}

<div class="outline-circle">CSS</div>

See the Pen Untitled by watashi-xyz (@watashi-xyz) on CodePen.

中抜き円(ドーナツ形状)

.donut-circle {
  width: 100px;
  height: 100px;
  border-radius: 50%;
  background-color: #e74c3c;
  display: flex;
  align-items: center;
  justify-content: center;
  position: relative;
  color: white;
  font-weight: bold;
}

.donut-circle::before {
  content: '';
  position: absolute;
  width: 60px;
  height: 60px;
  background-color: white;
  border-radius: 50%;
  top: 50%;
  left: 50%;
  transform: translate(-50%, -50%);
}

.donut-circle .text {
  position: relative;
  z-index: 1;
  color: #e74c3c;
  font-size: 12px;
}

<div class="donut-circle">
  <span class="text">DONUT</span>
</div>

See the Pen Untitled by watashi-xyz (@watashi-xyz) on CodePen.

二重線円

.double-border-circle {
  width: 100px;
  height: 100px;
  border: 2px solid #9b59b6;
  border-radius: 50%;
  background-color: white;
  display: flex;
  align-items: center;
  justify-content: center;
  color: #9b59b6;
  font-weight: bold;
  font-size: 14px;
  position: relative;
}

.double-border-circle::before {
  content: '';
  position: absolute;
  width: 80px;
  height: 80px;
  border: 1px solid #9b59b6;
  border-radius: 50%;
  top: 50%;
  left: 50%;
  transform: translate(-50%, -50%);
}

<div class="double-border-circle">DOUBLE</div>

See the Pen Untitled by watashi-xyz (@watashi-xyz) on CodePen.

グラデーション枠線円

.gradient-border-circle {
  width: 100px;
  height: 100px;
  border-radius: 50%;
  background: linear-gradient(45deg, #ff6b6b, #4ecdc4);
  display: flex;
  align-items: center;
  justify-content: center;
  padding: 3px;
}

.gradient-border-circle .inner {
  width: 100%;
  height: 100%;
  border-radius: 50%;
  background-color: white;
  display: flex;
  align-items: center;
  justify-content: center;
  color: #333;
  font-weight: bold;
  font-size: 14px;
}

<div class="gradient-border-circle">
  <div class="inner">GRAD</div>
</div>

See the Pen Untitled by watashi-xyz (@watashi-xyz) on CodePen.

なぜこの方法が効果的なのか:

  • ::before擬似要素を使用して複雑な形状を実現
  • z-indexでレイヤーの重なり順を制御
  • グラデーション枠線は外側の要素でグラデーションを作り、内側の要素で背景色を設定

活用シーン:

  • アウトライン円: ミニマルなデザイン、アクセントとして
  • 中抜き円: プログレスリング、通知バッジ
  • 二重線円: 高級感のあるデザイン、重要な情報の強調
  • グラデーション枠線: モダンなデザイン、SNSのストーリー風表現

CSSアニメーションで円の描画と文字表示を同時演出

ユーザーエクスペリエンスを向上させるために、CSSアニメーションを活用した動的な表現方法を解説します。円が描かれるアニメーションと文字の表示を組み合わせることで、ユーザーの注意を引き、インタラクティブな体験を提供できます。

円の描画アニメーション

.animated-circle {
  width: 120px;
  height: 120px;
  border-radius: 50%;
  background-color: transparent;
  border: 4px solid transparent;
  display: flex;
  align-items: center;
  justify-content: center;
  position: relative;
  animation: drawCircle 2s ease-in-out forwards;
}

@keyframes drawCircle {
  0% {
    border-color: transparent;
    transform: scale(0.8);
  }
  50% {
    border-color: #3498db;
    border-width: 4px;
    transform: scale(1.05);
  }
  100% {
    border-color: #3498db;
    background-color: #3498db;
    transform: scale(1);
  }
}

.animated-circle .text {
  color: white;
  font-weight: bold;
  font-size: 16px;
  opacity: 0;
  animation: fadeInText 1s ease-in-out 1.5s forwards;
}

@keyframes fadeInText {
  0% {
    opacity: 0;
    transform: translateY(10px);
  }
  100% {
    opacity: 1;
    transform: translateY(0);
  }
}

<div class="animated-circle">
  <span class="text">READY</span>
</div>

See the Pen Untitled by watashi-xyz (@watashi-xyz) on CodePen.

回転する円とテキストフェード

.rotating-circle {
  width: 100px;
  height: 100px;
  border-radius: 50%;
  background: conic-gradient(from 0deg, #ff6b6b, #4ecdc4, #45b7d1, #96ceb4, #feca57, #ff6b6b);
  display: flex;
  align-items: center;
  justify-content: center;
  animation: rotate 3s linear infinite;
  position: relative;
}

@keyframes rotate {
  0% {
    transform: rotate(0deg);
  }
  100% {
    transform: rotate(360deg);
  }
}

.rotating-circle .inner {
  width: 80px;
  height: 80px;
  border-radius: 50%;
  background-color: white;
  display: flex;
  align-items: center;
  justify-content: center;
  color: #333;
  font-weight: bold;
  font-size: 14px;
  animation: counterRotate 3s linear infinite;
}

@keyframes counterRotate {
  0% {
    transform: rotate(0deg);
  }
  100% {
    transform: rotate(-360deg);
  }
}

<div class="rotating-circle">
  <div class="inner">SPIN</div>
</div>

See the Pen Untitled by watashi-xyz (@watashi-xyz) on CodePen.

プログレス円アニメーション

.progress-circle {
  width: 120px;
  height: 120px;
  border-radius: 50%;
  background-color: #f8f9fa;
  display: flex;
  align-items: center;
  justify-content: center;
  position: relative;
  overflow: hidden;
}

.progress-circle::before {
  content: '';
  position: absolute;
  width: 100%;
  height: 100%;
  border-radius: 50%;
  background: conic-gradient(from 0deg, #28a745 0deg, #28a745 252deg, transparent 252deg);
  animation: progressFill 2s ease-in-out forwards;
}

@keyframes progressFill {
  0% {
    background: conic-gradient(from 0deg, #28a745 0deg, #28a745 0deg, transparent 0deg);
  }
  100% {
    background: conic-gradient(from 0deg, #28a745 0deg, #28a745 252deg, transparent 252deg);
  }
}

.progress-circle .percentage {
  position: relative;
  z-index: 1;
  color: #333;
  font-weight: bold;
  font-size: 18px;
  opacity: 0;
  animation: showPercentage 1s ease-in-out 1s forwards;
}

@keyframes showPercentage {
  0% {
    opacity: 0;
    transform: scale(0.5);
  }
  100% {
    opacity: 1;
    transform: scale(1);
  }
}

<div class="progress-circle">
  <div class="percentage">70%</div>
</div>

See the Pen Untitled by watashi-xyz (@watashi-xyz) on CodePen.

アニメーションのポイント:

  • animation-delayを使用してアニメーションの開始タイミングを調整
  • animation-fill-mode: forwardsで最終状態を保持
  • conic-gradientで円形のプログレス表現を実現
  • 複数のアニメーションを組み合わせて複雑な演出を作成

実装時の注意点:

  1. パフォーマンス: 過度なアニメーションはブラウザのパフォーマンスに影響
  2. アクセシビリティ: prefers-reduced-motionメディアクエリでアニメーションを無効化する配慮
  3. タイミング: アニメーションの長さと間隔を適切に調整
/* アクセシビリティ対応 */
@media (prefers-reduced-motion: reduce) {
  .animated-circle,
  .rotating-circle,
  .progress-circle {
    animation: none;
  }

  .animated-circle .text,
  .progress-circle .percentage {
    opacity: 1;
    animation: none;
  }
}

これらの応用テクニックを組み合わせることで、単純な「丸の中に文字」から大きく発展した、プロフェッショナルなUIコンポーネントを作成できます。次のセクションでは、これらの技術を実際のプロジェクトで効率的に運用するための実践的なアプローチについて解説します。

実践的なコードと運用で使える丸型パーツの作り方

実際の開発現場では、「丸の中に文字」を使ったUIを効率的に開発し、長期的に運用していくことが重要です。このセクションでは、コードの再利用性とメンテナンス性を重視した実践的なアプローチを解説します。

再利用可能なCSSコンポーネント化とクラス設計

BEM記法を活用したコンポーネント設計

再利用性の高い丸型UIを構築するには、適切なCSS設計が必要です。BEM(Block Element Modifier)記法を参考に、以下のようなコンポーネント設計を行います:

/* ベースコンポーネント */
.circle-badge {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  border-radius: 50%;
  text-align: center;
  line-height: 1;
  font-weight: 600;
  box-sizing: border-box;
}

/* サイズバリエーション */
.circle-badge--small {
  width: 32px;
  height: 32px;
  font-size: 12px;
}

.circle-badge--medium {
  width: 48px;
  height: 48px;
  font-size: 14px;
}

.circle-badge--large {
  width: 64px;
  height: 64px;
  font-size: 16px;
}

/* カラーバリエーション */
.circle-badge--primary {
  background-color: #007bff;
  color: white;
}

.circle-badge--success {
  background-color: #28a745;
  color: white;
}

.circle-badge--warning {
  background-color: #ffc107;
  color: #212529;
}

/* 複数行テキスト対応 */
.circle-badge--multiline {
  padding: 8px;
  line-height: 1.2;
  min-height: 48px;
}

/* アイコン付きバージョン */
.circle-badge__icon {
  width: 16px;
  height: 16px;
  margin-right: 4px;
}

.circle-badge__text {
  flex: 1;
}

HTML使用例:

<!-- 基本的な使用例 -->
<div class="circle-badge circle-badge--medium circle-badge--primary">
  5
</div>

<!-- 複数行テキスト -->
<div class="circle-badge circle-badge--large circle-badge--success circle-badge--multiline">
  完了<br>済み
</div>

<!-- アイコン付き -->
<div class="circle-badge circle-badge--medium circle-badge--warning">
  <svg class="circle-badge__icon">...</svg>
  <span class="circle-badge__text">3</span>
</div>

なぜこの設計が効果的なのか:

  • 拡張性: 新しいサイズやカラーを追加する際、既存のコードを変更する必要がない
  • 保守性: 各バリエーションが独立しているため、修正時の影響範囲が限定される
  • 再利用性: 一度定義すれば、プロジェクト全体で統一された見た目を保てる

画像・SVG・アイコンとテキストの同時配置対応

実際のプロジェクトでは、単純なテキストだけでなく、アイコンや画像を組み合わせた丸型UIが必要になることがあります。コンポーネント設計に柔軟性を持たせることで、様々なコンテンツタイプに対応できます:

/* 画像とテキストの組み合わせ用 */
.circle-badge--profile {
  padding: 4px;
  background-color: #f8f9fa;
  border: 2px solid #dee2e6;
}

.circle-badge__avatar {
  width: 24px;
  height: 24px;
  border-radius: 50%;
  object-fit: cover;
  margin-bottom: 2px;
}

.circle-badge__name {
  font-size: 10px;
  font-weight: 500;
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
  max-width: 100%;
}

/* SVGアイコン用の調整 */
.circle-badge--icon-only {
  padding: 12px;
}

.circle-badge--icon-only svg {
  width: 24px;
  height: 24px;
  fill: currentColor;
}

HTML使用例:

<!-- プロフィール画像付き -->
<div class="circle-badge circle-badge--large circle-badge--profile">
  <img src="avatar.jpg" alt="ユーザー" class="circle-badge__avatar">
  <div class="circle-badge__name">田中太郎</div>
</div>

<!-- アイコンのみ -->
<div class="circle-badge circle-badge--medium circle-badge--primary circle-badge--icon-only">
  <svg 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"/>
  </svg>
</div>

Tailwind CSSやSCSSで効率化する丸型UIの管理方法

Tailwind CSSを活用した実装

Tailwind CSSを使用することで、より簡潔で読みやすいコードを書けます:

<!-- Tailwind CSSでの基本実装 -->
<div class="w-12 h-12 rounded-full bg-blue-500 text-white flex items-center justify-center text-sm font-semibold">
  5
</div>

<!-- レスポンシブ対応 -->
<div class="w-8 h-8 md:w-12 md:h-12 lg:w-16 lg:h-16 rounded-full bg-green-500 text-white flex items-center justify-center text-xs md:text-sm lg:text-base font-semibold">
  完了
</div>

<!-- カスタムコンポーネント用のクラス定義 -->
<div class="circle-badge-sm bg-red-500 text-white">
  !
</div>

tailwind.config.jsでのカスタマイズ:

module.exports = {
  theme: {
    extend: {
      components: {
        '.circle-badge-sm': {
          '@apply w-8 h-8 rounded-full flex items-center justify-center text-xs font-semibold': {},
        },
        '.circle-badge-md': {
          '@apply w-12 h-12 rounded-full flex items-center justify-center text-sm font-semibold': {},
        },
        '.circle-badge-lg': {
          '@apply w-16 h-16 rounded-full flex items-center justify-center text-base font-semibold': {},
        },
      }
    }
  }
}

SCSSを使った効率的な管理

SCSSの変数とMixinを活用することで、保守性の高いコードを書けます:

// 変数定義
$circle-sizes: (
  'small': 32px,
  'medium': 48px,
  'large': 64px,
  'xlarge': 80px
);

$circle-colors: (
  'primary': (#007bff, white),
  'success': (#28a745, white),
  'warning': (#ffc107, #212529),
  'danger': (#dc3545, white)
);

// Mixin定義
@mixin circle-badge-base {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  border-radius: 50%;
  text-align: center;
  line-height: 1;
  font-weight: 600;
  box-sizing: border-box;
  transition: all 0.2s ease;

  &:hover {
    transform: scale(1.05);
  }
}

@mixin circle-badge-size($size) {
  width: $size;
  height: $size;
  font-size: calc(#{$size} / 4);

  @if $size >= 64px {
    padding: 8px;
    line-height: 1.2;
  }
}

@mixin circle-badge-color($bg-color, $text-color) {
  background-color: $bg-color;
  color: $text-color;

  &:hover {
    background-color: darken($bg-color, 5%);
  }
}

// コンポーネント生成
.circle-badge {
  @include circle-badge-base;

  // サイズバリエーション自動生成
  @each $name, $size in $circle-sizes {
    &--#{$name} {
      @include circle-badge-size($size);
    }
  }

  // カラーバリエーション自動生成
  @each $name, $colors in $circle-colors {
    &--#{$name} {
      @include circle-badge-color(nth($colors, 1), nth($colors, 2));
    }
  }

  // レスポンシブ対応
  @media (max-width: 768px) {
    &--responsive {
      @include circle-badge-size(map-get($circle-sizes, 'small'));
    }
  }

  @media (min-width: 769px) {
    &--responsive {
      @include circle-badge-size(map-get($circle-sizes, 'medium'));
    }
  }
}

SCSSの利点:

  • 効率的な管理: 変数やMixinを使うことで、一箇所の変更で全体に反映される
  • 自動生成: ループを使ってバリエーションを自動生成できる
  • 関数機能: darken()などの関数を使って動的なスタイル調整が可能

パフォーマンスを考慮した実装

実際のプロジェクトでは、パフォーマンスも重要な要素です:

/* GPUアクセラレーションを活用 */
.circle-badge {
  will-change: transform;
  backface-visibility: hidden;
  transform: translateZ(0);
}

/* アニメーションの最適化 */
.circle-badge--animated {
  transition: transform 0.2s cubic-bezier(0.4, 0, 0.2, 1);
}

.circle-badge--animated:hover {
  transform: translateZ(0) scale(1.05);
}

/* 大量の丸型UIがある場合のCSS Grid対応 */
.circle-badge-grid {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(48px, 1fr));
  gap: 16px;
  padding: 16px;
}

この実践的なアプローチにより、開発効率と保守性を両立した丸型UIコンポーネントを構築できます。次のセクションでは、実装時によくある質問と解決策を詳しく見ていきましょう。

よくある質問(FAQ)

ブラウザによって表示がずれるのはなぜですか?

ブラウザ間での表示の違いは、主に以下の要因によるものです:

主な原因と対策

1. フォントレンダリングの違い

/* 問題のあるコード */
.circle-badge {
  font-family: Arial, sans-serif; /* ブラウザごとに異なるフォールバック */
  font-size: 16px;
}

/* 改善されたコード */
.circle-badge {
  font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, sans-serif;
  font-size: 16px;
  font-weight: 500; /* 明確に指定 */
  -webkit-font-smoothing: antialiased;
  -moz-osx-font-smoothing: grayscale;
  text-rendering: optimizeLegibility;
}

2. box-sizingの統一

/* 必須の設定 */
.circle-badge {
  box-sizing: border-box; /* paddingとborderを含めたサイズ計算 */
  width: 48px;
  height: 48px;
  padding: 8px;
}

/* グローバルリセットの推奨 */
*, *::before, *::after {
  box-sizing: border-box;
}

3. line-heightの正規化

.circle-badge {
  line-height: 1; /* 相対値で統一 */
  /* または */
  line-height: normal; /* ブラウザデフォルトをリセット */
}

文字サイズが変わると丸からはみ出してしまうのですが、どうすればいいですか?

A: 文字サイズに応じて丸のサイズを動的に調整する方法があります:

解決策1: CSSの相対単位を活用

.circle-badge {
  width: 3em; /* 文字サイズの3倍 */
  height: 3em;
  border-radius: 50%;
  display: flex;
  align-items: center;
  justify-content: center;
  font-size: 16px; /* ベースサイズ */
  line-height: 1;
  padding: 0.5em; /* 文字サイズに比例したpadding */
}

/* 文字サイズが変わっても比例してサイズが変わる */
.circle-badge--large {
  font-size: 24px; /* 丸も自動的に大きくなる */
}

解決策2: CSS Gridを使った自動調整

.circle-badge {
  display: grid;
  place-items: center;
  aspect-ratio: 1 / 1; /* 正方形を保つ */
  border-radius: 50%;
  min-width: 2em;
  min-height: 2em;
  padding: 0.25em;
  font-size: clamp(12px, 2vw, 20px); /* レスポンシブ対応 */
}

解決策3: JavaScriptを使った動的調整

function adjustCircleSize() {
  const badges = document.querySelectorAll('.circle-badge');

  badges.forEach(badge => {
    const fontSize = parseFloat(getComputedStyle(badge).fontSize);
    const textLength = badge.textContent.length;

    // 文字数に応じてサイズを調整
    const multiplier = textLength > 2 ? 3.5 : 3;
    const size = fontSize * multiplier;

    badge.style.width = `${size}px`;
    badge.style.height = `${size}px`;
  });
}

// 使用例
window.addEventListener('resize', adjustCircleSize);
adjustCircleSize(); // 初期化

丸のサイズを固定したい場合はどうすればいいですか?

固定サイズの丸で文字を適切に収めるには、以下のアプローチが効果的です:

解決策1: 文字数制限とtruncation

.circle-badge--fixed {
  width: 48px;
  height: 48px;
  border-radius: 50%;
  display: flex;
  align-items: center;
  justify-content: center;
  font-size: 14px;
  line-height: 1;
  padding: 4px;
  overflow: hidden; /* はみ出しを隠す */
}

.circle-badge--fixed .text {
  max-width: 100%;
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
  text-align: center;
}

解決策2: 文字数に応じたフォントサイズ調整

.circle-badge--adaptive {
  width: 48px;
  height: 48px;
  border-radius: 50%;
  display: flex;
  align-items: center;
  justify-content: center;
  line-height: 1;
  padding: 4px;
}

/* 文字数に応じたサイズ調整 */
.circle-badge--adaptive[data-length="1"] { font-size: 20px; }
.circle-badge--adaptive[data-length="2"] { font-size: 16px; }
.circle-badge--adaptive[data-length="3"] { font-size: 12px; }
.circle-badge--adaptive[data-length="4"] { font-size: 10px; }

解決策3: 複数行対応の固定サイズ

.circle-badge--multiline-fixed {
  width: 60px;
  height: 60px;
  border-radius: 50%;
  display: flex;
  align-items: center;
  justify-content: center;
  text-align: center;
  font-size: 11px;
  line-height: 1.2;
  padding: 8px;
  word-break: keep-all;
  overflow-wrap: break-word;
}

レスポンシブ対応で、特定のブレイクポイントでだけ丸のサイズや文字サイズを変えたい場合は?

メディアクエリを活用した段階的なレスポンシブ対応が効果的です:

解決策1: ブレイクポイント別の詳細設定

.circle-badge--responsive {
  display: flex;
  align-items: center;
  justify-content: center;
  border-radius: 50%;
  transition: all 0.3s ease;
}

/* スマートフォン(〜768px) */
@media (max-width: 768px) {
  .circle-badge--responsive {
    width: 32px;
    height: 32px;
    font-size: 12px;
    line-height: 1;
  }
}

/* タブレット(769px〜1024px) */
@media (min-width: 769px) and (max-width: 1024px) {
  .circle-badge--responsive {
    width: 48px;
    height: 48px;
    font-size: 14px;
    line-height: 1.1;
  }
}

/* デスクトップ(1025px〜) */
@media (min-width: 1025px) {
  .circle-badge--responsive {
    width: 64px;
    height: 64px;
    font-size: 16px;
    line-height: 1.2;
  }
}

解決策2: CSS カスタムプロパティを使った効率的な管理

.circle-badge--smart {
  --badge-size: 32px;
  --badge-font-size: 12px;
  --badge-padding: 4px;

  width: var(--badge-size);
  height: var(--badge-size);
  font-size: var(--badge-font-size);
  padding: var(--badge-padding);
  border-radius: 50%;
  display: flex;
  align-items: center;
  justify-content: center;
}

@media (min-width: 769px) {
  .circle-badge--smart {
    --badge-size: 48px;
    --badge-font-size: 14px;
    --badge-padding: 6px;
  }
}

@media (min-width: 1025px) {
  .circle-badge--smart {
    --badge-size: 64px;
    --badge-font-size: 16px;
    --badge-padding: 8px;
  }
}

解決策3: Container Queriesを使った次世代対応

/* コンテナクエリ対応(モダンブラウザ) */
.badge-container {
  container-type: inline-size;
}

.circle-badge--container {
  width: 32px;
  height: 32px;
  font-size: 12px;
  border-radius: 50%;
  display: flex;
  align-items: center;
  justify-content: center;
}

@container (min-width: 200px) {
  .circle-badge--container {
    width: 48px;
    height: 48px;
    font-size: 14px;
  }
}

@container (min-width: 400px) {
  .circle-badge--container {
    width: 64px;
    height: 64px;
    font-size: 16px;
  }
}

丸の中のテキストが縦方向に中央揃えにならない場合はどうすればいいですか?

縦方向の中央揃えがうまくいかない場合の原因と対策:

解決策1: line-heightの調整

.circle-badge {
  width: 48px;
  height: 48px;
  border-radius: 50%;
  display: flex;
  align-items: center;
  justify-content: center;
  line-height: 1; /* 重要:line-heightを1に設定 */
  font-size: 16px;
}

/* または、高さと同じline-heightを指定 */
.circle-badge--line-height {
  width: 48px;
  height: 48px;
  line-height: 48px; /* 高さと同じ値 */
  text-align: center;
  border-radius: 50%;
}

解決策2: vertical-alignの問題解決

/* インライン要素での問題を解決 */
.circle-badge {
  display: inline-flex; /* inline-blockではなくinline-flex */
  align-items: center;
  justify-content: center;
  vertical-align: middle; /* 周囲のテキストとの配置調整 */
  width: 48px;
  height: 48px;
  border-radius: 50%;
}


丸の形が楕円になってしまうことがあるのですが、どうすれば正円を保てますか?

正円を確実に保つための対策:

解決策1: aspect-ratioの活用

.circle-badge {
  aspect-ratio: 1 / 1; /* 正方形を強制 */
  width: 48px; /* 幅のみ指定 */
  border-radius: 50%;
  display: flex;
  align-items: center;
  justify-content: center;
}

解決策2: 確実な正方形の作成

.circle-badge {
  width: 48px;
  height: 48px;
  min-width: 48px; /* 最小幅を保証 */
  min-height: 48px; /* 最小高さを保証 */
  max-width: 48px; /* 最大幅を制限 */
  max-height: 48px; /* 最大高さを制限 */
  border-radius: 50%;
  display: flex;
  align-items: center;
  justify-content: center;
  flex-shrink: 0; /* フレックスコンテナ内で縮小を防ぐ */
}

まとめ

この記事では、「CSSだけで丸の中に文字を中央に配置する方法」をテーマに、基本から応用まで幅広く解説してきました。Web制作の現場では意外とつまずきやすいこの実装ですが、CSSの基礎を正しく理解し、柔軟なレイアウト技術を身につければ、誰でも美しく安定したUIを実現できます。

特に、1行だけでなく複数行のテキスト配置や、レスポンシブ対応画像やアイコンとの組み合わせなど、実案件で「使えるかどうか」が重要なポイントだったかと思います。また、Tailwind CSSやSCSSを活用した効率的な運用方法再利用可能なコンポーネント設計も、今後の開発やメンテナンスで役立つはずです。

以下に、本記事の内容で特に重要なポイントを改めてまとめておきます。

重要ポイント

  • display: flexalign-items: centerjustify-content: center簡単かつ確実に中央揃え
  • 丸の中に複数行テキストを入れる場合は、text-align: centerと余白調整がカギ
  • border-radiusだけでなく、clip-pathaspect-ratioを使うことで自由度の高い形状も実現可能
  • 画像やアイコンとの組み合わせは、object-fitinline-flexでバランスを取る
  • Tailwind CSSやSCSSでコンポーネント化すれば、再利用性が高まり保守もラクに
  • アニメーションやデザインバリエーションでUIに動きや個性を加えるのも◎

「CSSで文字を丸の中に中央配置するだけ」と思われがちな処理ですが、実はかなり応用範囲が広く、対応できるようになるとアイコン、バッジ、ステップUI、プロフィール表示など、さまざまなデザインに応用できます。

ぜひこの記事のコードや解説を活用しながら、あなた自身のWeb制作に取り入れてみてください。そして、必要に応じてさらにカスタマイズし、より快適で魅力的なユーザー体験を提供できるデザイナー・コーダーを目指していきましょう。

CSSだけで波線背景を実現!画像不要で作れるコピペ実装&アニメーション付きデザイン集
CSSだけで実装できる波線背景の作り方をわかりやすく解説。コピペOKの実例や、Sass・Tailwind対応の再利用しやすい構造、さらにSVGやHaikei、clip-pathなどを使ったアニメーション付き応用テクニック、WordPressテンプレートへの組み込み方、レスポンシブ対応のポイントまで網羅します。
【2025年】レスポンシブブレイクポイントの決め方・書き方完全ガイド!CSSの最適解と実装テクニック
スマホ・タブレット・PCに対応するブレイクポイントの決め方や、CSS・SCSSでの効率的な書き方を解説。mobile-first/desktop-firstの設計方針や、チームで共有しやすいルール作り、SEOにも強いレスポンシブ対応の考え方まで網羅。ブレイクポイント設計に悩む方に向けた実用ガイドです。
CSSアニメーションで「ぽよん」感を出す方法【コピペOK】サンプルコード・パフォーマンス最適化まで
CSSだけで「ぽよん」と弾むアニメーションを作りたい方へ。コピペですぐ使えるコードのサンプルや、ボタン・画像・アイコンなどUI別の実装テクニック、cubic-bezierやtransformの具体的な数値例まで紹介します。ホバーやクリック時、ポップアップ、複数要素の連続バウンスなど多彩なバリエーションも解説。
タイトルとURLをコピーしました