Configuring Ignition Perspective Alarm Indicator Styles

Karen Mitchell10 min read
HMI / SCADAOther ManufacturerTechnical Reference
Licensed PE Working through this on a live machine? A Maine-licensed engineer can take it from here — included with IMD hardware, by the hour for everything else. Book an engineer

The operator sees one of four symptoms: no alarm mark, the wrong priority mark, a mark without a border, or a correctly shaped mark in the wrong position. Treat the display as the last link in a chain: controller state, driver value, tag value, class binding, generated class name, CSS selector, then pseudo-element rendering. The tag can be right while the binding is wrong, and the binding can be right while the selector never matches.

What is the screen telling you?

Start with the visible symptom. Each outcome narrows the next reading to take.

Screen symptom Reading to take Meaning Next check
No border and no icon Live alarm value and component style.classes The alarm is inactive, the binding returned no class, or the class has no matching CSS rule. Trace controller, driver, and tag values.
Correct alarm value but no visual Rendered class and matched CSS rules The data path works; the presentation path is broken. Compare the class path with the escaped selector.
Border appears but symbol or text does not ::before and ::after computed styles The base selector matches, but pseudo-element content, color, geometry, or clipping is wrong. Inspect the priority variables and pseudo-elements.
Correct symbol with the wrong color or label Resolved custom properties A local variable override or priority mapping disagrees with the alarm model. Audit the root palette and component-level overrides.
Symbol is cut off at an edge Ancestor overflow and element position The negative icon offsets extend beyond a clipping container. Inspect the selected variant and its containing block.

Do not begin by changing colors or offsets. First establish whether the display is receiving the intended alarm state and class. Visual edits cannot repair a stale tag, a failed driver update, or a binding that returns the wrong class.

Is the controller and tag path actually in alarm?

Read the controller source, the corresponding gateway tag, and the value used by the component binding at the same operating state. Record the alarm priority as well as the active or inactive state. A priority class cannot be selected correctly if the upstream value supplies only an unrelated status or stale quality.

  1. Place the process in a known condition using the approved operating or test method.
  2. Read the alarm source in the controller. If it is inactive, stop at the control logic; CSS is not the fault.
  3. Read the corresponding tag. If the controller is active but the tag differs, check driver communication, tag quality, addressing, and update behavior before touching the view.
  4. Read the value presented to the component binding. If the tag is correct but the binding input differs, trace intermediate expressions, transforms, indirect paths, and parameters.
  5. Confirm that the priority presented to the binding maps to the intended class number.

This separates a process-data problem from a rendering problem. When controller, tag, and binding input agree, continue at style.classes.

Does the component receive the intended style class?

The alarm border and icon are attached by a class, not by placing separate visual components over the equipment graphic. Read the component's live style.classes value while switching through known alarm states.

Alarm result Expected class path Visual role
Priority 1 Alarms/Display/border-1 Border plus square priority mark
Priority 2 Alarms/Display/border-2 Border plus upright triangle
Priority 3 Alarms/Display/border-3 Border plus inverted triangle
Priority 4 Alarms/Display/border-4 Border plus diamond

The class binding must return the complete intended path. If it returns border-2 while the stylesheet targets the generated class for Alarms/Display/border-2, the selector will not match. If it returns a Priority 3 path for a Priority 2 alarm, the CSS will accurately display the wrong mapping. The tag is right; the binding is wrong.

When the inactive state should have no indicator, have that branch omit the alarm class. Test inactive and every configured priority independently rather than inferring the other branches from one successful state.

Does the class path match the escaped CSS selector?

A Perspective Style path containing slashes becomes a generated class name beginning with psc-. The slash characters must be escaped in the CSS selector. For example:

.psc-Alarms\/Display\/border-1 {
  position: relative;
  box-shadow: 0px 0px 0px 2px var(--alarm-border-color, red);
}

The binding uses Alarms/Display/border-1; the stylesheet targets .psc-Alarms\/Display\/border-1. These are two representations of the same style path, not two class names to place on the component.

Check Location Passing result
Style path Component style.classes The exact priority and variant path is present.
Generated class Rendered component A corresponding psc- class is attached.
Selector match Browser computed styles The expected position and box-shadow declarations are applied.
Pseudo-elements ::before and ::after The shape and label rules appear and their content is not empty.

