.krs.style 構文リファレンス
English · 日本語(このファイル)
セレクタの種類
Section titled “セレクタの種類”| セレクタ | 例 | 対象 |
|---|---|---|
| 種別 | service | 指定した種別の全ノード |
| 複数種別 | service, domain | いずれかの種別の全ノード |
| タグ | [external] | 指定タグを持つ全ノード |
| アノテーション | @deprecated | 指定アノテーションを持つ全ノード |
| 複合(種別+タグ) | service[external] | 種別とタグの両方に一致 |
| 複合(タグ+アノテーション) | [external]@deprecated | タグとアノテーションの両方に一致 |
| 複合(種別+タグ+アノテーション) | service[external]@deprecated | すべてに一致 |
| ID | #ECommerce | 特定ノードのみ |
| エッジ | edge | 全エッジ |
| エッジ+タグ | edge[async] | 指定タグのエッジ |
| エッジ 始点 | edge[from=ApiGateway] | 指定ノードを始点とする全エッジ |
| エッジ 終点 | edge[to=ApiGateway] | 指定ノードを終点とする全エッジ |
| エッジ ID | edge#criticalWrite、edge#A->B、edge#A-->B | 特定のエッジのみ |
詳細度ルール(カスケード)
Section titled “詳細度ルール(カスケード)”| セレクタ | 例 | スコア |
|---|---|---|
| 種別 | service | 1 |
| タグ | [external] | 10 |
| アノテーション | @deprecated | 10 |
| 種別 + タグ | service[external] | 11 |
| タグ + アノテーション | [external]@deprecated | 20 |
| 種別 + タグ + アノテーション | service[external]@deprecated | 21 |
| ID | #ECommerce | 100 |
| エッジ | edge | 1 |
| エッジ + タグ | edge[async] | 11 |
| エッジ 始点 / 終点 | edge[from=ApiGateway] | 11 |
| エッジ ID | edge#criticalWrite | 101 |
edge#criticalWrite は 101(ID 100 + edge 種別 1)。
同スコアなら後に書いた方が優先(CSS同様)。
始点 / 終点エッジセレクタ(edge[from=<id>] / edge[to=<id>])
Section titled “始点 / 終点エッジセレクタ(edge[from=<id>] / edge[to=<id>])”あるノードを始点(または終点)とする全エッジを 1 ルールでまとめてスタイル
できる。密な図で残った交差や束を見分ける「color-by-source」の最有力手段で、
これが無いとハブの fan-out を edge#Hub->Target ルールの列挙でしか書けない。
edge[from=<id>]— 始点がノード<id>の全エッジedge[to=<id>]— 終点がノード<id>の全エッジ
edge[from=ApiGateway] { color: #3B82F6; } /* ApiGateway の fan-out をまとめて 1 色に */edge[from=Scheduler] { color: #10B981; }edge[to=AuthService] { color: #F59E0B; } /* AuthService を呼ぶ全エッジ */<id> はノード id。usecase→resource 合成エッジ向けに dot-notation の端点
(例: edge[to=OrderDB.OrderTable])も使える。base 形式
edge#PlaceOrder->OrderDB.OrderTable と同じ規則で、id はアクティブビュー上の
エッジの from / to 端点と比較される。
どちらも詳細度は 11(edge 種別 1 + 端点述語 10)で edge[<tag>] と同格。
タグと併用でき、1 本のエッジが from= と to= の両ルールに同時に一致しうる:
edge[from=ApiGateway][async] { stroke-style: dashed; } /* ApiGateway 発の async エッジ */from / to 以外の属性(例: edge[source=X])は unknown-edge-selector-attribute
エラーになる。
Related TPLs: TPL-20260624-04 (端点セレクタはビューが格納する id 形と同じ形で比較すること)。
エッジ ID セレクタ(edge#<id>)
Section titled “エッジ ID セレクタ(edge#<id>)”特定のエッジ 1 本だけにスタイルを適用する。<id> はエッジの canonical id で、
パース後に以下の規則で確定する:
.krsでエッジ宣言(またはusecaseのresource行)に#<id>が 書かれていれば、その author id がそのまま canonical id になる- それ以外は base 形式
<from><arrow><to>。->は sync、-->は async
/* `.krs` 側で A -> B "primary" #criticalWrite と書かれた場合 */edge#criticalWrite { color: #EF4444; }
/* author id が無い場合の base 形式 */edge#A->B { color: #00FF00; }
/* async の base 形式 */edge#A-->B { stroke-width: 2px; }
/* dot-notation を含む base id(usecase→resource 合成エッジなど) */edge#PlaceOrder->OrderDB.OrderTable { direction: down; }同じ base id を持つエッジが 2 本以上あって両方に author id が無い場合、
パーサが ambiguous-edge-base warning を出し、edge#<base> セレクタは
どちらにも一致しない。区別したい場合は .krs 側でいずれかに #<id> を
付ける。詳細は docs/spec/syntax.md と
docs/design/edge-id-selector.md を参照。
タグセレクタを優先すべきケース
Section titled “タグセレクタを優先すべきケース”「read / write の見た目を変えたい」のような 論理分類による上書き は
edge#<id> ではなく edge[write] / edge[read] を使うこと。タグセレクタは
論理分類に追従するので、usecase の operations を変更しただけで対象エッジが
正しく追従する。edge#<id> は「この特定のエッジ」を直接指したい場合に
限定して使う。
プロパティ一覧
Section titled “プロパティ一覧”/* ノード用プロパティ */background-color: #1D4ED8;color: #DBEAFE; /* テキスト色 */border-color: #1E40AF;border-width: 2px;border-style: solid; /* solid | dashed | dotted */border-radius: 8px;font-size: 13px;font-weight: bold; /* normal | bold */font-family: "Noto Sans JP", sans-serif;opacity: 0.6;
/* エッジ用プロパティ */color: #94A3B8;stroke-width: 1.5px;font-size: 11px;stroke-style: solid; /* solid | dashed | dotted(正準名、後述) */border-style: solid; /* solid | dashed | dotted(stroke-style のエイリアス) */direction: auto; /* up | down | left | right | auto(ヒント、後述) */label-position: middle; /* start | middle | end | <0.0..1.0> */label-offset: 0 0; /* <dy>px or <dx>px <dy>px(screen-axis) */
/* karasu固有プロパティ(CSS非対応のため例外) */shape: box; /* box | user | cylinder | queue | hexagon | cloud | url("...") */
/* アノテーション用プロパティ(バッジ表示) */badge-color: #EF4444;badge-icon: "⚠";badge-label: "非推奨";stroke-style プロパティ(エッジ)
Section titled “stroke-style プロパティ(エッジ)”stroke-style はエッジの線スタイル(solid | dashed | dotted)の
正準名である。エッジが既に使っている SVG 系の stroke-* 語彙
(stroke-width)と揃えている。border-style は後方互換のための
エイリアスとしてエッジでも引き続き使える — 既存のスタイルシートは
そのまま動作する。
edge[async] { stroke-style: dashed; } /* 推奨 */edge[legacy] { border-style: dashed; } /* エイリアス、同じ効果 */カスケード後に同一エッジへ両方が宣言されている場合は、宣言順に
かかわらず stroke-style が勝つ:
edge { border-style: dotted; stroke-style: dashed; } /* → dashed */ノードの線スタイルは border-style のみ — stroke-style はノード
シェイプには効果を持たない。
Related TPLs: TPL-20260511-02 — 本ドキュメントの
cssフェンスに宣言されたプロパティはアプリ内 reference データに存在しなければならず、PROPERTY_SCHEMASの全エントリは 本ドキュメントに記載されていなければならない(stroke-styleは正式化前は スキーマのみのゴーストだった — ADR-20260610-01 / #1492 参照)。
shape プロパティ
Section titled “shape プロパティ”| キーワード | 形状 | 主な用途 |
|---|---|---|
box | 角丸長方形 | service, domain(デフォルト) |
user | 人型(頭+体) | user |
cylinder | 円柱 | db系 |
queue | 横向き円柱 | queue系 |
hexagon | 六角形 | マイクロサービス |
cloud | 雲形 | 外部クラウド |
カスタム形状(SVGファイル参照):
service[external] { shape: url("shapes/cloud.svg");}レイアウトヒント(escape hatch)
Section titled “レイアウトヒント(escape hatch)”最後の手段として使う。 karasu の auto-layout(kind と到達性で決まる 行配置、直交エッジルーティング、ポート分散)はほとんどの図を入力なしで 描けます。レイアウトヒントは、それでも作者の意図を表現できない場合(例: 管理用 actor を右側に固定したい、外部サービスを片側に寄せたい)にだけ 使うこと。まずヒューリスティクスでの吸収を検討し、ヒントは最後に。
column — left | center | right
Section titled “column — left | center | right”同じ layer 内のノードを 3 つのバケット(left / center-もしくは未指定 / right)
に振り分けます。center と未指定は同じ中央バケットに入るため、両端だけを
明示的に指定して残りは未指定で済ませられます:
service[external] { column: right; }queue, database, storage { column: center; }/* internal service は未指定 → 中央バケットに入る */各バケット内は既存の並び(system view では宣言順、それ以外では barycenter) を保持します。layer(行)自体を動かす効果はありません。行を変えたく なった場合はヒントを増やす前に auto-layout のヒューリスティクス改善 Issue を立ててください。
外部サービス(system view): column で配置サイドを選ぶ
Section titled “外部サービス(system view): column で配置サイドを選ぶ”system view では [external] サービスを既定で左右のサイド列に配置します
(最下段の行ではありません)。これにより service → external のエッジが水平に
走り、下向きの infra ファンアウトの間を縫わずに済みます。サイドは consume する
サービスの位置から自動で決まります(各 external は、それを呼ぶサービスの側へ
グルーピングされます)。external サービスに column: left / column: right を
指定すると、その自動割り当てを上書きして指定した側に固定します:
#LegacyBilling { column: left; } /* この外部 SaaS を左側に固定する */external サービスの column: center / 未指定は、サイドを自動割り当てに委ねます。
(infra kind — database / queue / storage — は [external] タグの有無に
関わらず最下段の行に残ります。Tags を参照。)
Related TPLs: TPL-20260624-04
適用スコープ
Section titled “適用スコープ”| View | 挙動 |
|---|---|
system | 上記の通り適用。 |
deploy | 無視。解決時に style-column-ignored-non-system-view 警告が出る。 |
org | 同上。 |
left / center / right 以外の値は style-column-invalid-value
警告とともに破棄されます。
grid-columns — 正の整数
Section titled “grid-columns — 正の整数”コンテナの直接の子を畳むグリッドの列数を指定します。既定でもレイアウトは多数の
兄弟をバランス grid に畳み、横長の一行に潰れてズームアウトを強いる状態を避けます
(一目で把握できる解像度を保つ。コンセプトの scoped glance / 解像度の軸を参照)。
既定の列数は ≈ 正方形に自動バランスします: 少数(5 個まで)は 1 行のまま、より多い
場合は ceil(sqrt(n)) 列(最大 5 列)で横ではなく縦に伸ばします。
grid-columns はこの既定を特定のコンテナで上書きします。子を再配置したいノード
(services なら system、domains なら service、usecases なら domain、member grid
なら team)に指定します:
#PlatformSystem { grid-columns: 3; } /* services を 3 列で折り返す */#BillingDomain { grid-columns: 2; } /* usecases を 2 列で折り返す */1 行が最大レイヤー幅を超える場合は早めに折り返すため、過大な grid-columns でも
フレームを溢れさせません。column(system ビュー限定)と異なり、本ヒントは system /
drill-down ビューおよび org の member grid で有効です。deploy ビューもグリッドを自動
バランスしますが、コンテナを realizes 先でグループ化する都合上コンテナノードが無く、
v1 では grid-columns による上書きはできません。
正の整数でない値(0 や 2.5 など)は style-grid-columns-invalid-value 警告とともに
破棄され、レイアウトは自動バランスにフォールバックします。
Related TPLs: TPL-20260510-21 — 一度に見せる範囲を限定し、単一ビューが一目で把握できる解像度を保つ(バランス grid は視覚密度を一定に保つ)。
direction — auto | up | down | left | right
Section titled “direction — auto | up | down | left | right”エッジに対するレイアウトヒント。エッジを視覚的にどの方向に流したいかを
示唆する。デフォルトは auto(エンジンに任せる)。
edge[write] { direction: down; }edge[read] { direction: right; }edge#criticalWrite { direction: down; }値はリゾルバを経由して ResolvedEdgeStyle.direction に届き、GUI 編集
フロー(#1076 / #1098)と karasu の layered layout の両方で使われる。
反映される値
Section titled “反映される値”auto(デフォルト): バイアスなし。エンジンに完全に任せるup: source を target の 下 に配置し、矢印が視覚的に上向きに 流れるようにする。トポロジカルなレイヤ割り当てでエッジを反転する か、forced kind-based system view では source を target の 1 段下に ずらすことで実現する。矢印自体のfrom -> to方向は変わらないdown: source を target の 上 に配置し、矢印が視覚的に下方向に 流れるようにする。バックエッジや forced kind-based 段組などで他の 制約が逆方向にレイアウトしようとしても、明示的にdownで 上書きできる。upの鏡像で、forced layout では source を target の 1 段上に押し上げる(target 自身と他の同種ノードは動かない)。 target が既に layer 0 にある場合(押し上げる余地がない)は no-op で 自然な orientation に戻る。drill-down view(forced layer なし)では 自然な topological order が既にdownを満たすので、autoと 観察上同じleft/right: 矢印を 左 / 右 に流す(up/downと 同じく「矢印の流れる向き」を値で指定する)。source endpoint は 矢印の流れと逆側に配置される —direction: rightは source を target の 左 に、direction: leftは source を target の 右 に置く(結果として矢印は反対側に流れる)。自然な layered layout で source / target が異なる row に分かれる場合(service 同士の edge など 典型的なケース)、エンジンは まず source を target の layer に 引き寄せ、その後 within-layer の並び替えを行う。up/downの 「source 局所変位」モデルと同じ。bucketByColumnの後段で実行される ため、source endpoint については nodecolumnヒントを上書きする (target のcolumnは尊重)。同じ source への矛盾するヒントは last-wins で、cascade 規約と一貫する。詳細はdocs/design/edge-direction-horizontal.md
サイクル / forced-layer フォールバック
Section titled “サイクル / forced-layer フォールバック”up は absolute 指定ではなくヒント。以下のケースでエンジンは反転を
無効化する:
- サイクルガード:
upを適用すると layer DAG にサイクルが発生する 場合、該当エッジの反転を無効化し、自然な orientation で描画する - Forced kind-based layouts: トップレベルの system view は
user → client → service → ...のような種別による段組を強制する。 ここでもdirection: upは honor され、source ノードを target の 1 段下にずらす 形で実現する(target 自身と他の同種ノードは 動かない)。明示された該当エッジに限ってのみ kind stratification が 乱れる
詳細は docs/design/edge-direction-style.md。
不正値は黙って破棄され、direction は auto にフォールバックする。
label-position — start | middle | end | <0.0..1.0>
Section titled “label-position — start | middle | end | <0.0..1.0>”エッジに沿って label アンカーがどこに置かれるかを指定する。デフォルトは
middle(= 0.5)。
edge[delivers] { label-position: start; } /* source 端寄り */edge[implicit] { label-position: end; } /* target 端寄り */edge#criticalWrite { label-position: 0.25; }値がデフォルト(0.5)かつ label-offset が 0 のときは「最長セグメント
の中点」ヒューリスティクスを保持し、既存図の出力は byte-stable のまま。
著者がいずれかを設定した時点で、polyline 全長を辿って position × totalLength の点をアンカーにする経路に切り替わる。
不正値(未知のキーワード、数値でない文字列)は middle にフォールバック。
[0, 1] 範囲外の小数値はクランプ。
label-offset — <dy>px または <dx>px <dy>px
Section titled “label-offset — <dy>px または <dx>px <dy>px”label アンカーを画面の x/y 軸方向にずらす値(pixel)。CSS shorthand の構文を踏襲:
- 1 値 (
label-offset: 8px) →dx = 0,dy = 8。最頻出の 「label を下方向にずらす」ケース - 2 値 (
label-offset: 4px 8px) →dx = 4,dy = 8
edge { label-offset: 0 8px; } /* 全 label を anchor から 8px 下に */edge#wide { label-offset: 4px 8px; }screen axis(edge perpendicular ではなく)なので、グローバルルールでも edge の傾きに関係なく統一された方向にシフトする。正の値は右 (x) / 下 (y)、負の値は左 / 上。
renderer が anchor の上 -6px に label を置く既存のオフセットとは独立。
typographic な lift はそのまま、その上にこの offset が加算される。
以前の draft(撤回): 初版は
label-offsetを edge 方向に対する 1 軸 perpendicular ずらしと定義していた。これだとedge { label-offset: 8px; }の効果が edge の傾きごとに違う方向に出て 予測が立てにくかった。screen-axis CSS shorthand に切り替えた。詳細は ADR-20260509-05。
@import のスコープと衝突
Section titled “@import のスコープと衝突”- グローバルスコープ(ファイル全体に適用)
- 同じセレクタが複数ファイルで定義された場合は後勝ち
- 衝突時は警告を出力(エラーにはしない)
⚠ Warning: セレクタ "service" が複数ファイルで定義されています - default.krs.style:3 - my-theme.krs.style:2 my-theme.krs.style の定義が適用されます(後勝ち)スタイル解決の擬似コード
Section titled “スタイル解決の擬似コード”function resolveStyle(node, rules) { return rules .filter(rule => matches(node, rule.selector)) .sort((a, b) => specificity(a.selector) - specificity(b.selector)) .reduce((acc, rule) => ({ ...acc, ...rule.style }), {})}
function specificity(selector) { let score = 0 if (selector.id) score += 100 score += selector.tags.length * 10 score += selector.annotations.length * 10 if (selector.type) score += 1 return score}完全サンプル(default.krs.style)
Section titled “完全サンプル(default.krs.style)”/* ── 種別セレクタ ── */user { background-color: #1D4ED8; color: #DBEAFE; border-color: #1E40AF; border-width: 2px; border-radius: 8px; font-size: 13px; font-weight: bold; shape: user;}
service { background-color: #0369A1; color: #E0F2FE; border-color: #075985; border-width: 2px; border-radius: 8px; font-size: 13px; font-weight: bold; shape: box;}
domain { background-color: #15803D; color: #D1FAE5; border-color: #166534; shape: box;}
usecase { background-color: #1F2937; color: #F9FAFB; border-color: #374151; font-size: 11px; shape: box;}
impl { background-color: #78350F; color: #FEF3C7; border-color: #92400E; shape: box;}
/* ── タグセレクタ ── */[external] { background-color: #1F2937; color: #D1D5DB; border-color: #374151; border-style: dashed;}
/* ── アノテーションセレクタ ── */@deprecated { badge-color: #EF4444; badge-icon: "⚠"; badge-label: "非推奨"; opacity: 0.6;}
@new { badge-color: #10B981; badge-icon: "✦"; badge-label: "NEW";}
@experimental { badge-color: #F59E0B; badge-icon: "⚗"; badge-label: "実験的";}
@migration_target { badge-color: #3B82F6; badge-icon: "→"; badge-label: "移行先";}
/* ── 複合セレクタ ── */user[external] { color: #9CA3AF;}
[external]@deprecated { border-color: #EF4444;}
/* ── IDセレクタ ── */#ECommerce { background-color: #7C3AED;}
/* ── エッジ ── */edge { color: #94A3B8; stroke-width: 1.5px; font-size: 11px;}
edge[async] { border-style: dashed; color: #6B7280;}
/* ── 組織図(Org Tree View)── */team { background-color: #1E3A5F; color: #E2E8F0; border-color: #3B82F6;}
member { background-color: #0F172A; border-color: #334155;}
/* 特定チームのみ強調 */#BackendTeam { border-color: #F59E0B; border-width: 2px;}組織図ノードセレクタ(Org Tree View)
Section titled “組織図ノードセレクタ(Org Tree View)”Org Tree View は team / member の種別セレクタと ID セレクタ(#NodeId)をサポートします。
| セレクタ | 対象 |
|---|---|
team | すべてのチームカード |
member | すべてのメンバーカード |
#TeamId | 特定のチームカード |
#MemberId | 特定のメンバーカード |
edge | チーム間のベジェコネクタ |
対応プロパティ:
| プロパティ | 効果 |
|---|---|
background-color | カード背景色 |
color | テキスト色 |
border-color | 枠線色 |
border-width | 枠線幅(px) |
border-radius | 角丸(px) |
font-size | フォントサイズ(px) |
font-weight | フォントウェイト(normal / bold) |
font-family | フォントファミリー |
注意:
opacity/shape/badge-*は Org Tree View では無視されます。 タグ・アノテーション複合セレクタ(team[external]等)は現時点では未サポートです。
© 2026 Hiroki Kondo · Licensed under Apache-2.0