SharePoint column formatting

SharePoint traffic light (RAG status) column formatting

Show a red, amber, or green signal next to each item — from a score, a percentage, or a RAG choice — so problems stand out before anyone reads a number.

RAG reporting only works if the colors are instant. A SharePoint or Microsoft Lists column that shows 23, 55, and 82 makes people do the thresholds in their head; the same column as a red, amber, and green lamp doesn't. With a small piece of column formatting JSON, a number column gets a lamp and an icon that change at two thresholds you choose, and the cell stays editable with a click.

There are two common starting points, and this page covers both: a Number column (a health score, a percentage, a risk rating) where the color comes from thresholds, and a Choice column whose values are literally Red, Amber, Green.

Before and after

ProjectHealth
Q1 launch plan82
Onboarding flow55
API migration23
Brand refresh91
70 and above = green · 40–69 = amber · below 40 = red
Build this traffic light → Opens the generator on the Traffic Light template. Enter your field name, set the two thresholds, copy the JSON, done.

What the SharePoint traffic light JSON looks like

The generator produces JSON like the example below. Rather than hard-coding colors, it applies one of Microsoft's own sp-field-severity classes — the same styling SharePoint uses for its native conditional formatting — and pairs it with a Fluent icon so the state is readable without color:

{
  "$schema": "https://developer.microsoft.com/json-schemas/sp/v2/column-formatting.schema.json",
  "elmType": "div",
  "inlineEditField": "[$Health]",
  "attributes": {
    "class": "=if(toString([$Health]) == '', '', if([$Health] >= 70, 'sp-field-severity--good', if([$Health] >= 40, 'sp-field-severity--warning', 'sp-field-severity--blocked')))"
  },
  "style": { "cursor": "pointer", "color": "=if(toString([$Health]) == '', '#605e5c', '')" },
  "children": [
    {
      "elmType": "span",
      "attributes": {
        "iconName": "=if(toString([$Health]) == '', 'CircleRing', if([$Health] >= 70, 'CompletedSolid', if([$Health] >= 40, 'WarningSolid', 'StatusErrorFull')))"
      },
      "style": { "font-size": "18px", "margin-right": "8px" }
    },
    {
      "elmType": "span",
      "txtContent": "=if(toString([$Health]) == '', '—', [$Health])",
      "style": { "font-weight": "600" }
    }
  ]
}

Three things are doing the work. The class expression picks good, warning, or blocked from the two thresholds; the iconName expression picks a matching Fluent icon (a tick, a warning triangle, an error badge); and inlineEditField makes the whole cell click-to-edit, so someone can correct a score without opening the item. The number itself is still shown — a lamp with no value is a guess, not a report. And because SharePoint treats an empty number as 0, the toString([$Health]) == '' test catches blank cells first and gives them a grey ring and a dash instead of a red lamp.

Because the severity classes are Microsoft's, the result is a light tint with colored text and icon, not a solid block. That is deliberate — it matches the rest of a modern list. If you want a saturated, physical-looking signal, the Traffic Light (housing) template draws all three lamps in a dark housing and lights the matching one.

How to apply it

  1. Open the generator and pick the Traffic Light template (or use the button above).
  2. Enter your column's internal field name — see the note below.
  3. Set the Good threshold (green at or above) and the Warning threshold (amber at or above). Anything lower is red.
  4. Click Copy.
  5. In SharePoint: Column settings → Format this column → Advanced mode.
  6. Delete what's in the box, paste, click Preview, then Save.

For a Choice column that already holds Red, Amber, Green (or On track, At risk, Off track), skip the thresholds and use the Click-to-Edit Pill template instead: map each value to a color and you get a solid pill. The status column guide walks through that one.

Most common reason it doesn't work: the field name must match your column's internal name, which can differ from the display name (a column shown as "Project Health" might be ProjectHealth or Project_x0020_Health internally). See the internal field name guide to find yours.

Common questions

Does this work with a Choice column instead of a number?
Yes, but use a different template. The Traffic Light template compares a number against two thresholds. For a Choice column with values like Red, Amber, Green, use the Click-to-Edit Pill template and give each choice its color — you get a solid colored pill that people can also change with a click.
Why is the background a pale tint rather than a solid color?
The template uses Microsoft's built-in sp-field-severity classes, which SharePoint renders as a light tint with matching text and icon so it looks native. If you want a solid, saturated lamp, use the Traffic Light (housing) template instead — it draws three lamps and lights the matching one.
What happens when the number is empty?
SharePoint treats an empty Number cell as 0, so blank rows fall into the red band. If that would mislead people, give the column a default value or make it required so there are no blanks to misread.
Can I change the thresholds after I've applied it?
Yes. Open the generator again, set new values for the green and amber thresholds, copy, and paste over the old JSON in Advanced mode. Formatting lives on the column, so the change applies to every view that shows it.