If the rendered class is present but the rule does not appear in computed styles, correct the selector spelling, escaped slashes, or stylesheet loading. If the rule appears crossed out, a later rule or a more specific selector is winning the cascade.

Is the Perspective Style available in the Designer?

CSS selectors can render without a convenient Designer entry, but skeleton Perspective Styles make the class paths selectable from the style.classes dropdown. Create a skeleton for each path used by the stylesheet and group the names under Alarms/Display.

Perspective Style Matching CSS selector Effect
Alarms/Display/border-1 .psc-Alarms\/Display\/border-1 Priority 1 full border and corner mark
Alarms/Display/top-left-border-2 .psc-Alarms\/Display\/top-left-border-2 Priority 2 top-left shadow and mark
Alarms/Display/icon-3 .psc-Alarms\/Display\/icon-3 Priority 3 external icon without a border
Alarms/Display/inner-icon-4 .psc-Alarms\/Display\/inner-icon-4 Priority 4 icon positioned inside the component

The skeleton supplies the named Designer object; the stylesheet supplies the detailed border, geometry, and pseudo-element declarations. This arrangement reduces manual class-entry errors and keeps the four visual variants grouped. A skeleton with the wrong path still creates a selectable item, but its generated class will not match the intended selector.

Which border or icon variant fits the component?

Choose the variant by where the mark must sit and whether the equipment graphic needs a border.

Variant Border behavior Icon placement Use when
border-N A 2 px outer shadow surrounds the component. The icon uses negative top and left offsets. The complete object must carry the alarm state.
top-left-border-N A 1 px shadow is applied toward the top and left. The icon uses negative offsets. Only a top-left edge cue is wanted.
icon-N No border rule The icon uses negative offsets. The symbol alone is sufficient.
inner-icon-N No border rule The icon uses nonnegative or near-zero offsets. An external mark would be clipped or overlap adjacent content.

Both icon-N and inner-icon-N can work. Prefer inner-icon-N inside containers that clip overflow because it keeps the geometry within the component. Prefer icon-N when the icon must straddle the component corner and the parent permits visible overflow.

The four shapes use fixed geometry. Priority 1 is a 20 px square. Priorities 2 and 3 use 15 px transparent side borders and a 25 px colored bottom border to form a triangle; Priority 3 rotates that triangle 180 degrees. Priority 4 is a 20 px square rotated 45 degrees to form a diamond.

Do the priority color, shape, and label agree?

Two content configurations work. The original rules use a CSS counter with a numeric fallback:

counter-reset: alarm-content var(--alarm-priority-number, 1);
content: counter(alarm-content);

A variable-based configuration stores display text directly:

:root {
  --alarm-priority-colour-p1: #E22028;
  --alarm-priority-content-p1: "C";
  --alarm-priority-colour-p2: #EC8629;
  --alarm-priority-content-p2: "H";
  --alarm-priority-colour-p3: #F5E11B;
  --alarm-priority-content-p3: "M";
  --alarm-priority-colour-p4: #916AAD;
  --alarm-priority-content-p4: "L";
  --alarm-priority-colour-p5: black;
  --alarm-priority-content-p5: "D";
}

Then the label rule becomes content: var(--alarm-priority-content-p1);. Use the counter configuration when the mark must display numeric priority and component-level numeric overrides are useful. Use direct content variables when the mark must display letters such as C, H, M, L, and D. Direct content is the clearer configuration for nonnumeric labels because it removes the counter conversion.

The variable values reveal a semantic choice, not merely a color refactor. The original mapping uses red Priority 1, yellow Priority 2, orange Priority 3, and magenta Priority 4 with labels 1 through 4. The alternative mapping uses separate Priority 1 through Priority 5 variables and letter labels. Select one alarm philosophy, then keep the binding, class number, shape, color, and label aligned. Defining Priority 5 root variables alone does not draw Priority 5; corresponding selectors and geometry are also required.

Set label contrast by icon lightness. The supplied alternative uses white text on the red and magenta fills and black text on the lighter orange and yellow fills. Verify contrast on the deployed display rather than judging only in the Designer.

