---
title: "Column Headers - Styling & Height"
framework: react
version: "36.1.0"
---

# Column Headers - Styling & Height

Column Headers can be styled using CSS classes and inline styles. Header row heights can be configured statically or set to adjust automatically based on content.

## Header Style

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

| Property | Type | Required | Default | Description |
| --- | --- | --- | --- | --- |
| `headerStyle` | `HeaderStyle \| HeaderStyleFunc` |  |  | An object of CSS values / or function returning an object of CSS values for a particular header. |

```jsx
const [columnDefs, setColumnDefs] = useState([
    // applies to header and floating filter header
    {
        headerName: 'Static Styles',
        field: 'static',
        headerStyle: { color: 'red', 'background-color': 'green' }
    },
    {
        headerName: 'Dynamic Styles',
        field: 'dynamic',
        headerStyle: params => {
            // only style floating filter
            if (params.floatingFilter) {
                return { backgroundColor: 'green' };
            }
            return null;
        }
    },
]);

<AgGridReact columnDefs={columnDefs} />
```

## Header Class

Provides a class for the header. 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 |
| --- | --- | --- | --- | --- |
| `headerClass` | `HeaderClass` |  |  | CSS class to use for the header cell. Can be a string, array of strings, or function. |

```jsx
const [columnDefs, setColumnDefs] = useState([
    {
        headerName: 'Static Class',
        field: 'static',
        headerClass: 'my-class'
    },
    {
        headerName: 'Static Array of Classes',
        field: 'staticArray',
        headerClass: ['my-class1','my-class2'],
    },
    {
        headerName: 'Function Returns String',
        field: 'function',
        headerClass: params => {
            return params.columnGroup ? 'my-custom-column-group' : 'my-custom-column';
        },
    }
]);

<AgGridReact columnDefs={columnDefs} />
```

### Header Class & Style Example

Below shows both headerStyle and headerClass in a full working example. The example demonstrates the following:

- **Athlete Details**: uses `headerStyle` static object.
- **Athlete**: uses `headerStyle` static object. This also causes the floating filter to be styled.
- **Country**: uses `headerStyle` function callback. This allows to set a different background color for the header and floating filter.
- **Sport**: uses `headerClass` to add the `sport-header` class to the header.
- **Medal Details**: uses `headerStyle` callback function to toggle different styles when the group is expanded or collapsed.

#### Header Styling

```tsx
"use client";

import React, {
  useCallback,
  useMemo,
  useRef,
  useState,
  StrictMode,
} from "react";
import { createRoot } from "react-dom/client";
import { AgGridReact, AgGridProvider } from "ag-grid-react";
import "./styles.css";
import {
  ClientSideRowModelModule,
  ColDef,
  ColGroupDef,
  GridApi,
  GridOptions,
  HeaderClassParams,
  ModuleRegistry,
  NumberFilterModule,
  TextFilterModule,
  enableDevValidations,
} from "ag-grid-community";
import { useFetchJson } from "./useFetchJson";

if (process.env.NODE_ENV !== "production") {
  enableDevValidations();
}

const modules = [
  ClientSideRowModelModule,
  TextFilterModule,
  NumberFilterModule,
];

const GridExample = () => {
  const containerStyle = useMemo(() => ({ width: "100%", height: "100%" }), []);
  const gridStyle = useMemo(() => ({ height: "100%", width: "100%" }), []);

  const [columnDefs, setColumnDefs] = useState<(ColDef | ColGroupDef)[]>([
    {
      headerName: "Athlete Details",
      headerStyle: { color: "white", backgroundColor: "cadetblue" },
      children: [
        {
          field: "athlete",
          headerStyle: { color: "white", backgroundColor: "teal" },
        },
        { field: "age", initialWidth: 120 },
        {
          field: "country",
          headerStyle: (params: HeaderClassParams) => {
            return {
              color: "white",
              backgroundColor: params.floatingFilter
                ? "cornflowerblue"
                : "teal",
            };
          },
        },
      ],
    },
    {
      field: "sport",
      wrapHeaderText: true,
      autoHeaderHeight: true,
      headerName: "The Sport the athlete participated in",
      headerClass: "sport-header",
    },
    {
      headerName: "Medal Details",
      headerStyle: (params) => {
        return {
          color: "white",
          backgroundColor: params.columnGroup?.isExpanded()
            ? "cornflowerblue"
            : "orangered",
        };
      },
      children: [
        { field: "bronze", columnGroupShow: "open" },
        { field: "silver", columnGroupShow: "open" },
        { field: "gold", columnGroupShow: "open" },
        {
          columnGroupShow: "closed",
          field: "total",
        },
      ],
    },
  ]);
  const defaultColDef = useMemo<ColDef>(() => {
    return {
      initialWidth: 200,
      floatingFilter: true,
      filter: true,
    };
  }, []);

  const { data, loading } = useFetchJson<any>(
    "https://www.ag-grid.com/example-assets/olympic-winners.json",
  );

  return (
    <AgGridProvider modules={modules}>
      <div style={containerStyle}>
        <div style={gridStyle}>
          <AgGridReact
            rowData={data}
            loading={loading}
            columnDefs={columnDefs}
            defaultColDef={defaultColDef}
          />
        </div>
      </div>
    </AgGridProvider>
  );
};

const root = createRoot(document.getElementById("root")!);
root.render(
  <StrictMode>
    <GridExample />
  </StrictMode>,
);
```

