Clicky Cascading Style Sheets

Control the appearance of a Clicky diagram with style sheets written in a CSS-like language.

A CCSS file consists of a series of rule sets, which are blocks of declarations that apply to one or more selectors. For example, this rule set contains one declaration, for the background property. It says that all elements should have a red background:

* {
    background: rgb(100%,0,0);

Tell Clicky to use a CCSS file with its -s option:

clicky -s CCSSFILE ...


CCSS selectors determine which elements are affected by a rule block. The following basic selectors are available:

* Matches any element
CLASSNAME Matches elements with class CLASSNAME
CLASSNAME can contain glob match characters, like * or ?.
port Matches ports
handler Matches handlers

Additional modifiers can follow these selectors. For elements, the modifiers are:

#NAME Matches elements named NAME
NAME can contain glob match characters, like * or ?.
.anonymous Matches anonymous elements
.primitive Matches non-compound elements (defined directly by the driver)
.compound Matches compound elements (defined by elementclass or { ... })
.passthrough Matches compound elements defined by { input -> output }
.live Matches elements that are hooked up to a live driver
[in=N] Matches elements with N inputs
[in>=N] and similar comparisons also work.
[out=N] Matches elements with N outputs
[name*=X] Matches elements whose names contain X as a substring
[downstream=S] Matches elements downstream of at least one element or port matching S
S can be an element class name or an element name, possibly containing glob match characters. Use #S to match an element name only. You can also contain port numbers, as in [0]. The reachability calculations uses Click's flow codes.
[downstream!=S] Matches elements not downstream of any element or port matching S
[upstream=S] Matches elements upstream of at least one element or port matching S
[upstream!=S] Matches elements not upstream of any element or port matching S
[reachable=S] Matches elements reachable from at least one element or port matching S
Reachable is the union of upstream and downstream.
[reachable!=S] Matches elements not reachable from any element or port matching S
[HANDLER=VALUE] Matches elements hooked up to a live driver that have a handler named HANDLER, whose value is VALUE
[HANDLER!=VALUE] Matches elements hooked up to a live driver that have a handler named HANDLER, whose value is not VALUE
:hover Matches elements under the pointer
:active Matches elements that have been clicked
:pressed Matches elements that are being pressed

For ports, the modifiers are:

#NUM Matches ports numbered NUM
.input Matches input ports
.output Matches output ports
.push Matches push ports
.pull Matches pull ports
.agnostic Matches agnostic ports
.error Matches erroneous ports (too many for the element class or push/pull error)

For handlers, the modifiers are:

#HANDLER Matches handlers named HANDLER
HANDLER can contain glob match characters, like * or ?.
.read Matches read handlers
.write Matches write handlers
.param Matches read handlers that take parameters
.calm Matches "calm" handlers (marked by the driver as rarely changing)
.expensive Matches "expensive" handlers (marked by the driver as expensive to compute)
.deprecated Matches "deprecated" handlers (marked by the driver as deprecated)

A complete selector consists of one or more basic selectors separated by spaces. An element selector followed by a port selector matches the ports on elements that match the element selector. Multiple element selectors match compound element container relationships. For instance:

Foo Idle Matches Idle elements in compound elements named Foo.
* * * * Matches elements that are 4 deep in a compound element stack.
Idle port.push Matches push ports on Idle elements.

A rule set is preceded by one or more complete selectors separated by commas, and applies to any of those selectors.

When searching for a declaration, Clicky combines all applicable rulesets, ordering them so that the best matches take precedence.


The following declarations determine how elements are displayed.

orientation Element orientation: either vertical (the default) or horizontal, or either combined with reverse.
padding Padding around inside of element box. padding-left, padding-right, padding-top, padding-bottom are supported.
margin Margin outside the element box. The -left, -right, etc. versions are supported.
min-width Minimum element box width, including padding.
min-height Minimum element box height, including padding.
min-length Minimum element box dimension, including padding, in the direction of flow.
For horizontal orientation this is the same as min-width, for vertical orientation the same as min-height.
height-step Increment for element heights.
color Foreground color. Example: color: red, color: rgba(255,0,0,0.4).
text Text to print in the element. Can contain % escapes, explained below.
font Font to use for printing element text.
background-color Background color.
border-style Border style, none, solid, inset, dashed, or dotted.
border-color Border color.
border-width Border width.
border Combination of border style, color, and width.
shadow-style Shadow style, none, drop, outline, or unscaled-outline.
shadow-width Shadow width.
shadow-color Shadow color.
style Element drawing style; either normal or queue.
queue-stripe-style Border style for queue stripes.
queue-stripe-width Line width for queue stripes.
queue-stripe-color Color for queue stripes.
queue-stripe-spacing Spacing between queue stripes.
display Element display style: none (do not display), normal (display compound elements as including their contents), closed (display compound elements as primitives), expanded (display compound elements' contents but not the compound element itself), or passthrough (do not display, but display connections to or from the element as passing through it).
port-split How to split elements by ports. It can occasionally make a diagram look better if an element is split into two separate boxes, one for inputs and one for outputs. Values: none (default), inputs (only display inputs), outputs (only display outputs), both (display two boxes, one for inputs and one for outputs).
flow-split How to split elements by flow. Takes a flow code, such as ab/ab. Will split the element into multiple boxes, one each for each type of flow. Defaults to no split.

The % escapes for text declarations are:

%n Name of element
%c Element class name
%f Flat name of element (compound ancestor names turned into slashes)
%C Configuration string
%#C Configuration string surrounded by parentheses -- but if configuration is empty, then nothing
%:NC Nth configuration argument
%:*C Configuration argument corresponding to the port (port-text only)
%{handlername} Value of handler (live configurations only)
%.30C At most the first 30 characters of the configuration string (can be applied to any escape)

The text parser also accepts HTML-style font changes, such as <small> and <b>.

These declarations determine how ports are displayed:

port-shape Shape of ports, triangle or rectangle.
port-length Port length. This is the dimension parallel to the side on which the port is displayed.
port-width Port width. This is the dimension perpendicular to the side on which the port is displayed.
port-font Font for port explanation text.
port-text Text to display near the port.
port-color Port fill color.
port-border-style Style of port border.
port-border-width Port border width.
port-border-color Port border color.
port-margin Margin around ports.
port-edge-padding Extra padding to add to first and last ports.
port-display Whether to display inputs, outputs, both, or neither (none).

These declarations determine how handlers are used:

autorefresh Whether to autorefresh handler values: off (default), on (autorefresh), or a time count in seconds (autorefresh with that period).
autorefresh-period Autorefresh period.
display How to display handlers: displayed (default), none, collapse (show the handler name but inside an expander).
allow-refresh Whether to allow refresh: yes (default) or no.


Clicky CSS also support CSS-style media and import at-rules. A media at-rule says that the enclosed declarations apply only to the specified media types. For example, this says that drop shadows should only occur on the screen (not in PDF output):

@media screen {
* {
    shadow: drop rgba(50%, 50%, 45%, 50%) 3px;

Clicky understands two media types, print (PDF output) and screen (the UI).

An import at-rule includes rules from another CCSS file:

@import "filename.ccss";


Here is a simple Click configuration:

rr :: RoundRobinSched;

TimedSource(0.2) -> c1::Counter
	-> r :: { input -> Queue(20) -> output }
	-> Print(q1) -> [0]rr;
TimedSource(0.5) -> c2::Counter -> Queue(20) -> Print(q2) -> [1]rr;

rr -> TimedSink(0.1);

Here's how Clicky displays it with the default styles.


The following examples demonstrate how the display attribute affects elements.

expanded and closed are meaningful on compound elements only, and determine how compounds' contents are displayed. closed hides the contents, where expanded hides the compound, shifting the contents one level up to mingle with other elements.

#r { display: closed; }

#r { display: expanded; }

display: none causes the Print elements and all connections to and from those elements to vanish, leaving the diagram disconnected. display: passthrough hides the Print elements, but preserves their connections.

Print { display: none; }

Print { display: passthrough; }


Splitting elements is occasionally useful when backwards connection (such as through ICMPError), or high connectivity (common to IPRewriters), complicates a diagram. Display the problematic element multiple times with different port subsets and the diagram may simplify itself, for instance into subsets.

#rr { port-split: both; }

#rr { flow-split: ab/a; }


Use port classes to highlight or annotate particular ports.

#c1 port.output#0 {
	port-text: "interesting";
#rr port#1 {
	port-text: "boring";
#c2 port.input#0 {
	port-color: red;
	port-width: 10;
	port-length: 18;


* { orientation: horizontal }


Turn elements upstream of [0]rr blue:

[upstream=[0]rr] {
    background: rgb(200,200,255);

Turn elements in between a TimedSource and a Print green:

[downstream=TimedSource][upstream=Print] {
     background: rgb(200,255,200);

Default CCSS Rules

Here are the default rules Clicky applies to diagrams as of 3/7/2009. Your CCSS files augment these rules.

port.input {
    port-shape: triangle;
    port-length: 11px;
    port-width: 7px;
    port-margin: 1px;
    port-edge-padding: 2px;
port.output {
    port-shape: rectangle;
    port-length: 9px;
    port-width: 5.5px;
    port-margin: 1px;
    port-edge-padding: 2px;
port.push, port.push.agnostic {
    port-color: black;
port.pull, port.pull.agnostic {
    port-color: white;
port.agnostic {
    port-color: gray;
port.push, port.pull {
    port-border: black 1px solid;
port.agnostic, port.push.agnostic, port.pull.agnostic {
    port-border: black 1px inset;
port.push.error, port.push.agnostic.error {
    port-color: red;
port.pull.error, port.pull.agnostic.error {
    port-color: rgb(100%, 75%, 75%);
port.push.error, port.pull.error {
    port-border: red 1px solid;
port.agnostic.error, port.push.agnostic.error, port.pull.agnostic.error {
    port-border: red 1px inset;
* {
    background: rgb(100%, 100%, 87%);
    color: black;
    border: 1px solid black;
    padding: 8px 12px;
    margin: 20px 14px;
    shadow: drop rgba(50%, 50%, 45%, 50%) 3px;
    orientation: vertical;
    scale: 100%;
    queue-stripe: 1px solid rgb(87%, 87%, 50%);
    queue-stripe-spacing: 12px;
    text: "%n\n<small>%c</small>";
    display: open;
    port-display: both;
    port-font: 6;
    @media print {
	font: Times;
	port-font: Times 6;
*.anonymous {
    text: "%n";
* * {
    background: rgb(98%, 98%, 81%);
* * * {
    background: rgb(96%, 96%, 75%);
* * * * {
    background: rgb(94%, 94%, 69%);
@media screen {
*:hover {
    background: #fffff2;
*:active, *:active:hover {
    background: #ffff94;
    shadow: unscaled-outline rgba(90%, 20%, 95%, 50%) 3px;
*:pressed, *:active:pressed {
    shadow: drop rgba(50%, 50%, 45%, 50%) 3px;
*Queue {
    min-length: 49.6px;
    style: queue;
fullness {
    style: fullness;
    length: length;
    capacity: capacity;
    color: rgba(0%, 0%, 100%, 20%);
    autorefresh: length 0.1s;
activity {
    style: activity;
    handler: count;
    decay: 5s;
    max-value: 3;
    type: rate;
    autorefresh: 1s;
clicky-css.txt · Last modified: 2011/05/24 08:17 by kohler
Recent changes RSS feed Driven by DokuWiki