Are the pseudo-elements rendered in the right place?

Each alarm mark consumes both pseudo-elements: ::before draws the shape and ::after draws its text. The component receives position: relative, making it the positioning reference for the absolutely positioned mark.

Several selector groups intentionally repeat border-N::before, border-N::after, top-left-border-N::before, and top-left-border-N::after. The later group has equal specificity and therefore wins for properties it repeats. For Priority 1, for example, an earlier group places the square at top: 0px and left: 0px, while the later group places it at top: -10px and left: -10px. The resulting border variant uses the later negative offsets. The standalone inner-icon-1 selector remains at zero because it is absent from the later group.

Priority External icon offset Inner geometry
1 top: -10px; left: -10px 20 px square at 0px, 0px
2 Shape at -15px, -15px; text at -10px, -10px Shape at -1px, -1px; text at 3px, 4px
3 Shape at -10px, -15px; text at -10px, -10px Shape at 0px, -1px; text at 0px, 4px
4 top: -11px; left: -11px top: 4px; left: 4px

If a mark is displaced, inspect the winning computed top and left values before editing the stylesheet. If it is missing only near container edges, inspect ancestor overflow. If another stylesheet changes position, restore a positioned containing block on the alarm-bearing component.

Can one component display three indicators at once?

A single element provides only one ::before and one ::after, and this alarm design already uses both for one shape-and-label pair. Reassigning the same pseudo-elements to availability, mode, and alarm rules causes the cascade to replace or combine declarations on the same two generated boxes.

Use nested elements or wrappers when three independent indicators require separate position, shape, color, and text. Assign one indicator class to each child so every child has its own ::before and ::after. A comma-separated box-shadow list can draw multiple simple edge marks, but it cannot independently provide three labels and three different pseudo-element shapes. For equipment availability and mode represented only by plain color bars or dots, layered shadows or backgrounds can work; for labeled priority symbols, separate children are easier to test and bind.

Keep the process alarm visually independent from equipment availability and operating mode. Read each underlying state separately and verify that changing one does not remove or recolor the other two.

How do you apply and verify the resolving configuration?

  1. Confirm the controller alarm state, gateway tag value, binding input, and priority agree.
  2. Create skeleton Perspective Styles for every used path under Alarms/Display.
  3. Match each path to its escaped .psc-Alarms\/Display\/... selector.
  4. Choose one variant: border-N, top-left-border-N, icon-N, or inner-icon-N.
  5. Choose either numeric counters or quoted content variables. Use content variables for letter labels.
  6. Align every class number with its shape, color, contrast color, and alarm meaning. Add selectors before using the defined Priority 5 variables.
  7. Bind the active state to the intended class and omit the alarm class in the inactive branch.
  8. Open the running view and inspect the rendered class, matched base rule, ::before, ::after, and resolved variables.
  9. Exercise inactive state and each configured priority. Confirm the controller, tag, binding, class, border, symbol, label, and color change together.
  10. Test at component edges and normal screen dimensions. Confirm external icons are not clipped and that any simultaneous alarm, availability, and mode indicators remain visible.

FAQ

Can I select these alarm classes from the Perspective Designer?

Yes. Create skeleton Perspective Styles such as Alarms/Display/border-1; the stylesheet then matches the generated .psc-Alarms\/Display\/border-1 class.

Can I replace the alarm priority number with a letter?

Yes. Define a quoted variable such as --alarm-priority-content-p1: "C" and use content: var(--alarm-priority-content-p1) instead of the CSS counter.

Does defining a Priority 5 color automatically create its indicator?

No. The Priority 5 color and content variables provide values only; a Priority 5 class, shape selector, label selector, and binding branch are also required.

Can I show alarm, availability, and mode on one equipment object?

Yes, but use nested elements or wrappers for three independently positioned and labeled indicators. One element has only one ::before and one ::after, both already consumed by the alarm shape and label.

Does a visible alarm icon prove the binding is correct?

No. Drive the source through inactive state and every configured priority, then verify the controller value, tag value, bound class, border, shape, label, and color change together on the running screen.

Back to blog