.krs.style 構文リファレンス
English · 日本語(このファイル)
言語バージョン:
.krs language v1.0(言語 v1.0) —.krsと.krs.styleは 1 つの言語版を共有する(freeze 済み ADR-1314。各パッケージの npm 版とは独立 — ADR-2124)。
セレクタの種類
Section titled “セレクタの種類”| セレクタ | 例 | 対象 |
|---|---|---|
| 種別 | service |
指定した種別の全ノード |
| 複数種別 | service, domain |
いずれかの種別の全ノード |
| タグ | [external] |
指定タグを持つ全ノード |
| アノテーション | @deprecated |
指定アノテーションを持つ全ノード |
| 複合(種別+タグ) | service[external] |
種別とタグの両方に一致 |
| 複合(タグ+アノテーション) | [external]@deprecated |
タグとアノテーションの両方に一致 |
| 複合(種別+タグ+アノテーション) | service[external]@deprecated |
すべてに一致 |
| ファセット | [facets=pii] |
指定 facet に所属する全要素 |
| 複合(種別+ファセット) | service[facets=pii] |
種別と facet 所属の両方に一致 |
| ID | #ECommerce |
特定ノードのみ |
| エッジ | edge |
全エッジ |
| エッジ+タグ | edge[async] |
指定タグのエッジ |
| エッジ 始点 | edge[from=ApiGateway] |
指定ノードを始点とする全エッジ |
| エッジ 終点 | edge[to=ApiGateway] |
指定ノードを終点とする全エッジ |
| エッジ ID | edge#criticalWrite、edge#A->B、edge#A-->B |
特定のエッジのみ |
| バウンダリ | boundary |
全 boundary フレーム(Group by: boundary) |
| バウンダリ ID | boundary#pci |
特定 boundary のフレームのみ |
詳細度ルール(カスケード)
Section titled “詳細度ルール(カスケード)”| セレクタ | 例 | スコア |
|---|---|---|
| 種別 | service |
1 |
| タグ | [external] |
10 |
| アノテーション | @deprecated |
10 |
| 種別 + タグ | service[external] |
11 |
| タグ + アノテーション | [external]@deprecated |
20 |
| 種別 + タグ + アノテーション | service[external]@deprecated |
21 |
| ファセット | [facets=pii] |
10 |
| 種別 + ファセット | service[facets=pii] |
11 |
| ID | #ECommerce |
100 |
| エッジ | edge |
1 |
| エッジ + タグ | edge[async] |
11 |
| エッジ 始点 / 終点 | edge[from=ApiGateway] |
11 |
| エッジ ID | edge#criticalWrite |
101 |
| バウンダリ | boundary |
1 |
| バウンダリ ID | boundary#pci |
101 |
edge#criticalWrite は 101(ID 100 + edge 種別 1)。
同スコアなら後に書いた方が優先(CSS同様)。
ファセットセレクタ([facets=<id>])— experimental
Section titled “ファセットセレクタ([facets=<id>])— experimental”Experimental notation(post-v1.0 watch)。
facetが experimental なので このセレクタも experimental。後方互換はまだ約束しておらず、昇格は実利用の証拠を 条件とする(ADR-1820)。
宣言済み facet に所属する要素をスタイリングする
(syntax.ja.md § 横断的な所属)。
[facets=pii] { border-color: #14B8A6; border-width: 2px;}
/* 種別との複合 — PCI スコープの database だけ。 */database[facets=pci_scope] { background-color: #FEF3C7;}
/* 繰り返すと複数所属を同時に要求する(タグと同じく AND)。 */[facets=pii][facets=gdpr] { border-style: dashed;}- ノード限定。 v1 では
facetsはノードのプロパティなので、edge[facets=...]は全エッジに一致するのではなく何にも一致しない。 - 所属は要素側から読む —
facets <id>が書かれている場所そのもの。セレクタがfacet宣言側を参照することはない。宣言が持つのは関心事のメタデータであって メンバーリストではない。 - 未宣言の facet id はスタイル側のエラーにしない。
facets pclの打ち間違いは それが書かれた場所でfacet-not-declaredが 1 度だけ報告する。同じ綴りを指す セレクタは単に何にも一致しない。2 度報告すると、1 つの間違いを 2 箇所で直せと 言うことになる。 - fact と style の分離は不変。 所属は事実なので
.krs、見た目は選択なのでここ。 プレビューの overlay はさらに別のもので、読み手の一時的な選択であり、どこにも 書き込まれない。
任意名タグ / アノテーションセレクタからの移行
Section titled “任意名タグ / アノテーションセレクタからの移行”.krs.style は以前から任意のタグ名 / アノテーション名に一致してきた。そして今まで、
それが横断的関心事をスタイリングする唯一の手段だった。facet セレクタがその置き換えなので、
任意名セレクタは v1.x で非推奨(style-tag-selector-not-builtin /
style-annotation-selector-not-builtin)とし、構文 v2.0 で一致しなくなる。それまでは
引き続き動く — ルールを黙って落とすと既存モデルの見た目が変わってしまう。
移行前 — 名前が関心事を担っており、その意味はどこにも宣言されていない:
system Shop { database CardVault [pci] {} service Payments [pci] {}}[pci] { border-color: #F59E0B;}移行後 — 関心事を 1 度宣言し、所属を facets へ移し、セレクタでそれを狙う:
facet pci { label "PCI スコープ" description "年次 PCI DSS 評価の対象" link "https://example.com/policies/pci" "PCI ポリシー"}
system Shop { database CardVault { facets pci } service Payments { facets pci }}[facets=pci] { border-color: #F59E0B;}specificity は変わらない — [facets=pci] は [pci] と同じく 10 点。これは意図的で、
移行途中のシートでどのルールが勝つかが変わってしまうと、書き換えを 1 コミットで
やり切らねばならなくなる。
タグには無くて facet にあるものが 3 つある: 関心事自身のメタデータの置き場
(description / link)、宣言集合に対する打ち間違い検出(facets pcl は報告されるが、
[pcl] は黙って別のタグだった)、そして overlay — 読み手が何も編集せずに facet を
強調できる。
Related TPLs: TPL-1503 — このセレクタが、styling の次元で
facetを inert にしないための効果にあたる。TPL-2175 — 非推奨は、移行先が出荷される release で告知する(それより早く告知しない)。TPL-1101 — 新しいセレクタ形式がkarasu fmt/ シート tidy で round-trip すること。
始点 / 終点エッジセレクタ(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-1761 (端点セレクタはビューが格納する 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/adr/1096-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-1296 — 本ドキュメントの
cssフェンスに宣言されたプロパティはアプリ内 reference データに存在しなければならず、PROPERTY_SCHEMASの全エントリは 本ドキュメントに記載されていなければならない(stroke-styleは正式化前は スキーマのみのゴーストだった — ADR-1492 / #1492 参照)。
shape プロパティ
Section titled “shape プロパティ”| キーワード | 形状 | 主な用途 |
|---|---|---|
box |
角丸長方形 | service, domain(デフォルト) |
user |
人型(頭+体) | user |
cylinder |
円柱 | db系 |
queue |
横向き円柱 | queue系 |
hexagon |
六角形 | マイクロサービス |
cloud |
雲形 | 外部クラウド |
カスタム形状(SVGファイル参照):
service[external] { shape: url("shapes/cloud.svg");}kind の色語彙
Section titled “kind の色語彙”この節はビルトインスタイルシートが kind に色を割り当てる規則を説明します。 あなたのスタイルシートを縛るものではありません — ユーザールールはこれらすべてに 優先します。それでも規則として書き残すのは、デフォルトの配色が全体として読める 状態を保つためと、あとから kind を追加するときに毎回勘で決めずに済ませるためです。
規則は 2 つ、それに色相表が付きます。
規則 1 — 論理層は色相ではなく塗りで区別する
Section titled “規則 1 — 論理層は色相ではなく塗りで区別する”domain / usecase / resource / member は同じシステムを同じ視点から語る
語彙なので、4 つの無関係な色相で注意を奪い合うのではなく青系を共有します。区別
するのはカードの塗り方です:
| kind | 表現 | 読み方 |
|---|---|---|
domain |
navy 塗り | この層が所有する構造 |
usecase |
塗りなし — canvas が透け、枠線だけ | 振る舞い。それを収める構造より軽く描く |
resource |
中立な slate 塗り | 物理層が所有するものへの参照 |
member |
navy 塗り + shape: user |
すでに形状で分離済み |
塗りなしの kind には、知っておくべき帰結が 2 つあります。
-
枠線が輪郭そのものになる。 塗りがない以上、カードを描いているのは枠線だけ なので、枠線が WCAG の非テキスト基準 3:1 を負います。判定面は 3 つあります: 素の canvas、boundary フレームの tint を重ねた canvas(メンバーシップは 1:N な ので frame は重なる — 3 枚重ねまで検証)、そして
@deprecatedが fade させた 不透明度でのカード(塗りありなら本体が残るが、塗りなしでは輪郭しか残らない)。 両テーマのusecase枠線が青のランプのほぼ両端に位置し、どちらも純粋に見た目で 選ぶ場合より canvas から遠い明度になっているのは、この 3 つを同時に満たすためです。この fade より薄い不透明度の状態(facet オーバーレイの dim、diff の ghost)は 対象外です。好みの問題ではなく、その α ではどんな色でも 3:1 に届かないためです。 枠線に置ける最良の色は純白ですが、dark canvas に対して dim の α で 2.50:1、 ghost の α で 2.70:1 にしかなりません。WCAG 1.4.11 が inactive component に 設けている除外と同じ扱いになります。
-
境界のメンバーシップが色で読めるようになる。 Group by: boundary のとき、 不透明な塗りに隠されていた frame の tint がカード内部まで届くので、塗りなしの カードは位置だけでなく色でも境界の一員として読めます。
塗りなしにするときは none ではなく transparent を使います。transparent は
描画される(painted)ので、カードはクリック・ホバーの当たり判定を保ちます。
規則 2 — deploy kind は 1 つの色相を 3 通りに使う
Section titled “規則 2 — deploy kind は 1 つの色相を 3 通りに使う”deploy kind はそれぞれ色相を 1 つ持ちます。カードの 3 色はすべてその同じ色相を 明度違いで取ったもので、accent がカードから浮かずにカードのものになります:
border-color/badge-color— accent、彩度そのままbackground-color— 塗り。明度の両端のうち canvas に近い側。カードが canvas に穴を開けるのではなく、canvas の上に載っているように見せるcolor— ラベル。その反対側の端、すなわち塗りから最も遠い明度
明度のどちらが「canvas に近い側」かはテーマで入れ替わります。同じ規則から dark では
oci の塗りがほぼ黒に、light では淡色になるのはこのためです。絶対的な明度ではなく
canvas を基準に規則を書いているので、1 つの文で両テーマを記述できます。
| kind | 色相 |
|---|---|
oci |
blue |
lambda |
purple |
jar |
green |
war |
orange |
function |
yellow |
assets |
cyan |
job |
red |
artifact |
gray |
store |
teal |
この表が固定するのは色相と規則であって hex 値ではありません。具体的な hex は、
2 つの規則と両テーマのコントラストガードを満たす値なら何でも構いません — すなわち
background-color を設定する kind は対の color も設定し、その対が 4.5:1 を満たす
こと。したがって kind を追加するとは、この表に行を足し、その行から 3 色を導出する
ことです。結果はガードが検証します
(packages/core/src/builtins/default-style-contrast.test.ts)。
jobはedge[cyclic]と赤を共有しています。この衝突は本節より前から存在する もので、既存の kind 色を組み替えるより維持を選びました。新しい kind でこれ以上 衝突を増やさないでください。
Related TPLs: TPL-2421 — kind の追加は色相表への行追加であり、fill / text はその行から導出する。hex は コントラストガードが検証する。 TPL-1697 —
background-colorを設定する kind はテーマごとに対の textcolorも設定する。 TPL-2366 — canvas 上に直接文字として描かれる色はテーマごとにコントラストを検証する。
レイアウトヒント(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-1761
適用スコープ
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-1223 — 一度に見せる範囲を限定し、単一ビューが一目で把握できる解像度を保つ(バランス 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/adr/1135-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/adr/9019-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-1184。
@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;}boundary フレームセレクタ(boundary / boundary#<id>)
Section titled “boundary フレームセレクタ(boundary / boundary#<id>)”Group by: boundary では、system view が各 boundary のメンバーを破線のフレームで囲み、
宣言順に循環する識別色を付ける。style シートはこの色を引き取れる。
boundary { border-style: solid; } /* 全フレーム */boundary#pci { border-color: #C0392B; } /* 特定の boundary */id 空間を選ぶのはキーワードの側である。boundary はノードではないので、裸の #pci は
pci という名前のノードを指し、フレームには決して当たらない。#criticalWrite が
edge#criticalWrite の指すエッジではなくノードを指すのと同じ関係。specificity も他と
同じ部品から導かれる: boundary が 1、boundary#pci が 101(id の 100 + 種別の 1)。
シートが名指ししなかった boundary は循環色のままなので、1 つ指定しても他は動かない。
scoped boundary の扱い。 node ブロック内で宣言した boundary は identity が
(宣言スコープ, id)なので、別々のスコープがそれぞれ pci を持ちうる。boundary#pci は
id を名指すがスコープは名指さないので、すべてのスコープ(top-level を含む)の同 id に
一致する。特定スコープの boundary だけを狙う書き方は現時点では無い。必要になったら、
修飾なしの意味を変えずに修飾形を足せる。
サポートするプロパティ:
| プロパティ | 効果 |
|---|---|
border-color |
フレームの色。明示指定が無ければ塗りとタイトルもこの色になる |
background-color |
フレームの薄い塗り。border-color と分けたいときだけ |
color |
フレームのタイトル。border-color と分けたいときだけ |
border-width |
枠線の太さ(px) |
border-style |
solid / dashed / dotted。既定は dashed |
Note:
border-colorの 1 宣言が枠線・塗り・タイトルをまとめて塗り替える。 boundary の色は、重なった 2 つのフレームが「入れ子」ではなく「重なり」に読めるための 条件なので、1 つの宣言でそれが 2 色に割れてはならない。分けたいときはbackground-color/colorを明示する。
Note:
shape/opacity/border-radius/font-*/badge-*はフレームでは 無視される。帯の外へ伸びたフレームは矩形直交の輪郭として描かれるため、設定できる 角丸が存在しない。
team フレーム(Group by: team)はまだこの方法で指定できない。 #2269 を参照。
boundary は experimental notation なので、本セレクタもスタイルを当てる構文と同じく
後方互換を約束しない(syntax.ja.md)。
Related TPLs: TPL-2234 — boundary の色はフレームと
◇タブに届き、両者は別のコードが描く。1 つの resolver を読むことで、style の上書きが片方だけを塗り替える事故を防ぐ。TPL-1503 — 裸のboundaryルールは本セレクタ以前は parse されて無効果だった。今は効果を持つ。TPL-1296 — 上の specificity 行はreference-data.tsからの生成物で、ここに手書きしない。
組織図ノードセレクタ(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 underApache-2.0