結論
プロは「線幅」と「光学サイズ」を別々の規律として扱う。第一に線幅をセット全体で1つの値に固定し(Material 2dp、Octicons/Atlassian 1.5px、Semrush 2px)、サイズが変わっても比例拡縮させず据え置くか opsz 軸で補正する。第二に外接矩形の数学的中央ではなく光学的重心とキーライン基準図形で面積を揃え、座標を整数でピクセルグリッドにスナップする——この2点で「1つだけ浮く」は消える。
01 — 線幅はサイズに比例させず据え置く
最大の浮き要因はこれ。24pxで描いた2px線をそのまま48pxに拡大すると線は4px相当に太り、別物に見える。SVGなら vector-effect:non-scaling-stroke で拡縮時の線太りを止め、サイズ別クラスで線幅を据え置く(または16px→1.5px、24px→2pxのように微調整)のが正解。
primaryOcticons | Primer (GitHub)
primaryMaterial Symbols guide – Google Fonts
02 — セット内で線幅を1つに統一する
アイコンごとに1px / 1.5px / 2pxが混ざると「別々のストックサイトから拾い集めた」ように見え、プロ感が一気に消える。小サイズでは可読性も落ちる。代表値は Material 2dp、Octicons/Atlassian 1.5px、Semrush 2px。値そのものは何でもよく、本質は「1セット1線幅」。
primaryIconography - Atlassian Design
primarySemrush Intergalactic - Icon
03 — 非対称アイコンは光学的中央へ寄せる
Playの三角形を外接矩形の数学的中央に置くと、左に寄って見える。重量が右に偏っているからだ。正解は視覚的重心へ微調整して右へ寄せること。検証は目を細める「squintテスト」で、各アイコンの視覚的ウェイトが均等かを見る。
blogPractical Guide To Icon Design – UX Planet
04 — キーライン基準図形で「面積」を揃える
同じ24pxの箱に詰めても、円・複雑な形・細い形は塗り面積が小さく、小さく見える。「幾何学的に等しい=光学的に不等しい」のが原因。Materialは24dpキャンバスで円⌀20dp / 正方形18×18dp / 縦横の矩形20×16dpという基準図形に主要マスを合わせ、形が違っても大きさ感を一定にする。
primaryIcons - Style - Material Design (M1)
blogOptical weight in icons – Dutchicon
05 — テキスト隣は opsz を下げてベースラインを合わせる
Material Symbolsのデフォルトは opsz=48。本文16-24pxの隣でそのまま使うと太く重く、ピクセルグリッドにも乗らない。完全グリッド整合に設計されているのは20と24版のみ。テキスト隣では opsz を文字サイズに合わせて20か24へ下げ、ベースラインのズレも line-height:1 や微小な translateY で潰す。
primaryIcons – Material Design 3 (Applying icons)
06 — 整数座標でピクセルグリッドにスナップする
X/Y座標が小数だとアンチエイリアスで線がにじみ、隣のシャープなアイコンの中で1つだけぼやけて浮く。座標は整数でon-pixel配置、外側エッジをピクセル境界に揃える。1px線は座標を.5に置いて線の中心をピクセル中央へ合わせる。下のボタンはベースラインずれの「浮き」も同時に示す。
primaryOcticons | Primer (GitHub)
blogIcon Grids & Keylines Demystified – Helena Zhang
実装スニペット
インラインSVGの線幅を全箇所で固定し、サイズが変わっても据え置く。
.icon{
width: 24px;
height: 24px;
fill: none;
stroke: currentColor;
stroke-width: 2; /* 24px基準。全アイコン共通で固定、サイズ比例させない */
stroke-linecap: square; /* 四角いキャップ(Atlassian流) */
stroke-linejoin: round; /* 外角は丸め、内角はパス側で直角に */
vector-effect: non-scaling-stroke; /* 拡大しても線幅を太らせない */
}
.icon--16{ width:16px; height:16px; stroke-width:1.5; }
.icon--32{ width:32px; height:32px; stroke-width:2; }
Material Symbols(可変フォント)をテキスト隣で最適化する。opszは表示font-sizeに連動させる。
.material-symbols-outlined{
font-variation-settings:
'opsz' 24, /* 本文隣はピクセルグリッド整合の24(または20) */
'wght' 400, /* テキストの太さに合わせる */
'GRAD' 0, /* テキストフォントのGRADと揃える */
'FILL' 0;
font-size: 24px;
line-height: 1; /* ベースラインのズレ=浮きを防ぐ */
vertical-align: middle;
}
/* 大きく飾るときだけ opsz を上げる */
.icon-hero{ font-size:48px; font-variation-settings:'opsz' 48,'wght' 400,'GRAD' 0,'FILL' 0; }
ボタン内でアイコンとテキストのベースラインを光学的に合わせる。
.btn{ display:inline-flex; align-items:center; gap:8px; }
.btn .icon{
width:1em; height:1em; /* 文字サイズに連動 */
flex:0 0 auto;
transform: translateY(0.05em); /* 光学的に下げてテキスト重心へ合わせる */
}
小サイズのにじみを防ぐ。直線主体には crispEdges、曲線中心には geometricPrecision を。
.icon--crisp{
shape-rendering: crispEdges; /* 16px等の小サイズで線のにじみを抑える */
}
/* 書き出し時: viewBoxは整数、パス座標も整数/0.5刻みに。
1px線は座標を .5 に置き中心をピクセル中央へ(例 x=8 → 7.5/8.5境界) */
チェックリスト
- セット内の全アイコンが1つの線幅で描かれている(1px/1.5px/2pxの混在なし)
- サイズ違いで線幅を比例拡縮していない(据え置き or opsz/サイズ別クラスで補正)
- SVGに
vector-effect:non-scaling-strokeを入れ、拡大時の線太りを止めた - Play等の非対称アイコンを光学的中央へ寄せ、squintテストで重量が均等
- 円・複雑な形をキーライン基準図形に合わせ、面積(大きさ感)が揃っている
- テキスト隣のMaterial Symbolsは
opsz=20か24、デフォルト48のままにしていない - 座標は整数でピクセルグリッドにスナップ、外側エッジが境界に乗りにじみがない
- ボタン/ラベルでアイコンとテキストのベースラインが揃い、上下に浮いていない
限界 / 出典
数値の多くは Material(2dp)・Octicons(1.5px)・Semrush(2px)など各デザインシステム固有の規定で、絶対基準ではない。本質は「自分のセットで線幅を1つに統一する」ことで、値そのものは可変。opszの「完全ピクセルグリッド整合は20と24版のみ」は Material Symbols 固有で、他フォントには当てはまらない。GRAD軸の範囲は資料により-50〜200/-25〜200と表記揺れがある。CSSの vector-effect:non-scaling-stroke と shape-rendering:crispEdges はブラウザ/レンダラ依存で、特に crispEdges は曲線で角張るため直線アイコン向け(曲線中心は geometricPrecision が安全)。0.5px刻みやサブピクセル調整は高DPR(Retina)前提で、等倍/低DPR環境では消える・にじむリスクがある。ColorParkの「2026」表記は将来日付で、新規性より一般的目安として扱うのが妥当。設計時の数値は実機・実DPRでのスクショ検証を最終確認とすべき。
primaryIcons - Style - Material Design (M1)
primaryMaterial Symbols guide – Google Fonts
primaryIcons – Material Design 3 (Applying icons)
primaryOcticons | Primer (GitHub)
primaryIconography - Atlassian Design
primarySemrush Intergalactic - Icon
blogPractical Guide To Icon Design – UX Planet
blogIcon Grids & Keylines Demystified – Helena Zhang
blogOptical weight in icons – Dutchicon
primaryopticalSize property - Flutter API