---
title: "Cell Styles"
framework: javascript
version: "36.1.0"
---

# Cell Styles

Cells can be styled based on the column that they belong to or the data that they contain.

You can mix and match any of the following mechanisms:

- **Cell Style:** Set CSS properties on a cell to directly change its appearance.
- **Cell Class:** Attach a CSS class to a cell so that it can be styled by your application's style sheets.
- **Cell Class Rules:** Provide rules for applying CSS classes.

Each of these approaches are presented in the following sections.

> **Note**
>
> If you want to change the default appearance of *all* cells in order to customise the grid to match your application's design, check out the [Theming documentation](https://www.ag-grid.com/javascript-data-grid/theming/).

## Cell Style

Used to provide CSS styles directly (not using a class) to the cell. Can be either an object of CSS styles, or a function returning an object of CSS styles.

| Property | Type | Required | Default | Description |
| --- | --- | --- | --- | --- |
| `cellStyle` | `CellStyle \| CellStyleFunc` |  |  | An object of CSS values / or function returning an object of CSS values for a particular cell. Module: [`CellStyleModule`](https://www.ag-grid.com/javascript-data-grid/modules/). |

```js
const gridOptions = {
    columnDefs: [
        // same style for each row
        {
            headerName: 'Static Styles',
            field: 'static',
            cellStyle: {color: 'red', 'background-color': 'green'}
        },
        // different styles for each row
        {
            headerName: 'Dynamic Styles',
            field: 'dynamic',
            cellStyle: params => {
                if (params.value === 'Police') {
                    //mark police cells as red
                    return {color: 'red', backgroundColor: 'green'};
                }
                return null;
            }
        },
    ],

    // other grid options ...
}
```

## Cell Class

Provides a class for the cells in this column. Can be a string (a class), array of strings (array of classes), or a function (that returns a string or an array of strings).

| Property | Type | Required | Default | Description |
| --- | --- | --- | --- | --- |
| `cellClass` | `string \| string[] \| CellClassFunc` |  |  | Class to use for the cell. Can be string, array of strings, or function that returns a string or array of strings. Module: [`CellStyleModule`](https://www.ag-grid.com/javascript-data-grid/modules/). |

```js
const gridOptions = {
    columnDefs: [
        // return same class for each row
        {
            headerName: 'Static Class',
            field: 'static',
            cellClass: 'my-class'
        },
        // return same array of classes for each row
        {
            headerName: 'Static Array of Classes',
            field: 'staticArray',
            cellClass: ['my-class1','my-class2'],
        },
        // return class based on function
        {
            headerName: 'Function Returns String',
            field: 'function',
            cellClass: params => {
                return params.value === 'something' ? 'my-class-1' : 'my-class-2';
            },
        },
        // return array of classes based on function
        {
            name: 'Function Returns Array',
            field: 'functionArray',
            cellClass: params => ['my-class-1','my-class-2'],
        }
    ],

    // other grid options ...
}
```

## Cell Class Rules

You can define rules which can be applied to include certain CSS classes via `colDef.cellClassRules`. These rules are provided as a JavaScript map where the keys are the class names and the values are expressions that if evaluated to true, the class gets used. The expression can either be a JavaScript function, or a string which is treated as a shorthand for a function by the grid.

| Property | Type | Required | Default | Description |
| --- | --- | --- | --- | --- |
| `cellClassRules` | `CellClassRules` |  |  | Rules which can be applied to include certain CSS classes. Module: [`CellStyleModule`](https://www.ag-grid.com/javascript-data-grid/modules/). |

The following snippet is cellClassRules using functions on a year column:

```js
const gridOptions = {
    columnDefs: [
        {
            field: 'year',
            cellClassRules: {
                // apply green to 2008
                'rag-green-outer': params => params.value === 2008,
                // apply blue to 2004
                'rag-blue-outer': params => params.value === 2004,
                // apply red to 2000
                'rag-red-outer': params => params.value === 2000,
            }
        }
    ],

    // other grid options ...
}
```

## Cell Styling Properties

All cellClass cellStyle and cellClassRules functions take a `CellClassParams`.

Properties available on the `CellClassParams&lt;TData = any, TValue = any, TContext = any&gt;` interface.

| Property | Type | Required | Default | Description |
| --- | --- | --- | --- | --- |
| `column` | [`Column`](https://www.ag-grid.com/javascript-data-grid/column-object/) |  |  | Column for this callback |
| `colDef` | [`ColDef`](https://www.ag-grid.com/javascript-data-grid/column-properties/) |  |  | The colDef associated with the column for this cell |
| `value` | [`TValue \| null \| undefined`](https://www.ag-grid.com/javascript-data-grid/typescript-generics/#cell-value-tvalue) |  |  | The value to be rendered |
| `data` | [`TData \| undefined`](https://www.ag-grid.com/javascript-data-grid/typescript-generics/#row-data-tdata) |  |  | The data associated with this row from rowData. Data is `undefined` for row groups. |
| `node` | [`IRowNode`](https://www.ag-grid.com/javascript-data-grid/row-object/) |  |  | The RowNode associated with this row |
| `rowIndex` | `number` |  |  | The index of the row |
| `api` | [`GridApi`](https://www.ag-grid.com/javascript-data-grid/grid-api/) |  |  | The grid api. |
| `context` | [`TContext`](https://www.ag-grid.com/javascript-data-grid/typescript-generics/#context-tcontext) |  |  | Application context as set on `gridOptions.context`. |

As an alternative, you can also provide shorthands of the functions using an expression. The column Age in the example uses expressions. An expression is evaluated by the grid by executing the string as if it were a Javascript expression. The expression has the following attributes available to it (mapping the attributes of the equivalent params object):

- `x`: maps value
- `ctx`: maps context
- `node`: maps node
- `data`: maps data
- `colDef`: maps colDef
- `rowIndex`: maps rowIndex
- `api`: maps the grid api

In other words, `x` and `ctx` map value and context, all other attributes map the parameters of the same name.

The following snippet is cellClassRules using expressions on an age column:

```js
const gridOptions = {
    columnDefs: [
        {
            field: 'age',
            cellClassRules: {
                'rag-green': 'x < 20',
                'rag-blue': 'x >= 20 && x < 25',
                'rag-red': 'x >= 25',
            }
        }
    ],

    // other grid options ...
}
```

> **Note**
>
> String based expressions are parsed and evaluated as JavaScript. Use of this form of expression may require configuration of your [Content Security Policy](https://www.ag-grid.com/javascript-data-grid/security/#content-security-policy-csp).
>
> Functions are recommended for most use cases, unless there is a specific need for string-based expressions.

## Style Refresh

If you refresh a cell, or a cell is updated due to editing, the `cellStyle`, `cellClass` and `cellClassRules` are all applied again. This has the following effect:

- `cellStyle`: All new styles are applied. If a new style is the same as an old style, the new style overwrites the old style. If a new style is not present, the old style is left (the grid will NOT remove styles).
- `cellClass`: All new classes are applied. Old classes are not removed so be aware that classes will accumulate. If you want to remove old classes, then use cellClassRules.
- `cellClassRules`: Unlike `cellClass` and `cellStyle`, `cellClassRules` dynamically adds or removes CSS classes every time the callback runs. Rules are re-evaluated whenever any column in the `rowNode` updates. This is useful for styling a cell based on another cell's value but may impact performance due to frequent executions.

> **Note**
>
> If you are using `cellStyle` to highlight changing data, then please take note that grid will not remove styles. For example, if you are setting text color to 'red' for a condition, then you should explicitly set it back to default eg 'black' when the condition is not met. Otherwise the highlight will remain once it's first applied.

```js
// unsafe, the red will stay after initially applied
cellStyle: params => params.value > 80 ? { color: 'red' } : null
```

```js
// safe, the black will override the red when the condition is not true
cellStyle: params => params.value > 80 ? { color: 'red' } : { color: 'black' }
```

## Combined Example

Below shows both `cellClassRules` snippets above in a full working example. The example demonstrates the following:

- Age uses `cellClassRules` with expressions (strings instead of functions). Editing the cell will update the style.
- Year uses `cellClassRules` with functions. Editing the cell will update the style.
- Date and Sport use `cellClass`. Date sets it explicitly, Sport sets it using a function. Because a function is used for Sport, it can select class based on data value. Editing Sport will have undetermined results as the class values will accumulate.
- Gold sets `cellStyle` implicitly. It is not dependent on the cell value.
- Silver and Bronze set `cellStyle` using a function that depends on the value. Editing will update the cellStyle.

#### Cell Styling

```ts
import {
  CellClassParams,
  CellClassRules,
  CellStyleModule,
  ClientSideRowModelModule,
  ColDef,
  GridApi,
  GridOptions,
  ICellRendererParams,
  ModuleRegistry,
  NumberEditorModule,
  TextEditorModule,
  ValueParserParams,
  createGrid,
  enableDevValidations,
} from "ag-grid-community";
import { IOlympicData } from "./interfaces";

// Enable extended validations only for development
if (process.env.NODE_ENV !== "production") {
  enableDevValidations();
}

ModuleRegistry.registerModules([
  NumberEditorModule,
  TextEditorModule,
  CellStyleModule,
  ClientSideRowModelModule,
]);

const ragCellClassRules: CellClassRules = {
  "rag-green-outer": (params) => params.value === 2008,
  "rag-blue-outer": (params) => params.value === 2004,
  "rag-red-outer": (params) => params.value === 2000,
};

const columnDefs: ColDef[] = [
  { field: "athlete" },
  {
    field: "age",
    maxWidth: 90,
    valueParser: numberParser,
    cellClassRules: {
      "rag-green": "x < 20",
      "rag-blue": "x >= 20 && x < 25",
      "rag-red": "x >= 25",
    },
  },
  { field: "country" },
  {
    field: "year",
    maxWidth: 90,
    valueParser: numberParser,
    cellClassRules: ragCellClassRules,
    cellRenderer: ragRenderer,
  },
  { field: "date", cellClass: "rag-blue" },
  {
    field: "sport",
    cellClass: cellClass,
  },
  {
    field: "gold",
    valueParser: numberParser,
    cellStyle: {
      // you can use either came case or dashes, the grid converts to whats needed
      backgroundColor: "#aaffaa", // light green
    },
  },
  {
    field: "silver",
    valueParser: numberParser,
    // when cellStyle is a func, we can have the style change
    // dependent on the data, eg different colors for different values
    cellStyle: cellStyle,
  },
  {
    field: "bronze",
    valueParser: numberParser,
    // same as above, but demonstrating dashes in the style, grid takes care of converting to/from camel case
    cellStyle: cellStyle,
  },
];

function cellStyle(params: CellClassParams) {
  const color = numberToColor(params.value);
  return {
    backgroundColor: color,
  };
}

function cellClass(params: CellClassParams) {
  return params.value === "Swimming" ? "rag-green" : "rag-blue";
}

function numberToColor(val: number) {
  if (val === 0) {
    return "#ffaaaa";
  } else if (val == 1) {
    return "#aaaaff";
  } else {
    return "#aaffaa";
  }
}

function ragRenderer(params: ICellRendererParams) {
  return '<span class="rag-element">' + params.value + "</span>";
}

function numberParser(params: ValueParserParams) {
  const newValue = params.newValue;
  let valueAsNumber;
  if (newValue === null || newValue === undefined || newValue === "") {
    valueAsNumber = null;
  } else {
    valueAsNumber = parseFloat(params.newValue);
  }
  return valueAsNumber;
}

let gridApi: GridApi<IOlympicData>;

const gridOptions: GridOptions<IOlympicData> = {
  columnDefs: columnDefs,
  defaultColDef: {
    flex: 1,
    minWidth: 150,
    editable: true,
  },
};

const gridDiv = document.querySelector<HTMLElement>("#myGrid")!;
gridApi = createGrid(gridDiv, gridOptions);

fetch("https://www.ag-grid.com/example-assets/olympic-winners.json")
  .then((response) => response.json())
  .then((data: IOlympicData[]) => gridApi!.setGridOption("rowData", data));
```

[Live example: Cell Styling](https://www.ag-grid.com/examples/cell-styles/cell-styling/typescript)

## First and Last Columns

It's possible to style the cells in the first and last columns using CSS by targeting the `.ag-column-first` and `.ag-column-last` selectors as follows:

```css
.ag-column-first {
    background-color: #2244cc44;
}

.ag-column-last {
    background-color: #cc333344;
}
```

#### Cell Styling

```ts
import {
  CellClassParams,
  CellClassRules,
  ClientSideRowModelModule,
  ColDef,
  GridApi,
  GridOptions,
  ICellRendererParams,
  ModuleRegistry,
  NumberEditorModule,
  TextEditorModule,
  ValueParserParams,
  createGrid,
  enableDevValidations,
} from "ag-grid-community";
import { IOlympicData } from "./interfaces";

// Enable extended validations only for development
if (process.env.NODE_ENV !== "production") {
  enableDevValidations();
}

ModuleRegistry.registerModules([
  NumberEditorModule,
  TextEditorModule,
  ClientSideRowModelModule,
]);

const columnDefs: ColDef[] = [
  { field: "athlete" },
  {
    field: "age",
    maxWidth: 90,
  },
  { field: "country" },
  {
    field: "gold",
  },
  {
    field: "silver",
  },
  {
    field: "bronze",
  },
];

let gridApi: GridApi<IOlympicData>;

const gridOptions: GridOptions<IOlympicData> = {
  columnDefs: columnDefs,
  defaultColDef: {
    flex: 1,
    minWidth: 150,
    editable: true,
  },
};

const gridDiv = document.querySelector<HTMLElement>("#myGrid")!;
gridApi = createGrid(gridDiv, gridOptions);

fetch("https://www.ag-grid.com/example-assets/olympic-winners.json")
  .then((response) => response.json())
  .then((data: IOlympicData[]) => gridApi!.setGridOption("rowData", data));
```

[Live example: Cell Styling](https://www.ag-grid.com/examples/cell-styles/cell-styling-first-last/typescript)
