SharePoint column formatting

SharePoint data bar column formatting

The at-a-glance bars Excel adds with conditional formatting — in a SharePoint list column, sized against a maximum you choose, with the number still visible beside it.

Excel users reach for data bars the moment a column of numbers needs comparing: one look tells you which rows are big and which are small, without reading a single digit. SharePoint and Microsoft Lists have no built-in equivalent, but a short piece of column formatting JSON draws the same thing — a track, a fill whose width is the value as a fraction of your max, and the number in a monospace label beside it.

This is a different job from a progress bar. A progress bar answers "how finished is this one item?" and changes color at thresholds. A data bar answers "how does this row compare to the others?" — every bar shares one scale and one color, so the eye can rank them instantly.

Before and after

RegionOpen orders
North America18
EMEA11
APAC6
LATAM20
Fill = value ÷ max (20) · same color for every row
Build this data bar → Opens the generator on the Data Bar template. Enter your field name and max value, copy the JSON, done.

What the SharePoint data bar JSON looks like

The generator produces JSON like the example below. An outer flex row holds two things: a fixed-width track with the fill positioned inside it, and a label showing the raw number:

{
  "$schema": "https://developer.microsoft.com/json-schemas/sp/v2/column-formatting.schema.json",
  "elmType": "div",
  "inlineEditField": "[$Value]",
  "style": { "display": "flex", "align-items": "center", "cursor": "pointer" },
  "children": [
    {
      "elmType": "div",
      "style": {
        "position": "relative", "height": "14px", "width": "90px",
        "border-radius": "3px", "background-color": "#edebe9",
        "overflow": "hidden", "flex-shrink": "0", "margin-right": "8px"
      },
      "children": [
        {
          "elmType": "div",
          "style": {
            "position": "absolute", "top": "0", "left": "0", "height": "14px",
            "border-radius": "3px", "background-color": "#0078d4",
            "width": "=if(Number([$Value]) >= 20, '100%', if(Number([$Value]) <= 0, '0%', toString(Number([$Value]) / 20 * 100) + '%'))"
          }
        }
      ]
    },
    {
      "elmType": "span",
      "style": { "font-size": "12px", "font-weight": "600", "color": "#323130", "font-family": "Consolas, Menlo, monospace" },
      "txtContent": "=toString([$Value])"
    }
  ]
}

The whole effect lives in one line: the fill's width is value ÷ max × 100%, clamped so anything at or above the max fills the track and anything at or below zero draws nothing. Number() guards against a value that arrives as text, and overflow: hidden on the track keeps the rounded corners clean. Because the track is a fixed 90px, every row's bar is on the same scale — which is the entire point of a data bar.

Two related templates cover the cases a plain data bar can't. Variance Bar handles numbers that can be negative — it grows left from a centre line for values under zero and right for values over it, ideal for actual-vs-plan. Bullet Chart adds shaded range bands and a tick at a target value, when "how big" isn't enough and you need "big compared to what".

How to apply it

  1. Open the generator and pick the Data Bar template (or use the button above).
  2. Enter your column's internal field name — see the note below.
  3. Set the Max to the largest value you expect — it's what a full bar means.
  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.
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 "Open Orders" might be OpenOrders or Open_x0020_Orders internally). See the internal field name guide to find yours.

Common questions

How is this different from the progress bar template?
A progress bar shows how complete one thing is and changes color at thresholds. A data bar compares sizes across rows: every bar uses the same scale and the same color, so the longest bar is simply the largest number. Use data bars for counts and amounts, progress bars for percent complete.
What if a value is bigger than the max?
The bar stops at 100% of the track — it never overflows the cell — and the number beside it still shows the real value. Set the max to the largest value you expect, or a round number just above it.
Can it handle negative numbers?
Not this one: anything at or below zero draws an empty track. For values that go both ways, use the Variance Bar template — it grows left from a centre line for negatives and right for positives.
Can I hide the number and show only the bar?
Yes. In the JSON, remove the last child element (the span with the txtContent) and only the track remains. Keep the number if people need exact values, since a bar alone is hard to read precisely.