Style grid header cells and column groups.
The grid exposes many theme parameters starting header* for customising header appearance:
const myTheme = themeQuartz.withParams({
headerHeight: '30px',
headerTextColor: 'white',
headerBackgroundColor: 'black',
headerCellHoverBackgroundColor: 'rgba(80, 40, 140, 0.66)',
headerCellMovingBackgroundColor: 'rgb(80, 40, 140)',
});For the full list, see the Headers section of the parameters reference.
When the theme parameters are not enough you can use CSS classes, in particular ag-header, ag-header-cell, and ag-header-group-cell:
.ag-header {
font-family: cursive;
}
.ag-header-group-cell {
font-weight: normal;
font-size: 22px;
}
.ag-header-cell {
font-size: 18px;
}import {
createApp,
defineComponent,
onBeforeMount,
ref,
shallowRef,
} from "vue";
import { AgGridVue } from "ag-grid-vue3";
import "./styles.css";
import {
ColDef,
ColGroupDef,
GridApi,
GridOptions,
GridReadyEvent,
ModuleRegistry,
Theme,
enableDevValidations,
themeQuartz,
} from "ag-grid-community";
import { AllEnterpriseModule } from "ag-grid-enterprise";
import { IOlympicData } from "./interfaces";
if (process.env.NODE_ENV !== "production") {
// Enable extended validations only for development
enableDevValidations();
}
ModuleRegistry.registerModules([AllEnterpriseModule]);
const myTheme = themeQuartz.withParams({
headerHeight: "30px",
headerTextColor: "white",
headerBackgroundColor: "black",
headerCellHoverBackgroundColor: "rgba(80, 40, 140, 0.66)",
headerCellMovingBackgroundColor: "rgb(80, 40, 140)",
});
const VueExample = defineComponent({
template: `
<div style="height: 100%">
<ag-grid-vue
style="width: 100%; height: 100%;"
@grid-ready="onGridReady"
:theme="theme"
:columnDefs="columnDefs"
:defaultColDef="defaultColDef"
:rowData="rowData"></ag-grid-vue>
</div>
`,
components: {
"ag-grid-vue": AgGridVue,
},
setup(props) {
const gridApi = shallowRef<GridApi<IOlympicData> | null>(null);
const theme = ref<Theme | "legacy">(myTheme);
const columnDefs = ref<(ColDef | ColGroupDef)[]>([
{
headerName: "Group 1",
children: [{ field: "athlete", minWidth: 170 }, { field: "age" }],
},
{
headerName: "Group 2",
children: [
{ field: "country" },
{ field: "year" },
{ field: "date" },
{ field: "sport" },
{ field: "gold" },
{ field: "silver" },
{ field: "bronze" },
{ field: "total" },
],
},
]);
const defaultColDef = ref<ColDef>({
editable: true,
filter: true,
});
const rowData = ref<IOlympicData[]>(null);
const onGridReady = (params: GridReadyEvent) => {
gridApi.value = params.api;
const updateData = (data) => (rowData.value = data);
fetch("https://www.ag-grid.com/example-assets/olympic-winners.json")
.then((resp) => resp.json())
.then((data) => updateData(data));
};
return {
gridApi,
theme,
columnDefs,
defaultColDef,
rowData,
onGridReady,
};
},
});
const app = createApp(VueExample);
app.mount("#app");
.ag-header {
font-family: cursive;
}
.ag-header-group-cell {
font-weight: normal;
font-size: 22px;
}
.ag-header-cell {
font-size: 18px;
}
Header Column Borders and Resize Handles Copy Link
Header Column Borders appear between every column, whereas Resize Handles only appear on resizeable columns (Group 1 in the example below).
const myTheme = themeQuartz.withParams({
headerColumnBorder: { color: 'purple' },
headerColumnBorderHeight: '80%',
headerColumnResizeHandleColor: 'orange',
headerColumnResizeHandleHeight: '25%',
headerColumnResizeHandleWidth: '5px',
});import {
createApp,
defineComponent,
onBeforeMount,
ref,
shallowRef,
} from "vue";
import { AgGridVue } from "ag-grid-vue3";
import {
ColDef,
ColGroupDef,
GridApi,
GridOptions,
GridReadyEvent,
ModuleRegistry,
Theme,
enableDevValidations,
themeQuartz,
} from "ag-grid-community";
import { AllEnterpriseModule } from "ag-grid-enterprise";
import { IOlympicData } from "./interfaces";
if (process.env.NODE_ENV !== "production") {
// Enable extended validations only for development
enableDevValidations();
}
ModuleRegistry.registerModules([AllEnterpriseModule]);
const myTheme = themeQuartz.withParams({
headerColumnBorder: { color: "purple" },
headerColumnBorderHeight: "80%",
headerColumnResizeHandleColor: "orange",
headerColumnResizeHandleHeight: "25%",
headerColumnResizeHandleWidth: "5px",
});
const VueExample = defineComponent({
template: `
<div style="height: 100%">
<ag-grid-vue
style="width: 100%; height: 100%;"
@grid-ready="onGridReady"
:theme="theme"
:columnDefs="columnDefs"
:defaultColDef="defaultColDef"
:rowData="rowData"></ag-grid-vue>
</div>
`,
components: {
"ag-grid-vue": AgGridVue,
},
setup(props) {
const gridApi = shallowRef<GridApi<IOlympicData> | null>(null);
const theme = ref<Theme | "legacy">(myTheme);
const columnDefs = ref<(ColDef | ColGroupDef)[]>([
{
headerName: "Group 1",
children: [
{ field: "athlete", minWidth: 170, resizable: true },
{ field: "age", resizable: true },
],
resizable: true,
},
{
headerName: "Group 2",
children: [
{ field: "country" },
{ field: "year" },
{ field: "date" },
{ field: "sport" },
{ field: "gold" },
{ field: "silver" },
{ field: "bronze" },
{ field: "total" },
],
},
]);
const defaultColDef = ref<ColDef>({
editable: true,
filter: true,
resizable: false,
});
const rowData = ref<IOlympicData[]>(null);
const onGridReady = (params: GridReadyEvent) => {
gridApi.value = params.api;
const updateData = (data) => (rowData.value = data);
fetch("https://www.ag-grid.com/example-assets/olympic-winners.json")
.then((resp) => resp.json())
.then((data) => updateData(data));
};
return {
gridApi,
theme,
columnDefs,
defaultColDef,
rowData,
onGridReady,
};
},
});
const app = createApp(VueExample);
app.mount("#app");
Style Header on Filter Copy Link
Each time a Column Filter is applied to a column, the CSS class ag-header-cell-filtered is added to the header. This can be used for adding style to headers that are filtered.
The example below adds some styling to ag-header-cell-filtered, so when you filter a column you will notice the column header change.
import {
createApp,
defineComponent,
onBeforeMount,
ref,
shallowRef,
} from "vue";
import { AgGridVue } from "ag-grid-vue3";
import "./styles.css";
import {
AllCommunityModule,
ColDef,
ColGroupDef,
GridApi,
GridOptions,
GridReadyEvent,
GridState,
ModuleRegistry,
enableDevValidations,
} from "ag-grid-community";
import { IOlympicData } from "./interfaces";
if (process.env.NODE_ENV !== "production") {
// Enable extended validations only for development
enableDevValidations();
}
ModuleRegistry.registerModules([AllCommunityModule]);
const VueExample = defineComponent({
template: `
<div style="height: 100%">
<ag-grid-vue
style="width: 100%; height: 100%;"
@grid-ready="onGridReady"
:columnDefs="columnDefs"
:defaultColDef="defaultColDef"
:initialState="initialState"
:rowData="rowData"></ag-grid-vue>
</div>
`,
components: {
"ag-grid-vue": AgGridVue,
},
setup(props) {
const gridApi = shallowRef<GridApi<IOlympicData> | null>(null);
const columnDefs = ref<ColDef[]>([
{ field: "athlete" },
{ field: "age", maxWidth: 120 },
{ field: "country" },
{ field: "year", maxWidth: 120 },
{ field: "sport" },
{ field: "gold" },
{ field: "silver" },
{ field: "bronze" },
{ field: "total" },
]);
const defaultColDef = ref<ColDef>({
flex: 1,
minWidth: 150,
filter: true,
});
const initialState = ref<GridState>({
filter: {
filterModel: {
country: {
filterType: "text",
type: "contains",
filter: "us",
},
},
},
});
const rowData = ref<IOlympicData[]>(null);
const onGridReady = (params: GridReadyEvent) => {
gridApi.value = params.api;
const updateData = (data) => (rowData.value = data);
fetch("https://www.ag-grid.com/example-assets/olympic-winners.json")
.then((resp) => resp.json())
.then((data) => updateData(data));
};
return {
gridApi,
columnDefs,
defaultColDef,
initialState,
rowData,
onGridReady,
};
},
});
const app = createApp(VueExample);
app.mount("#app");
.ag-header-cell-filtered {
background-color: #1b6d8544;
}
Styling the First and Last Columns Copy Link
You can style all first and last column headers (Grouped, Non-Grouped and Floating Filters) using CSS by targeting the .ag-column-first and .ag-column-last selectors as follows:
.ag-header-group-cell.ag-column-first {
background-color: #2244cc66; /* bluest */
}
.ag-header-cell.ag-column-first {
background-color: #2244cc44; /* bluer */
}
.ag-floating-filter.ag-column-first {
background-color: #2244cc22; /* blue */
}
.ag-header-group-cell.ag-column-last {
background-color: #33cc3366; /* greenest */
}
.ag-header-cell.ag-column-last {
background-color: #33cc3344; /* greener */
}
.ag-floating-filter.ag-column-last {
background-color: #33cc3322; /* green */
}import {
createApp,
defineComponent,
onBeforeMount,
ref,
shallowRef,
} from "vue";
import { AgGridVue } from "ag-grid-vue3";
import "./styles.css";
import {
AllCommunityModule,
ColDef,
ColGroupDef,
GridApi,
GridOptions,
GridReadyEvent,
ModuleRegistry,
enableDevValidations,
} from "ag-grid-community";
import { IOlympicData } from "./interfaces";
if (process.env.NODE_ENV !== "production") {
// Enable extended validations only for development
enableDevValidations();
}
ModuleRegistry.registerModules([AllCommunityModule]);
const VueExample = defineComponent({
template: `
<div style="height: 100%">
<ag-grid-vue
style="width: 100%; height: 100%;"
@grid-ready="onGridReady"
:columnDefs="columnDefs"
:defaultColDef="defaultColDef"
:rowData="rowData"></ag-grid-vue>
</div>
`,
components: {
"ag-grid-vue": AgGridVue,
},
setup(props) {
const gridApi = shallowRef<GridApi<IOlympicData> | null>(null);
const columnDefs = ref<(ColDef | ColGroupDef)[]>([
{
headerName: "Athlete Details",
children: [
{ field: "athlete" },
{ field: "age", maxWidth: 120 },
{ field: "country" },
],
},
{ field: "year", maxWidth: 100 },
{
headerName: "Sport Details",
children: [
{ field: "total", columnGroupShow: "closed" },
{ field: "gold", columnGroupShow: "open" },
{ field: "silver", columnGroupShow: "open" },
{ field: "bronze", columnGroupShow: "open" },
],
},
]);
const defaultColDef = ref<ColDef>({
flex: 1,
minWidth: 150,
filter: true,
floatingFilter: true,
});
const rowData = ref<IOlympicData[]>(null);
const onGridReady = (params: GridReadyEvent) => {
gridApi.value = params.api;
const updateData = (data) => (rowData.value = data);
fetch("https://www.ag-grid.com/example-assets/olympic-winners.json")
.then((resp) => resp.json())
.then((data) => updateData(data));
};
return {
gridApi,
columnDefs,
defaultColDef,
rowData,
onGridReady,
};
},
});
const app = createApp(VueExample);
app.mount("#app");
.ag-header-group-cell.ag-column-first {
background-color: #2244cc66; /* bluest */
}
.ag-header-cell.ag-column-first {
background-color: #2244cc44; /* bluer */
}
.ag-floating-filter.ag-column-first {
background-color: #2244cc22; /* blue */
}
.ag-header-group-cell.ag-column-last {
background-color: #33cc3366; /* greenest */
}
.ag-header-cell.ag-column-last {
background-color: #33cc3344; /* greener */
}
.ag-floating-filter.ag-column-last {
background-color: #33cc3322; /* green */
}