webdevpuneet.com

Conditional Formatting Table — Live Threshold Cell Coloring HTML CSS JS

Conditional Formatting Table · Tables · Plain HTML, CSS & JS · Live preview

CategoryTables

Copy & paste

Source Code

<div class="tcf-card">
  <div class="tcf-head">
    <h3>Rep performance — units sold</h3>
  </div>
  <div class="tcf-controls">
    <label>Low threshold<input type="number" id="tcfLow" value="40" min="0" max="200"></label>
    <label>High threshold<input type="number" id="tcfHigh" value="80" min="0" max="200"></label>
  </div>
  <table class="tcf-table" id="tcfTable">
    <thead><tr><th>Rep</th><th>Jan</th><th>Feb</th><th>Mar</th><th>Apr</th><th>May</th><th>Jun</th></tr></thead>
    <tbody id="tcfBody"></tbody>
  </table>
</div>

Extend with AI

Take This Snippet Further With AI

The AI prompt for this one is for Patreon supporters ($3 a month), along with a site with no ads. Supporters enter the passcode once and it is remembered in this browser.

· Become a supporter

What's included

Features

Pure value-to-color function
colorFor computes a color band from a value and two thresholds — nothing is precomputed or hardcoded.
Live threshold controls
Number inputs recolor the entire table on every keystroke via the input event.
Three-band classification
Below-low, mid-band, and at-or-above-high map to distinct red/amber/green treatments.
Inverted-range guard
High is clamped to never fall below low, keeping the bands coherent under any input.
Inline computed styling
Colors are set from the function's live return value, appropriate for a continuous threshold-driven mapping.
Uniform across all columns
The same coloring function applies identically to every numeric column with no special-casing.
Tabular numeral alignment
Centered, monospaced-width numerals keep the colored grid easy to scan by column.
Data-driven, not markup-driven
Adding rows, columns, or changing values requires no changes to the coloring logic.

About this UI Snippet

Conditional Formatting Table — Cells Colored Live From Adjustable Thresholds

Screenshot of the Conditional Formatting Table snippet rendered live

Spreadsheets have offered conditional formatting for decades because color is the fastest way to scan a grid of numbers for outliers — red for underperforming, green for exceeding target — without reading every value individually. This snippet reimplements that as a genuine live computation: a plain function maps each cell's numeric value to a color band based on two adjustable threshold inputs, and every cell recolors immediately whenever those thresholds change.

A pure value-to-color function, not precomputed classes

colorFor(value, low, high) takes a number and the two current threshold values and returns a background/foreground color pair with three plain if/return branches — below low is red, between low and high is amber, at or above high is green. Nothing about which cells are which color is baked into the markup or the data; every single cell's color is the live output of calling this function during render, which is what makes the thresholds genuinely adjustable rather than cosmetic.

Number inputs drive a full re-render

Two <input type="number"> controls hold the current low and high thresholds. Their input event (firing on every keystroke or spinner click, not just on blur) calls render(), which re-runs colorFor against every cell in the table with the new threshold values and rewrites the table body — so dragging or typing a new threshold recolors the entire grid live, the same way dragging a conditional formatting rule's threshold in a spreadsheet does.

A guard against an inverted range

If a user sets the high threshold below the low threshold, the three-band logic would produce a nonsensical or empty middle band. render() clamps high up to at least low before computing colors, so the bands always stay in a sane low ≤ middle < high order regardless of what the user types into the controls.

Style applied inline from computed values, not toggled classes

Because the color bands are threshold-driven rather than a small fixed set of states, each cell's background and text color are set directly via an inline style attribute built from colorFor's return value, rather than switching between a few predefined CSS classes — the right approach when the underlying value-to-color mapping is a continuous function of user-adjustable numbers rather than a small enum of fixed states.

Same function, every column

render() runs the identical colorFor call across every numeric column for every rep — there's no per-column special-casing, so adding a seventh month of data or changing which columns exist requires no changes to the coloring logic at all, only to the COLUMNS array driving which fields get rendered.

Customizing it

Add a third or fourth band with more granular thresholds, invert the direction (lower is better) with a toggle, or compute thresholds automatically from the dataset's own mean and standard deviation instead of fixed inputs. Pair with a multi-column sort table to sort by whichever month is currently most colored.

Step by step

How to Use

  1. 1
    Paste HTML, CSS, and JSA sales rep performance table renders with cells colored red, amber, or green by value.
  2. 2
    Adjust the Low threshold inputEvery cell below the new low value immediately turns red; the table recolors live.
  3. 3
    Adjust the High threshold inputCells at or above the new high value turn green; values between the two turn amber.
  4. 4
    Set High below LowThe high value automatically clamps up to match low, keeping the three bands sane.
  5. 5
    Scan for outliersColors make it immediately obvious which reps are under or over target across months.
  6. 6
    Swap in your own data and columnsReplace REPS and COLUMNS — colorFor runs identically across every numeric column.

Real-world uses

Common Use Cases

Sales performance dashboards
Spot underperforming reps by colouring each cell from its value against low and high thresholds, recalculated on every keystroke.
Inventory stock monitoring
Colour stock counts red, amber or green according to adjustable limits, with high clamped so it can never fall below low.
Budget tracking
Flag over-budget or under-target lines in a grid, in the same way spreadsheets use conditional formatting for outliers.
QA test result matrices
Colour pass-rate percentages across builds and suites, and compare with a comparison table for feature grids.
Grading tables
Highlight scores in a grid, using a pure colorFor function that maps a value and two thresholds to a colour band.
Related: Nested JSON to Table Mapper
See the Nested JSON to Table Mapper for a related tables pattern worth pairing with this one.

Got questions?

Frequently Asked Questions

The color bands are driven by two continuously adjustable number inputs, not a small fixed set of states — colorFor computes an actual color value based on where a number falls between two arbitrary thresholds a user can change at any time. Toggling between a handful of predefined CSS classes works for a fixed number of states, but a threshold-driven function is more directly expressed by computing the style value itself in JavaScript and applying it inline.

Add another comparison branch to colorFor before the final return, e.g. if (value >= high * 1.5) return { bg: '#a7f3d0', fg: '#065f46' } for an "exceptional" band, checked before the regular at-or-above-high case — the render loop and every input control keep working unchanged since they only ever call colorFor and use whatever it returns.

Swap which branch returns red and which returns green in colorFor — the below-low branch would return the green color pair and the at-or-above-high branch would return red, since the function only decides which color a range gets, not which direction is "good." Everything else (the threshold inputs, the render loop) is unaffected.

Before rendering, calculate the dataset's mean and standard deviation (or a percentile) across all visible values, and set low/high to something like mean minus one standard deviation and mean plus one standard deviation instead of reading them from the input fields — colorFor itself doesn't need to change, since it only needs any two numeric thresholds passed in.

Keep colorFor as a pure, framework-independent function. Store the low and high threshold values in component state bound to two number inputs, and compute each cell's inline style (or CSS custom properties) by calling colorFor(value, low, high) during render — the function itself needs no changes since it takes plain numbers and returns a plain color pair.