イニシャル自動生成アバター
画像がなくても成立するアバター一覧。氏名からイニシャルを抜き出し、名前自体をハッシュ化して背景色を決めるため、同じ名前は常に同じ色になります。
ライブデモ
コード
HTML
<!-- イニシャル自動生成: 氏名からイニシャルを抜き出し、名前のハッシュ値で背景色を決める(画像なしでも成立) -->
<div class="stage">
<ul class="initials-grid" id="initialsGrid" aria-label="メンバーのイニシャルアバター一覧"></ul>
</div>
CSS
* { box-sizing: border-box; }
body {
margin: 0;
min-height: 100vh;
display: grid;
place-items: center;
padding: 28px;
font-family: "Hiragino Sans", "Segoe UI", system-ui, -apple-system, sans-serif;
background:
radial-gradient(circle at 85% 10%, rgba(129, 140, 248, .12) 0%, transparent 42%),
radial-gradient(circle at 8% 92%, rgba(52, 211, 153, .1) 0%, transparent 45%),
#0d0e14;
color: #e2e8f0;
}
.initials-grid {
list-style: none;
display: grid;
grid-template-columns: repeat(3, minmax(0, 1fr));
gap: 22px 16px;
width: 100%;
max-width: 420px;
margin: 0;
padding: 28px 24px;
border-radius: 22px;
background: rgba(255, 255, 255, .045);
border: 1px solid rgba(255, 255, 255, .09);
box-shadow: 0 26px 60px -28px rgba(0, 0, 0, .7);
}
/* JSが生成する各アイテムのスタイル */
.initial-item {
display: grid;
justify-items: center;
gap: 9px;
}
.initial-avatar {
width: 56px;
height: 56px;
border-radius: 50%;
display: grid;
place-items: center;
color: #fff;
font-weight: 700;
font-size: 15.5px;
letter-spacing: .01em;
box-shadow: 0 10px 20px -9px rgba(0, 0, 0, .6);
transition: transform .3s cubic-bezier(.22, 1, .36, 1);
}
.initial-item:hover .initial-avatar {
transform: translateY(-3px) scale(1.06);
}
.initial-name {
margin: 0;
font-size: 11.5px;
text-align: center;
line-height: 1.3;
color: rgba(226, 232, 240, .6);
}
@media (prefers-reduced-motion: reduce) {
.initial-avatar { transition: none; }
.initial-item:hover .initial-avatar { transform: none; }
}
@media (max-width: 420px) {
.initials-grid { grid-template-columns: repeat(2, minmax(0, 1fr)); padding: 22px 16px; }
}
JavaScript
// イニシャル自動生成: 氏名からイニシャルを抜き出し、名前文字列のハッシュ値から背景色(色相)を決めて描画する
(() => {
const grid = document.getElementById('initialsGrid');
if (!grid) return; // null安全
const NAMES = ['田中 太郎', '佐藤 花子', '鈴木 一郎', 'Emma Wilson', '山本 美咲', 'David Chen'];
// 「姓 名」または「First Last」の先頭文字を組み合わせる。1語のみなら先頭2文字を使う
const getInitials = (name) => {
const parts = name.trim().split(/\s+/).filter(Boolean);
if (parts.length === 0) return '?';
if (parts.length === 1) return parts[0].slice(0, 2).toUpperCase();
return (parts[0].charAt(0) + parts[1].charAt(0)).toUpperCase();
};
// 名前の文字列から安定した数値ハッシュを作り、色相(0-359)に変換する。同じ名前は常に同じ色になる
const hashHue = (str) => {
let hash = 0;
for (let i = 0; i < str.length; i++) {
hash = str.charCodeAt(i) + ((hash << 5) - hash);
hash |= 0; // 32bit整数に丸める
}
return Math.abs(hash) % 360;
};
const frag = document.createDocumentFragment();
NAMES.forEach((name) => {
const hue = hashHue(name);
const li = document.createElement('li');
li.className = 'initial-item';
const avatar = document.createElement('span');
avatar.className = 'initial-avatar';
avatar.setAttribute('aria-hidden', 'true');
avatar.style.background = `linear-gradient(155deg, hsl(${hue} 70% 55%), hsl(${(hue + 40) % 360} 62% 38%))`;
avatar.textContent = getInitials(name);
const label = document.createElement('p');
label.className = 'initial-name';
label.textContent = name;
li.appendChild(avatar);
li.appendChild(label);
frag.appendChild(li);
});
grid.appendChild(frag);
})();
🤖 AIエージェント用プロンプト
このままコピーしてAIに貼り付け「追加する場所」だけ書き換えればOK
あなたは熟練のフロントエンドエンジニアです。私のWebサイトに「イニシャル自動生成アバター」の効果を追加してください。
# 追加してほしい効果
イニシャル自動生成アバター(バッジ & アバター)
画像がなくても成立するアバター一覧。氏名からイニシャルを抜き出し、名前自体をハッシュ化して背景色を決めるため、同じ名前は常に同じ色になります。
# 追加する場所
👉【ここに対象箇所を記入:例「トップのヒーローセクション」「お問い合わせボタン」「記事カードの一覧」など】
# 参考実装(この見た目・挙動を再現してください)
【HTML】
<!-- イニシャル自動生成: 氏名からイニシャルを抜き出し、名前のハッシュ値で背景色を決める(画像なしでも成立) -->
<div class="stage">
<ul class="initials-grid" id="initialsGrid" aria-label="メンバーのイニシャルアバター一覧"></ul>
</div>
【CSS】
* { box-sizing: border-box; }
body {
margin: 0;
min-height: 100vh;
display: grid;
place-items: center;
padding: 28px;
font-family: "Hiragino Sans", "Segoe UI", system-ui, -apple-system, sans-serif;
background:
radial-gradient(circle at 85% 10%, rgba(129, 140, 248, .12) 0%, transparent 42%),
radial-gradient(circle at 8% 92%, rgba(52, 211, 153, .1) 0%, transparent 45%),
#0d0e14;
color: #e2e8f0;
}
.initials-grid {
list-style: none;
display: grid;
grid-template-columns: repeat(3, minmax(0, 1fr));
gap: 22px 16px;
width: 100%;
max-width: 420px;
margin: 0;
padding: 28px 24px;
border-radius: 22px;
background: rgba(255, 255, 255, .045);
border: 1px solid rgba(255, 255, 255, .09);
box-shadow: 0 26px 60px -28px rgba(0, 0, 0, .7);
}
/* JSが生成する各アイテムのスタイル */
.initial-item {
display: grid;
justify-items: center;
gap: 9px;
}
.initial-avatar {
width: 56px;
height: 56px;
border-radius: 50%;
display: grid;
place-items: center;
color: #fff;
font-weight: 700;
font-size: 15.5px;
letter-spacing: .01em;
box-shadow: 0 10px 20px -9px rgba(0, 0, 0, .6);
transition: transform .3s cubic-bezier(.22, 1, .36, 1);
}
.initial-item:hover .initial-avatar {
transform: translateY(-3px) scale(1.06);
}
.initial-name {
margin: 0;
font-size: 11.5px;
text-align: center;
line-height: 1.3;
color: rgba(226, 232, 240, .6);
}
@media (prefers-reduced-motion: reduce) {
.initial-avatar { transition: none; }
.initial-item:hover .initial-avatar { transform: none; }
}
@media (max-width: 420px) {
.initials-grid { grid-template-columns: repeat(2, minmax(0, 1fr)); padding: 22px 16px; }
}
【JavaScript】
// イニシャル自動生成: 氏名からイニシャルを抜き出し、名前文字列のハッシュ値から背景色(色相)を決めて描画する
(() => {
const grid = document.getElementById('initialsGrid');
if (!grid) return; // null安全
const NAMES = ['田中 太郎', '佐藤 花子', '鈴木 一郎', 'Emma Wilson', '山本 美咲', 'David Chen'];
// 「姓 名」または「First Last」の先頭文字を組み合わせる。1語のみなら先頭2文字を使う
const getInitials = (name) => {
const parts = name.trim().split(/\s+/).filter(Boolean);
if (parts.length === 0) return '?';
if (parts.length === 1) return parts[0].slice(0, 2).toUpperCase();
return (parts[0].charAt(0) + parts[1].charAt(0)).toUpperCase();
};
// 名前の文字列から安定した数値ハッシュを作り、色相(0-359)に変換する。同じ名前は常に同じ色になる
const hashHue = (str) => {
let hash = 0;
for (let i = 0; i < str.length; i++) {
hash = str.charCodeAt(i) + ((hash << 5) - hash);
hash |= 0; // 32bit整数に丸める
}
return Math.abs(hash) % 360;
};
const frag = document.createDocumentFragment();
NAMES.forEach((name) => {
const hue = hashHue(name);
const li = document.createElement('li');
li.className = 'initial-item';
const avatar = document.createElement('span');
avatar.className = 'initial-avatar';
avatar.setAttribute('aria-hidden', 'true');
avatar.style.background = `linear-gradient(155deg, hsl(${hue} 70% 55%), hsl(${(hue + 40) % 360} 62% 38%))`;
avatar.textContent = getInitials(name);
const label = document.createElement('p');
label.className = 'initial-name';
label.textContent = name;
li.appendChild(avatar);
li.appendChild(label);
frag.appendChild(li);
});
grid.appendChild(frag);
})();
# 外部ライブラリ
なし(追加ライブラリ不要)
# 守ってほしいこと
- 既存のHTML構造・レイアウト・デザインを壊さないこと。必要に応じてクラス名・色・サイズを私のサイトに合わせて調整してよい。
- クラス名やidが既存と衝突しないよう、必要なら接頭辞で名前空間を分けること。
- レスポンシブ対応と prefers-reduced-motion への配慮を入れること。
- 私のサイトのフレームワーク(React / Vue / 素のHTML など)に合わせて実装すること。不明な場合は素のHTML/CSS/JSで提示し、組み込み手順も説明すること。
- 変更後の確認手順も簡潔に教えてください。