---
url: /datatable/conditional-formatting
name: Conditional Formatting
description:
    "`dash_table.DataTable` is an interactive table that supports rich styling,
    conditional formatting, editing, sorting, filtering, and more."
languages:
  - python
  - julia
  - matlab
---

# ![](/assets/images/language_icons/f-sharp_50px.svg) Conditional Formatting

Conditional formatting is provided through the `style_data_conditional`
property. The `if` keyword provides a set of conditional formatting
statements and the rest of the keywords are camelCased CSS properties.

The `if` syntax supports several operators, `row_index`, `column_id`,
`filter_query`, `column_type`, `column_editable`, and `state`.

`filter_query` is the most flexible option when dealing with data.

Here is an example of all operators:

{{example all_operators}}

Notes:
- `filter_query` supports different operators depending on the data type
of the column:

  - `=`, `>`, `>=`, `<`, `<=`, and `contains` are supported by
  all data types (`numeric`, `text`, `datetime`, and `any`)
  - With `contains`, the right-hand-side needs to be a string,
  so `{Date} contains "01"` will work but `{Date} contains 1` will not.
  - `datestartswith` is supported by `datetime`
  - `is nil` is supported by all data types
  - `is blank` is supported by all data types

- A column's default data type is `any`
- `column_type` refers to the data type of the column (`numeric`, `text`, `datetime`, and `any`)
- `column_editable` can be equal to `True` or `False` (new in Dash 1.12.0)
- `state` can be equal to `'active'` or `'selected'` (new in Dash 1.12.0). Use this to change
   the default pink background and border colors for selected and active cells.
- `row_index` is absolute - if you filter or sort your table,
   the 5th row will remain highlighted. Try sorting the columns and
   notice how "San Francisco" remains highlighted but "London" does not.
