CSS Syntax
Nest accepts CSS selector strings wherever a selector is expected. Strings are parsed by parseCssSel into selector attrsets, then matched by the same engine as programmatic selectors.
Basic tokens
Section titled “Basic tokens”Star *
Section titled “Star *”Matches any node:
is = "*"ID #name
Section titled “ID #name”Matches a node by its name attribute (the attrset key in the DOM):
is = "#lb-prod" # node named lb-prodis = "#web-1" # node named web-1Name (bare word)
Section titled “Name (bare word)”Matches by name, same as #id but without the #:
is = "web" # node named webClass .traitName
Section titled “Class .traitName”Matches nodes whose entity trait exposes an output class with this name:
is = ".nixos" # entity has nixos output classis = ".homeManager" # entity has homeManager output classAttribute [key=value]
Section titled “Attribute [key=value]”Matches nodes where toString node.key == value:
is = "[env=prod]"is = "[system=x86_64-linux]"Attribute existence [key]
Section titled “Attribute existence [key]”Matches nodes that have the attribute, regardless of value:
is = "[sshKeys]"is = "[httpPort]"Compound selectors
Section titled “Compound selectors”Multiple tokens without a combinator — all must match (AND):
is = "#lb-prod.nixos" # named lb-prod AND has nixos classis = "[env=prod][system=x86_64-linux]" # two attribute conditionsOr (comma)
Section titled “Or (comma)”Comma-separated alternatives — any must match:
is = "#web-1, #web-2"is = "[env=prod], [env=staging]"Child combinator >
Section titled “Child combinator >”Matches a node that is a direct child of another:
is = "prod > web" # node named web whose parent is named prodis = "cluster > *" # any direct child of clusterDescendant combinator (+)
Section titled “Descendant combinator (+)”Matches a node descended from another (not necessarily direct child).
is = "cluster +web" # web descended from clusterPseudo-classes
Section titled “Pseudo-classes”:not(sel)
Section titled “:not(sel)”Matches nodes NOT matching sel:
is = ":not(#alice)"is = ":not([env=staging])":has(sel)
Section titled “:has(sel)”Matches nodes that have a direct child matching sel:
is = ":has(.admin)"is = ":has([sshKeys])":within(sel)
Section titled “:within(sel)”Matches nodes that have an ancestor matching sel:
is = ":within(#prod)"is = ":within(.nixos)"Complete examples
Section titled “Complete examples”# All hostsis = ".nixos"
# Hosts named web-1is = "#web-1.nixos"
# Prod hosts by attributeis = "[env=prod].nixos"
# Either prod or stagingis = "[env=prod], [env=staging]"
# Hosts with admin childrenis = ".nixos:has(.admin)"
# Web nodes under prodis = "prod > .nixos[addr]"Parsing
Section titled “Parsing”String selectors are parsed by parseCssSel which tokenizes via parseCompound:
#name→{ __sel = "id"; name = "…" }.class→{ __sel = "class"; name = "…" }[k=v]→{ __sel = "attr"; key = "k"; val = "v" }[k]→{ __sel = "attrExists"; key = "k" }:pseudo(inner)→{ __sel = "pseudo"; selector = parsed-inner },→{ __sel = "or"; selectors = [ … ] }>→{ __sel = "child"; parentSel = …; childSel = … }+→{ __sel = "descendant"; ancestorSel = …; descendantSel = … }
Compound (multiple tokens) → list, matched as AND.