[Live example: Header Styling](https://www.ag-grid.com/examples/column-headers-styling/header-styles/reactFunctionalTs/)

## Header Height

These properties can be used to change the different heights used in the headers.

| Property | Type | Required | Default | Description |
| --- | --- | --- | --- | --- |
| `headerHeight` | `number` |  |  | The height in pixels for the row containing the column label header. If not specified, it uses the theme value of `header-height`. See [Header Height](https://www.ag-grid.com/react-data-grid/column-headers-styling/#header-height) for more information. |
| `groupHeaderHeight` | `number` |  |  | The height in pixels for the rows containing header column groups. If not specified, it uses `headerHeight`. See [Header Height](https://www.ag-grid.com/react-data-grid/column-headers-styling/#header-height) for more information. |
| `floatingFiltersHeight` | `number` |  |  | The height in pixels for the row containing the floating filters. If not specified, it uses the theme value of `header-height`. See [Header Height](https://www.ag-grid.com/react-data-grid/column-headers-styling/#header-height) for more information. |
| `pivotHeaderHeight` | `number` |  |  | The height in pixels for the row containing the columns when in pivot mode. If not specified, it uses `headerHeight`. See [Header Height](https://www.ag-grid.com/react-data-grid/column-headers-styling/#header-height) for more information. |
| `pivotGroupHeaderHeight` | `number` |  |  | The height in pixels for the row containing header column groups when in pivot mode. If not specified, it uses `groupHeaderHeight`. See [Header Height](https://www.ag-grid.com/react-data-grid/column-headers-styling/#header-height) for more information. |
| `hidePaddedHeaderRows` | `boolean` |  |  | Hide any column header rows that would only contain padded groups. See [Hiding Additional Header Rows](https://www.ag-grid.com/react-data-grid/column-groups/#hide-padded-header-rows) for more information. |

As you can see in the example below, if you change any of the header heights, this change will be reflected automatically. Note how if the value is cleared (set to `undefined`), it might reuse other values. To see all the interactions check the properties descriptions at the top of the page.

#### Dynamic Header Height

```tsx
"use client";

import React, {
  useCallback,
  useMemo,
  useRef,
  useState,
  StrictMode,
} from "react";
import { createRoot } from "react-dom/client";
import { AgGridReact, AgGridProvider } from "ag-grid-react";
import "./styles.css";
import {
  AutoGroupColumnDef,
  ClientSideRowModelModule,
  ColDef,
  ColGroupDef,
  GridApi,
  GridOptions,
  ModuleRegistry,
  NumberFilterModule,
  TextFilterModule,
  enableDevValidations,
} from "ag-grid-community";
import { PivotModule } from "ag-grid-enterprise";
import { IOlympicData } from "./interfaces";
import { useFetchJson } from "./useFetchJson";

if (process.env.NODE_ENV !== "production") {
  enableDevValidations();
}

const modules = [
  TextFilterModule,
  ClientSideRowModelModule,
  PivotModule,
  NumberFilterModule,
];

function setIdText(id: string, value: string | number | undefined) {
  document.getElementById(id)!.textContent =
    value == undefined ? "undefined" : value + "";
}

const GridExample = () => {
  const gridRef = useRef<AgGridReact<IOlympicData>>(null);
  const containerStyle = useMemo(() => ({ width: "100%", height: "100%" }), []);
  const gridStyle = useMemo(() => ({ height: "100%", width: "100%" }), []);

  const [columnDefs, setColumnDefs] = useState<(ColDef | ColGroupDef)[]>([
    {
      headerName: "Athlete Details",
      children: [
        {
          field: "athlete",
          width: 150,
          suppressSizeToFit: true,
          enableRowGroup: true,
          rowGroupIndex: 0,
        },
        {
          field: "age",
          width: 90,
          minWidth: 75,
          maxWidth: 100,
          enableRowGroup: true,
        },
        {
          field: "country",
          enableRowGroup: true,
        },
        {
          field: "year",
          width: 90,
          enableRowGroup: true,
          pivotIndex: 0,
        },
        { field: "sport", width: 110, enableRowGroup: true },
        {
          field: "gold",
          enableValue: true,
          suppressHeaderMenuButton: true,
          filter: "agNumberColumnFilter",
          aggFunc: "sum",
        },
        {
          field: "silver",
          enableValue: true,
          suppressHeaderMenuButton: true,
          filter: "agNumberColumnFilter",
          aggFunc: "sum",
        },
        {
          field: "bronze",
          enableValue: true,
          suppressHeaderMenuButton: true,
          filter: "agNumberColumnFilter",
          aggFunc: "sum",
        },
        {
          field: "total",
          enableValue: true,
          suppressHeaderMenuButton: true,
          filter: "agNumberColumnFilter",
          aggFunc: "sum",
        },
      ],
    },
  ]);
  const defaultColDef = useMemo<ColDef>(() => {
    return {
      floatingFilter: true,
      width: 120,
    };
  }, []);
  const autoGroupColumnDef = useMemo<AutoGroupColumnDef>(() => {
    return {
      width: 200,
    };
  }, []);

  const { data, loading } = useFetchJson<IOlympicData>(
    "https://www.ag-grid.com/example-assets/olympic-winners.json",
  );

  const setPivotOn = useCallback(() => {
    document.querySelector("#requiresPivot")!.className = "";
    document.querySelector("#requiresNotPivot")!.className = "hidden";
    gridRef.current!.api.setGridOption("pivotMode", true);
    setIdText("pivot", "on");
  }, []);

  const setPivotOff = useCallback(() => {
    document.querySelector("#requiresPivot")!.className = "hidden";
    document.querySelector("#requiresNotPivot")!.className = "";
    gridRef.current!.api.setGridOption("pivotMode", false);
    setIdText("pivot", "off");
  }, []);

  const setHeaderHeight = useCallback((value?: number) => {
    gridRef.current!.api.setGridOption("headerHeight", value);
    setIdText("headerHeight", value);
  }, []);

  const setGroupHeaderHeight = useCallback((value?: number) => {
    gridRef.current!.api.setGridOption("groupHeaderHeight", value);
    setIdText("groupHeaderHeight", value);
  }, []);

  const setFloatingFiltersHeight = useCallback((value?: number) => {
    gridRef.current!.api.setGridOption("floatingFiltersHeight", value);
    setIdText("floatingFiltersHeight", value);
  }, []);

  const setPivotGroupHeaderHeight = useCallback((value?: number) => {
    gridRef.current!.api.setGridOption("pivotGroupHeaderHeight", value);
    setIdText("pivotGroupHeaderHeight", value);
  }, []);

  const setPivotHeaderHeight = useCallback((value?: number) => {
    gridRef.current!.api.setGridOption("pivotHeaderHeight", value);
    setIdText("pivotHeaderHeight", value);
  }, []);

  return (
    <AgGridProvider modules={modules}>
      <div style={containerStyle}>
        <div className="example-wrapper">
          <div className="button-bar example-header">
            <table>
              <tbody>
                <tr>
                  <td className="labels">
                    pivot
                    <br />(<span id="pivot">off</span>)
                  </td>
                  <td className="buttons-container">
                    <button onClick={setPivotOn}>on</button>
                    <button onClick={setPivotOff}>off</button>
                  </td>
                </tr>
                <tr>
                  <td className="labels">
                    groupHeaderHeight
                    <br />(<span id="groupHeaderHeight">undefined</span>)
                  </td>
                  <td className="buttons-container">
                    <button onClick={() => setGroupHeaderHeight(40)}>
                      40px
                    </button>
                    <button onClick={() => setGroupHeaderHeight(60)}>
                      60px
                    </button>
                    <button onClick={() => setGroupHeaderHeight(undefined)}>
                      undefined
                    </button>
                  </td>
                  <td className="labels">
                    headerHeight
                    <br />(<span id="headerHeight">undefined</span>)
                  </td>
                  <td className="buttons-container">
                    <button onClick={() => setHeaderHeight(70)}>70px</button>
                    <button onClick={() => setHeaderHeight(80)}>80px</button>
                    <button onClick={() => setHeaderHeight(undefined)}>
                      undefined
                    </button>
                  </td>
                </tr>
                <tr id="requiresPivot" className="hidden">
                  <td className="labels">
                    pivotGroupHeaderHeight
                    <br />(<span id="pivotGroupHeaderHeight">undefined</span>)
                  </td>
                  <td className="buttons-container">
                    <button onClick={() => setPivotGroupHeaderHeight(50)}>
                      50px
                    </button>
                    <button onClick={() => setPivotGroupHeaderHeight(70)}>
                      70px
                    </button>
                    <button
                      onClick={() => setPivotGroupHeaderHeight(undefined)}
                    >
                      undefined
                    </button>
                  </td>
                  <td className="labels">
                    pivotHeaderHeight
                    <br />(<span id="pivotHeaderHeight">undefined</span>)
                  </td>
                  <td className="buttons-container">
                    <button onClick={() => setPivotHeaderHeight(60)}>
                      60px
                    </button>
                    <button onClick={() => setPivotHeaderHeight(80)}>
                      80px
                    </button>
                    <button onClick={() => setPivotHeaderHeight(undefined)}>
                      undefined
                    </button>
                  </td>
                </tr>
                <tr id="requiresNotPivot">
                  <td className="labels">
                    floatingFiltersHeight
                    <br />(<span id="floatingFiltersHeight">undefined</span>)
                  </td>
                  <td className="buttons-container">
                    <button onClick={() => setFloatingFiltersHeight(35)}>
                      35px
                    </button>
                    <button onClick={() => setFloatingFiltersHeight(55)}>
                      55px
                    </button>
                    <button onClick={() => setFloatingFiltersHeight(undefined)}>
                      undefined
                    </button>
                  </td>
                </tr>
              </tbody>
            </table>
          </div>

          <div style={gridStyle}>
            <AgGridReact<IOlympicData>
              ref={gridRef}
              rowData={data}
              loading={loading}
              columnDefs={columnDefs}
              defaultColDef={defaultColDef}
              autoGroupColumnDef={autoGroupColumnDef}
            />
          </div>
        </div>
      </div>
    </AgGridProvider>
  );
};

const root = createRoot(document.getElementById("root")!);
root.render(
  <StrictMode>
    <GridExample />
  </StrictMode>,
);
```

[Live example: Dynamic Header Height](https://www.ag-grid.com/examples/column-headers-styling/dynamic-height/reactFunctionalTs/)

## Auto Header Height

The column header row can have its height set automatically based on the content of the header cells. This is most useful when used together with [Custom Header Components](https://www.ag-grid.com/react-data-grid/column-headers-components/) or when using the `wrapHeaderText` column property.

To enable this, set `autoHeaderHeight=true` on the column definition you want to adjust the header height for. If more than one column has this property enabled, then the header row will be sized to the maximum of these columns' header cells so no content overflows.

The example below demonstrates using the `autoHeaderHeight` property in conjunction with the `wrapHeaderText` property, so that long column names are fully displayed.

- Note that the long column header names wrap onto another line.
- Try making a column smaller by dragging the resize handle on the column header, observe that the header will expand so the full header content is still visible.

#### Auto Header Height

```tsx
"use client";

import React, {
  useCallback,
  useMemo,
  useRef,
  useState,
  StrictMode,
} from "react";
import { createRoot } from "react-dom/client";
import { AgGridReact, AgGridProvider } from "ag-grid-react";
import {
  ClientSideRowModelModule,
  ColDef,
  ColGroupDef,
  GridApi,
  GridOptions,
  ModuleRegistry,
  enableDevValidations,
} from "ag-grid-community";
import { useFetchJson } from "./useFetchJson";

if (process.env.NODE_ENV !== "production") {
  enableDevValidations();
}

const modules = [ClientSideRowModelModule];

const GridExample = () => {
  const containerStyle = useMemo(() => ({ width: "100%", height: "100%" }), []);
  const gridStyle = useMemo(() => ({ height: "100%", width: "100%" }), []);

  const [columnDefs, setColumnDefs] = useState<ColDef[]>([
    { field: "athlete", headerName: "The full Name of the athlete" },
    {
      field: "age",
      headerName: "The number of Years since the athlete was born",
      initialWidth: 120,
    },
    { field: "country", headerName: "The Country the athlete was born in" },
    { field: "sport", headerName: "The Sport the athlete participated in" },
    {
      field: "total",
      headerName: "The Total number of medals won by the athlete",
    },
  ]);
  const defaultColDef = useMemo<ColDef>(() => {
    return {
      initialWidth: 200,
      wrapHeaderText: true,
      autoHeaderHeight: true,
    };
  }, []);

  const { data, loading } = useFetchJson<any>(
    "https://www.ag-grid.com/example-assets/olympic-winners.json",
  );

  return (
    <AgGridProvider modules={modules}>
      <div style={containerStyle}>
        <div style={gridStyle}>
          <AgGridReact
            rowData={data}
            loading={loading}
            columnDefs={columnDefs}
            defaultColDef={defaultColDef}
          />
        </div>
      </div>
    </AgGridProvider>
  );
};

const root = createRoot(document.getElementById("root")!);
root.render(
  <StrictMode>
    <GridExample />
  </StrictMode>,
);
```

[Live example: Auto Header Height](https://www.ag-grid.com/examples/column-headers-styling/auto-height/reactFunctionalTs/)

## Text Orientation

By default, the text label for the header is displayed horizontally, i.e. as normal readable text. To display the text in another orientation you have to provide your own CSS to change the orientation and also provide the adequate header heights using the appropriate grid property.

The following example shows how you can provide a unique look and feel to the headers. Note that:

- The header heights have all been changed via grid options:

```jsx
// Group columns
const groupHeaderHeight = 75;
// Label columns
const headerHeight = 150;

<AgGridReact
    groupHeaderHeight={groupHeaderHeight}
    headerHeight={headerHeight}
/>
```

- The grouped column header `Athlete Details` has a specific style applied to it to make it bigger. Note that the style is slightly different depending if pivoting or not:

```css
.ag-pivot-off .ag-header-group-cell {
    font-size: 50px;
}

.ag-pivot-on .ag-header-group-cell {
    font-size: 10px;
    color: green;
}
```

- The column labels have CSS applied to them so they are displayed vertically.

```css
.ag-header-cell-label {
    /* Necessary to allow for text to grow vertically */
    height: 100%;
    padding: 0;
}

.ag-header-cell-label .ag-header-cell-text {
    /* Force the width corresponding to how much width
    we need once the text is laid out vertically */
    width: 55px;
    writing-mode: vertical-lr;
    line-height: 2em;
    margin-top: 60px;
}
```

- The styling of the column labels have also been tweaked depending if pivoting or not.

```css
.ag-pivot-off .ag-header-cell-label {
    color: #8a6d3b;
}

.ag-pivot-on .ag-header-cell-label {
    color: #1b6d85;
    font-weight: bold;
}
```

#### Header Height and Text Orientation

```tsx
"use client";

import React, {
  useCallback,
  useMemo,
  useRef,
  useState,
  StrictMode,
} from "react";
import { createRoot } from "react-dom/client";
import { AgGridReact, AgGridProvider } from "ag-grid-react";
import "./styles.css";
import {
  ClientSideRowModelModule,
  ColDef,
  ColGroupDef,
  GridApi,
  GridOptions,
  ModuleRegistry,
  NumberFilterModule,
  TextFilterModule,
  enableDevValidations,
} from "ag-grid-community";
import { RowGroupingModule } from "ag-grid-enterprise";
import { IOlympicData } from "./interfaces";
import { useFetchJson } from "./useFetchJson";

if (process.env.NODE_ENV !== "production") {
  enableDevValidations();
}

const modules = [
  TextFilterModule,
  ClientSideRowModelModule,
  RowGroupingModule,
  NumberFilterModule,
];

const GridExample = () => {
  const containerStyle = useMemo(() => ({ width: "100%", height: "100%" }), []);
  const gridStyle = useMemo(() => ({ height: "100%", width: "100%" }), []);

  const [columnDefs, setColumnDefs] = useState<(ColDef | ColGroupDef)[]>([
    {
      headerName: "Athlete Details",
      children: [
        {
          field: "athlete",
          width: 150,
          suppressSizeToFit: true,
          enableRowGroup: true,
          rowGroupIndex: 0,
        },
        {
          field: "age",
          width: 90,
          minWidth: 75,
          maxWidth: 100,
          enableRowGroup: true,
        },
        {
          field: "country",
          width: 120,
          enableRowGroup: true,
        },
        {
          field: "year",
          width: 90,
          enableRowGroup: true,
        },
        { field: "sport", width: 110, enableRowGroup: true },
        {
          field: "gold",
          width: 60,
          enableValue: true,
          suppressHeaderMenuButton: true,
          suppressHeaderFilterButton: true,
          filter: "agNumberColumnFilter",
          aggFunc: "sum",
        },
        {
          field: "silver",
          width: 60,
          enableValue: true,
          suppressHeaderMenuButton: true,
          suppressHeaderFilterButton: true,
          filter: "agNumberColumnFilter",
          aggFunc: "sum",
        },
        {
          field: "bronze",
          width: 60,
          enableValue: true,
          suppressHeaderMenuButton: true,
          suppressHeaderFilterButton: true,
          filter: "agNumberColumnFilter",
          aggFunc: "sum",
        },
        {
          field: "total",
          width: 60,
          enableValue: true,
          suppressHeaderMenuButton: true,
          suppressHeaderFilterButton: true,
          filter: "agNumberColumnFilter",
          aggFunc: "sum",
        },
      ],
    },
  ]);

  const { data, loading } = useFetchJson<IOlympicData>(
    "https://www.ag-grid.com/example-assets/olympic-winners.json",
  );

  return (
    <AgGridProvider modules={modules}>
      <div style={containerStyle}>
        <div style={gridStyle}>
          <AgGridReact<IOlympicData>
            rowData={data}
            loading={loading}
            columnDefs={columnDefs}
            groupHeaderHeight={75}
            headerHeight={150}
          />
        </div>
      </div>
    </AgGridProvider>
  );
};

const root = createRoot(document.getElementById("root")!);
root.render(
  <StrictMode>
    <GridExample />
  </StrictMode>,
);
```

[Live example: Header Height and Text Orientation](https://www.ag-grid.com/examples/column-headers-styling/text-orientation/reactFunctionalTs/)