- `column_id`, `row_index`, and `header_index` can be equal to a scalar
(as above) or a _list of values_. For example, `'column_id': ['Region', 'Pressure']`
is valid (new in Dash 1.12.0). `DataTable` filtering & conditional formatting
performs faster when specified a list of values vs a list of separate `if` blocks.
- Note `'filter_query': '{Delivery} > {Date}'`: Filter queries can compare columns
to each other!
- `id` is a special hidden column that can be used as an alternative
to `row_index` for highlighting data by index. Since each row has a
unique `id`, the conditional formatting associated with this `id`
will remain associated with that data after sorting and filtering.
- `RebeccaPurple`, `hotpink`, `DodgerBlue`... These are
[named CSS colors](https://developer.mozilla.org/en-US/docs/Web/CSS/color_value#Color_keywords).
We recommend avoiding the common color names like
`red`, `blue`, `green`  as they look very outdated. For other color
suggestions, see [http://clrs.cc/](http://clrs.cc/).
- Since we're using `.format`, we escape `{` with `\{\{` and `}` with `\}\}`.
- To highlight a row, omit `column_id`. To highlight a particular cell, include `column_id`.
- `style_cell_conditional` (all cells, including headers),
`style_header_conditional` (header cells),
`style_filter_conditional` (filter input boxes)
are alternative keywords that can be used for filtering other parts of the table.
- Limitation - If the table is editable, then the maximum value could change
if the user edits the table. Since this example hard codes the
maximum value in the filter expression, the highlighting value
would no longer be highlighted. As a workaround, you could update
`style_data_conditional` via a callback whenever `derived_virtual_data` changes.
This limitation applies for any conditional formatting with hardcoded
numbers computed from an expression in Python
(including many of the examples below!).
See [plotly/dash-table#755](https://github.com/plotly/dash-table/issues/755) for updates.

## Alternative Highlighting Styles

Instead of highlighting the background cell, you can change the color
of the text, bold the text, add underlines, or style it using any
other CSS property.

{{example alt_highlighting_styles}}

### Special Characters like Emojis, Stars, Checkmarks, Circles

You can copy and paste emoji unicode characters directly into your code.
We recommend copying values from emojipedia, e.g.
[https://emojipedia.org/star/](https://emojipedia.org/star/).

New unicode emoji characters are released every year and may not be
available in the character sets of your audience's machines.
The appearance of these icons differs on most operating systems.

{{example special_characters}}

## Filtering and Conditional Formatting Recipes

### Highlighting the Max Value in a Column

{{example highlighting_max_val_col}}

### Highlighting a Row with the Min Value

{{example highlighting_row_min_val}}

### Highlighting the Top Three or Bottom Three Values in a Column

{{example highlighting_top_3_or_bottom_3_val_col}}

### Highlighting the Max Value in Every Row

{{example highlighting_max_val_every_row}}

### Highlighting the Top Two Values in a Row

{{example highlighting_top_2_val_row}}

### Highlighting the Maximum Value in the Table

{{example highlighting_max_val_table}}

### Highlighting a Range of Values

{{example highlighting_range_val1}}

{{example highlighting_range_val2}}

_Let's break down `\{\{\{col}}}`. We want the final expression to look something like
`{2017} > 5 & {2017} < 10` where 2017 is the name of the column.
Since we're using `.format()`, we need to escape the brackets,
so `{2017}` would be `{\{2017}}`. Then, we need to replace `2017` with `{col}`
for the find-and-replace, so  becomes`\{\{\{col}}}`.`format(col=col)`_

### Highlighting Top 10% or Bottom 10% of Values by Column

{{example highlighting_top10_bottom10_val_col1}}

{{example highlighting_top10_bottom10_val_col2}}

### Highlighting Values above Average and Below Average

Here, the highlighting is done _per column_.

{{example highlighting_val_above_below_avg1}}

Here, the highlighting is done _per table_.

{{example highlighting_val_above_below_avg2}}

### Highlighting None, NaN, or Empty String Values

Three filter queries help with empty or blank values:
- `{my_column} is nil` will match `None` values
- `{my_column} is blank` will match `None` values and empty strings
- `{my_column} = ""` will match empty strings

{{example highlighting_none_nan_empty}}

### Displaying Special Values for `NaN` or `None` Values

{{example display_special_val_nan_none1}}

Limitations:
- `Format(nully=)` does not yet match for empty strings, only
`None` values. See [plotly/dash-table#763](https://github.com/plotly/dash-table/issues/763)
for updates.
- `'type': 'numeric'` needs to be set, see [plotly/dash-table#762](https://github.com/plotly/dash-table/issues/762)
for updates.

An alternative method would be to fill in e.g. "N/A" in the data before rendering:

{{example display_special_val_nan_none2}}

Limitation: If your table is editable, then if a user deletes the
contents of a cell, "N/A" will no longer be displayed.
This is unlike the example with `Format` where the `DataTable` will
automatically display `N/A` for any empty cells, even after editing.

{{oss {{dash-club}} }}

### Highlighting Text that Contains a Value

{{example highlighting_txt_contains_val}}

### Highlighting Text that Equals a Value

{{example highlighting_txt_eq_val}}

### Highlighting Cells by Value with a Colorscale Like a Heatmap

This recipe shades cells with `style_data_conditional` and creates a
legend with HTML components. You'll need to `pip install colorlover`
to get the colorscales.

{{example highlighting_cells_val_color_heatmap}}

### Highlighting with a Colorscale on a Single Column

{{example highlighting_colorscale_single_col}}

### Displaying Data Bars

These recipes display a creative use of background `linear-gradient`
colors to display horizontal bar charts within the table.
Your mileage may vary! Feel free to modify these recipes for your own
use.

{{example display_data_bars}}

### Data Bars without Text

Display the data bars without text by creating a new column and making
the text transparent.

{{example data_bars_without_txt}}

### Diverging Data Bars

The `data_bars_diverging` function splits up the data into two quadrants
by the midpoint.
Alternative representations of data bars may split up the data by
positive and negative numbers or by the average values.
Your mileage may vary! Feel free to modify the `data_bars_diverging`
function to your own visualization needs. If you create something new,
please share your work on the [Dash Community Forum](https://community.plotly.com/tag/show-and-tell).

{{example diverging_data_bars}}

### Highlighting Dates

{{example highlighting_dates}}