---
title: "Row Styles"
framework: angular
version: "36.1.0"
---

# Row Styles

Row customisation can be achieved in the following ways:

- **Row Style:** Providing a CSS style for the rows. Applied individually to each element.
- **Row Class:** Providing a CSS class for the rows. Not removed on data refresh.
- **Row Class Rules:** Providing rules for applying CSS classes. These styles are dynamic and applied in batches.

> **Note**
>
> We recommend Row Class Rules for most use cases. See [Refresh of Styles](https://www.ag-grid.com/angular-data-grid/row-styles/#refresh-of-styles) for more details.
>
> When spanning rows, the row is not a visual component, and so the cells should be styled instead.

Each of these approaches are presented in the following sections.

## Row Style

You can add CSS styles to each row in the following ways:

| Property | Type | Required | Default | Description |
| --- | --- | --- | --- | --- |
| `rowStyle` | `RowStyle` |  |  | The style properties to apply to all rows. Set to an object of key (style names) and values (style values). Module: [`RowStyleModule`](https://www.ag-grid.com/angular-data-grid/modules/). |
| `getRowStyle` | `GetRowStyle` |  |  | Callback version of property `rowStyle` to set style for each row individually. Function should return an object of CSS values or undefined for no styles. Module: [`RowStyleModule`](https://www.ag-grid.com/angular-data-grid/modules/). |

```ts
<ag-grid-angular
    [rowStyle]="rowStyle"
    [getRowStyle]="getRowStyle"
    /* other grid options ... */ />

// set background colour on every row, this is probably bad, should be using CSS classes
this.rowStyle = { background: 'black' };
// set background colour on even rows again, this looks bad, should be using CSS classes
this.getRowStyle = params => {
    if (params.node.rowIndex % 2 === 0) {
        return { background: 'red' };
    }
};
```

If your data is static, use row classes to apply styles for better performance.

## Row Class

You can add CSS classes to each row in the following ways:

| Property | Type | Required | Default | Description |
| --- | --- | --- | --- | --- |
| `rowClass` | `string \| string[]` |  |  | CSS class(es) for all rows. Provide either a string (class name) or array of strings (array of class names). Module: [`RowStyleModule`](https://www.ag-grid.com/angular-data-grid/modules/). |
| `getRowClass` | `GetRowClass` |  |  | Callback version of property `rowClass` to set class(es) for each row individually. Function should return either a string (class name), array of strings (array of class names) or undefined for no class. Module: [`RowStyleModule`](https://www.ag-grid.com/angular-data-grid/modules/). |

```ts
<ag-grid-angular
    [rowClass]="rowClass"
    [getRowClass]="getRowClass"
    /* other grid options ... */ />

// all rows assigned CSS class 'my-green-class'
this.rowClass = 'my-green-class';
// all even rows assigned 'my-shaded-effect'
this.getRowClass = params => {
    if (params.node.rowIndex % 2 === 0) {
        return 'my-shaded-effect';
    }
};
```

## Row Class Rules

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

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

The following snippet shows `rowClassRules` that use functions and the value from the year column:

```ts
<ag-grid-angular
    [rowClassRules]="rowClassRules"
    /* other grid options ... */ />

this.rowClassRules = {
    // apply green to 2008
    'rag-green-outer': (params) => { return params.data.year === 2008; },

    // apply amber 2004
    'rag-amber-outer': (params) => { return params.data.year === 2004; },

    // apply red to 2000
    'rag-red-outer': (params) => { return params.data.year === 2000; }
};
```

## Row Style/Class Functions

All rowStyle, rowClass and rowClassRules functions take a `RowClassParams` params object.

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

| Property | Type | Required | Default | Description |
| --- | --- | --- | --- | --- |
| `data` | [`TData \| undefined`](https://www.ag-grid.com/angular-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/angular-data-grid/row-object/) |  |  | The RowNode associated with this row |
| `rowIndex` | `number` |  |  | The index of the row |
| `api` | [`GridApi`](https://www.ag-grid.com/angular-data-grid/grid-api/) |  |  | The grid api. |
| `context` | [`TContext`](https://www.ag-grid.com/angular-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. 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):

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

The following snippet shows `rowClassRules` applying classes to rows using expressions on an age column value:

```ts
<ag-grid-angular
    [rowClassRules]="rowClassRules"
    /* other grid options ... */ />

this.rowClassRules = {
    'rag-green': 'data.age < 20',
    'rag-amber': 'data.age >= 20 && data.age < 25',
    'rag-red': 'data.age >= 25',
};
```

## Refresh of Styles

If you refresh a row, or a cell is updated due to editing, the `rowStyle`, `rowClass` and `rowClassRules` are all applied again. This has the following effect:

- **rowStyle**: All new styles are applied. Style properties not present in the new result are not removed — previously applied style properties will persist on the row element.
- **rowClass**: 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 rowClassRules.
- **rowClassRules**: Rules that return true will have the class applied the second time. Rules that return false will have the class removed second time.

## Example Row Class Rules

The example below demonstrates `rowClassRules`:

- `rowClassRules` are used to apply the class `sick-days-warning` when the number of sick days > 5 and <= 7, and the class `sick-days-breach` is applied when the number of sick days >= 8.
- The grid re-evaluates the rowClassRules and applies styles when the data is changed independent of mechanism. See [Updating Data](https://www.ag-grid.com/angular-data-grid/data-update/) for details on methods to update data.

#### Row Class Rules

```ts
import { Component } from "@angular/core";
import { AgGridAngular } from "ag-grid-angular";
import "./styles.css";
import {
  ClientSideRowModelModule,
  ColDef,
  ColGroupDef,
  GridApi,
  GridOptions,
  GridReadyEvent,
  ModuleRegistry,
  NumberEditorModule,
  RowApiModule,
  RowClassRules,
  RowStyleModule,
  TextEditorModule,
  enableDevValidations,
} from "ag-grid-community";
import { getData } from "./data";
if (process.env.NODE_ENV !== "production") {
  enableDevValidations();
}

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

@Component({
  selector: "my-app",
  standalone: true,
  imports: [AgGridAngular],
  template: `<div class="example-wrapper">
    <div style="margin-bottom: 5px">
      <button (click)="setData()">Update Data</button>
    </div>

    <ag-grid-angular
      style="width: 100%; height: 100%;"
      [rowData]="rowData"
      [columnDefs]="columnDefs"
      [rowClassRules]="rowClassRules"
      (gridReady)="onGridReady($event)"
    />
  </div> `,
})
export class AppComponent {
  private gridApi!: GridApi;

  rowData: any[] | null = getData();
  columnDefs: ColDef[] = [
    { headerName: "Employee", field: "employee" },
    { headerName: "Number Sick Days", field: "sickDays", editable: true },
  ];
  rowClassRules: RowClassRules = {
    // row style function
    "sick-days-warning": (params) => {
      const numSickDays = params.data.sickDays;
      return numSickDays > 5 && numSickDays <= 7;
    },
    // row style expression
    "sick-days-breach": "data.sickDays >= 8",
  };

  setData() {
    this.gridApi.forEachNode(function (rowNode) {
      const newData = {
        employee: rowNode.data.employee,
        sickDays: randomInt(),
      };
      rowNode.setData(newData);
    });
  }

  onGridReady(params: GridReadyEvent) {
    this.gridApi = params.api;
  }
}

function randomInt() {
  return Math.floor(window.agRandom() * 10);
}
```

[Live example: Row Class Rules](https://www.ag-grid.com/examples/row-styles/row-class-rules/angular)

## Highlighting Rows and Columns

The grid can highlight both Rows and Columns as the mouse hovers over them.

Highlighting Rows is on by default. To turn it off, set the grid property `suppressRowHoverHighlight=true`.

Highlighting Columns is off by default. To turn it on, set the grid property `columnHoverHighlight=true`.

```ts
<ag-grid-angular
    [suppressRowHoverHighlight]="suppressRowHoverHighlight"
    [columnHoverHighlight]="columnHoverHighlight"
    /* other grid options ... */ />

// turns OFF row hover, it's on by default
this.suppressRowHoverHighlight = true;
// turns ON column hover, it's off by default
this.columnHoverHighlight = true;
```

In this example Rows and Columns are highlighted.

Note if you hover over a header group, all columns in the group will be highlighted.

#### Highlight Rows And Columns

```ts
import { Component } from "@angular/core";
import { HttpClient } from "@angular/common/http";
import { AgGridAngular } from "ag-grid-angular";
import {
  ClientSideRowModelModule,
  ColDef,
  ColGroupDef,
  ColumnHoverModule,
  GridApi,
  GridOptions,
  GridReadyEvent,
  ModuleRegistry,
  enableDevValidations,
} from "ag-grid-community";
if (process.env.NODE_ENV !== "production") {
  enableDevValidations();
}

ModuleRegistry.registerModules([ColumnHoverModule, ClientSideRowModelModule]);
import { IOlympicData } from "./interfaces";

@Component({
  selector: "my-app",
  standalone: true,
  imports: [AgGridAngular],
  template: `<ag-grid-angular
    style="width: 100%; height: 100%;"
    [columnDefs]="columnDefs"
    [defaultColDef]="defaultColDef"
    [columnHoverHighlight]="true"
    [rowData]="rowData"
    (gridReady)="onGridReady($event)"
  /> `,
})
export class AppComponent {
  columnDefs: (ColDef | ColGroupDef)[] = [
    {
      headerName: "Participant",
      children: [{ field: "athlete" }, { field: "age" }],
    },
    {
      headerName: "Details",
      children: [
        { field: "country" },
        { field: "year" },
        { field: "date" },
        { field: "sport" },
      ],
    },
  ];
  defaultColDef: ColDef = {
    flex: 1,
  };
  rowData!: IOlympicData[];

  constructor(private http: HttpClient) {}

  onGridReady(params: GridReadyEvent<IOlympicData>) {
    this.http
      .get<
        IOlympicData[]
      >("https://www.ag-grid.com/example-assets/olympic-winners.json")
      .subscribe((data) => (this.rowData = data));
  }
}
```

[Live example: Highlight Rows And Columns](https://www.ag-grid.com/examples/row-styles/highlight-rows-and-columns/angular)

In this example Column highlighting is disabled by default and Row highlighting has been disabled using `suppressRowHoverHighlight=true`.

#### No Highlighting Rows And Columns

```ts
import { Component } from "@angular/core";
import { HttpClient } from "@angular/common/http";
import { AgGridAngular } from "ag-grid-angular";
import {
  ClientSideRowModelModule,
  ColDef,
  ColGroupDef,
  GridApi,
  GridOptions,
  GridReadyEvent,
  ModuleRegistry,
  enableDevValidations,
} from "ag-grid-community";
if (process.env.NODE_ENV !== "production") {
  enableDevValidations();
}

ModuleRegistry.registerModules([ClientSideRowModelModule]);
import { IOlympicData } from "./interfaces";

@Component({
  selector: "my-app",
  standalone: true,
  imports: [AgGridAngular],
  template: `<ag-grid-angular
    style="width: 100%; height: 100%;"
    [columnDefs]="columnDefs"
    [defaultColDef]="defaultColDef"
    [suppressRowHoverHighlight]="true"
    [rowData]="rowData"
    (gridReady)="onGridReady($event)"
  /> `,
})
export class AppComponent {
  columnDefs: (ColDef | ColGroupDef)[] = [
    {
      headerName: "Participant",
      children: [{ field: "athlete" }, { field: "age" }],
    },
    {
      headerName: "Details",
      children: [
        { field: "country" },
        { field: "year" },
        { field: "date" },
        { field: "sport" },
      ],
    },
    {
      headerName: "Medals",
      children: [
        { field: "gold" },
        { field: "silver" },
        { field: "bronze" },
        { field: "total" },
      ],
    },
  ];
  defaultColDef: ColDef = {
    flex: 1,
  };
  rowData!: IOlympicData[];

  constructor(private http: HttpClient) {}

  onGridReady(params: GridReadyEvent<IOlympicData>) {
    this.http
      .get<
        IOlympicData[]
      >("https://www.ag-grid.com/example-assets/olympic-winners.json")
      .subscribe((data) => (this.rowData = data));
  }
}
```

[Live example: No Highlighting Rows And Columns](https://www.ag-grid.com/examples/row-styles/highlight-nothing/angular)

Row Highlighting works by the grid adding the CSS class `ag-row-hover` to the rows getting hovered. The grid cannot depend on using CSS `:hover` selector as this will not highlight the entire row if Columns are pinned.

Column Highlighting works by the grid adding the CSS class `ag-column-hover` to all Cells to be highlighted.

## Styling the First and Last Rows

It's possible to style the first and last rows of the grid using CSS by targeting the `.ag-row-first` and `.ag-row-last` selectors as follows:

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

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

#### Row Styling First and Last

```ts
import { Component } from "@angular/core";
import { HttpClient } from "@angular/common/http";
import { AgGridAngular } from "ag-grid-angular";
import "./styles.css";
import {
  ClientSideRowModelModule,
  ColDef,
  ColGroupDef,
  GridApi,
  GridOptions,
  GridReadyEvent,
  ModuleRegistry,
  enableDevValidations,
} from "ag-grid-community";
if (process.env.NODE_ENV !== "production") {
  enableDevValidations();
}

ModuleRegistry.registerModules([ClientSideRowModelModule]);
import { IOlympicData } from "./interfaces";

@Component({
  selector: "my-app",
  standalone: true,
  imports: [AgGridAngular],
  template: `<ag-grid-angular
    style="width: 100%; height: 100%;"
    [columnDefs]="columnDefs"
    [defaultColDef]="defaultColDef"
    [rowData]="rowData"
    (gridReady)="onGridReady($event)"
  /> `,
})
export class AppComponent {
  columnDefs: (ColDef | ColGroupDef)[] = [
    {
      headerName: "Participant",
      children: [{ field: "athlete" }, { field: "age" }],
    },
    {
      headerName: "Details",
      children: [
        { field: "country" },
        { field: "year" },
        { field: "date" },
        { field: "sport" },
      ],
    },
    {
      headerName: "Medals",
      children: [
        { field: "gold" },
        { field: "silver" },
        { field: "bronze" },
        { field: "total" },
      ],
    },
  ];
  defaultColDef: ColDef = {
    flex: 1,
  };
  rowData!: IOlympicData[];

  constructor(private http: HttpClient) {}

  onGridReady(params: GridReadyEvent<IOlympicData>) {
    this.http
      .get<
        IOlympicData[]
      >("https://www.ag-grid.com/example-assets/olympic-winners.json")
      .subscribe((data) => (this.rowData = data.slice(0, 5)));
  }
}
```

[Live example: Row Styling First and Last](https://www.ag-grid.com/examples/row-styles/row-styling-first-last/angular)
