Learn how to customise the look and feel of AG Grid using the Theming API, custom CSS, and conditional formatting.
Overview Copy Link
In this tutorial you will:
- Start with a built-in theme
- Customise theme parameters
- Add dark mode support
- Apply custom CSS for fine-tuning
- Conditionally style cells & rows
By the end, you'll have built a fully styled grid that looks like the example below, complete with both light and dark themes:
This tutorial assumes basic knowledge of AG Grid. If you haven't already, we recommend reading our Introductory Tutorial first.
Introduction to Styling Copy Link
AG Grid provides three main approaches to styling:
- Theming API: Fully-typed API for customising default themes.
- Custom CSS: Fine-grained control over specific grid elements.
- Cell/Row Styles: Data-driven formatting for individual cells and rows.
Each of these approaches can be used to customise our built-in themes: Quartz, Alpine, Balham, and Material.
Our themes are simply JavaScript objects that define colours, spacing, fonts, and other design tokens. By default, the Quartz theme is applied; to use a custom theme, create a reference to the desired theme and pass it to the grid options:
import { themeQuartz } from 'ag-grid-community';
const myTheme = themeQuartz;
const gridOptions = {
theme: myTheme,
// ... other options
};
The example below demonstrates an AG Grid data grid with an unmodified Quartz theme. Open the example in CodeSandbox or Plunkr to follow this tutorial:
Our Built-in Themes docs provide a full overview of the available themes and their features.
Customising Themes Copy Link
Themes can be customised directly using the Theming API, which provides three main features:
- Theme Parameters: Adjust colours, spacing, fonts, and other variables to create a unique theme.
- Theme Parts: Mix-and-match parts from different themes, such as light/dark schemes, inputs or icon sets.
- Theme Modes: Define multiple colour schemes (e.g. light and dark) within a single theme.
Theme Parameters Copy Link
Theme Parameters are configuration values that affect the appearance of the grid.
Some parameters, such as headerTextColor, affect a single aspect of grid appearance. Others such as spacing affect the whole grid.
To set parameters on a theme, call the theme.withParams(...) method which returns a new theme with different default values for its parameters.
For example, to customise your themes colours, spacing, and font sizes, add the following params to the themeQuartz.withParams() method:
// Custom theme with parameters
const myTheme = themeQuartz
.withParams({
backgroundColor: '#ffffff',
foregroundColor: '#1a1a1a',
headerBackgroundColor: '#faf8f5',
spacing: 10,
fontSize: 12,
headerFontSize: 14,
});
const gridOptions = {
theme: myTheme,
// ... other options
};
When you run your application, you should see the new theme applied to the grid, with slightly smaller text, and an off-white header background colour:
Our Theme Parameters docs provide a full list of available parameters and how to use them.
Theme Parts Copy Link
Theme Parts contain the CSS styles for a single feature like icons or text inputs. Using parts you can, for example, use the Material icons with the Quartz theme, or use the colourSchemeDarkBlue part to use a dark mode colour scheme.
To add a part to a theme, call the theme.withPart(...) method which returns a new theme using that part.
For example, to use the Material icon set with the Quartz theme, pass the iconSetMaterial part to the themeQuartz.withPart() method:
import { themeQuartz, iconSetMaterial } from 'ag-grid-community';
// Custom Quartz theme that uses Material icons
const myTheme = themeQuartz
.withParams({ /*...*/ })
.withPart(iconSetMaterial);
const gridOptions = {
theme: myTheme,
// ... other options
};
When you run your application, you should see the Material icons used for the Filter icon:
Our Theming Parts docs provide a full overview of the available theme parts and how to use them.
Theme Modes Copy Link
Theme Modes allow you to define multiple colour schemes within a single theme, that can be toggled dynamically using a theme-mode HTML attribute.
To use Theme Modes, you first need to create light and dark colour schemes by chaining another withParams method onto the themeQuartz object, passing an additional string parameter to name the scheme:
const myTheme = themeQuartz
.withPart(iconSetMaterial)
.withParams(
{
// Existing theme params...
},
'light' // Light scheme name, used as value of data-ag-theme-mode attribute
)
.withParams(
{
// Add dark theme params
backgroundColor: '#1e1e2f',
foregroundColor: '#e2e8f0',
headerBackgroundColor: '#2d2d44',
selectedRowBackgroundColor: 'rgba(110, 168, 254, 0.2)',
spacing: 10,
fontSize: 12,
},
'dark' // Dark scheme name, used as value of data-ag-theme-mode attribute
);
const gridOptions = {
theme: myTheme,
// ... other options
};
The active colour scheme can then be controlled by setting the data-ag-theme-mode="mode" attribute on any parent element of the grid, commonly the html or body elements:
// Index.html - Button to control colour scheme
<button id="toggle" onclick="setThemeMode()">Enable Dark Mode</button>
// Theme mode toggle logic
const toggleButton = document.querySelector<HTMLElement>('#toggle')!;
function setThemeMode() {
const isDark = document.body.dataset.agThemeMode === 'dark';
const nextMode = isDark ? 'light' : 'dark';
document.body.dataset.agThemeMode = nextMode;
toggleButton.innerText = nextMode === 'dark' ? 'Enable Light Mode' : 'Enable Dark Mode';
}
// Set initial mode
document.body.dataset.agThemeMode = 'light';
When you run your application, you should be able to toggle between light and dark modes by clicking the button:
Our Theme Modes docs provide a full overview of how to use theme modes and best practices for implementing dark mode support.
Custom CSS for Fine-Tuning Copy Link
When the Theming API doesn't provide enough control, you can use custom CSS to target specific grid elements.
Every DOM element rendered by the grid exposes a class name prefixed with .ag-. You can target these class names with your own CSS rules, allowing limitless customisation.
Finding Class Names Copy Link
Use your browser's developer tools to inspect grid elements and find the appropriate class names. Right-click on any grid element and select "Inspect" to see its classes.
Overriding CSS Styles Copy Link
Once you've identified the class names, you can write custom CSS rules to override the default styles.
Override the following CSS to style the header text with the .ag-header-cell-text class:
.ag-header-cell-text {
text-transform: uppercase;
letter-spacing: 0.05em;
font-weight: 600;
font-size: 0.85em;
}
You can also target specific columns by using the column’s field value via the col-id attribute selector.
Override the CSS for cells in the product column with the .ag-cell class and [col-id='productName'] selector:
.ag-cell[col-id='productName'] {
font-weight: 500;
}
When you run the example, you should see the styles applied to the header text and product columns:
Our Extending with CSS docs provide more information on applying custom CSS.
Conditional Formatting Copy Link
Conditional formatting allows you to dynamically apply styles to cells or rows based on their data.
There are two main approaches for applying styles based on data:
Both of these features work in the same way, allowing you to create functions that dynamically apply CSS classes to elements based on arbitrary data.
Cell Class Rules Copy Link
Class Rules are defined by passing a JavaScript map to the cellClassRules column property where the keys are the class names and the values are expressions that, when returning true, the class gets used.
These expressions access the cell's data via the params object, which includes information such as the cell value and row node.
For example, to apply different classes to cells in the status column based on their value, first define the following cellClassRules:
// Column Definition with Cell Class Rules
const columnDefs = [
{
field: 'status',
cellClassRules: {
'status-delivered': (params) => params.value === 'Delivered',
'status-pending': (params) => params.value === 'Pending',
'status-cancelled': (params) => params.value === 'Cancelled',
},
},
// Other columns...
];
Each time a cell is rendered within the status column, the cellClassRules function will be evaluated, and a CSS class applied to the cell based on its value.
To style these cells, add the corresponding classes to your CSS:
.status-delivered {
color: #2e7d32;
}
.status-pending {
color: #ed6c02;
}
.status-cancelled {
color: #d32f2f;
}
When you run your application, you should see the conditional styles applied to cells based on their data:
Our Cell Styles docs provide a full overview of how to use class rules and best practices for conditional formatting.
Row Class Rules Copy Link
Row Class Rules work similarly to Cell Class Rules, but use the rowClassRules grid option to apply styles to entire rows, rather than cells.
For example, to apply a high-sales class to rows where the salesRevenue is greater than $10,000, first, define the following rule:
const gridOptions = {
rowClassRules: {
'high-sales': params => params.data.salesRevenue > 10000,
}
};
And then add the corresponding class to your CSS:
.high-sales {
background-color: rgba(76, 175, 80, 0.15);
}
When you run your application, you should see the conditional styles applied to rows based on their data:
Our Row Styles docs provide a full overview of how to use class rules and best practices for conditional formatting.
Design Tools Copy Link
Whilst this tutorial has been focused on customising themes from within your application, we also provide tools to help both developers and designers create custom themes.
Theme Builder Copy Link
The Theme Builder is a visual tool for creating and customising themes. It allows you to:
- Customise theme parameters via a user-friendly interface.
- Preview theme changes in real-time.
- Enable/disable grid features to accurately represent your configuration.
You can then generate the resulting custom theme as code and copy it directly into your project.
Figma Design System Copy Link
The AG Grid design system replicates the Quartz and Alpine themes within Figma, allowing you to customise them with Figma variables to match your brand and style.
Figma variables can also be used with the Style Dictionary package to automatically generate an AG Grid compatible theme object. Visit our Design System docs to learn more, or download the figma file using the button below to get started.
Test Your Knowledge Copy Link
Try these challenges to reinforce what you've learned:
Change the accent colour to
#0e4491in light mode, and#6ea8fein dark modeHint: Use
withParams({ accentColor: '...' })Add a bottom border to header cells using CSS
Hint: Target
.ag-header-cellwithborder-bottom: 2px solid blueMake cell text bold where profit margin is greater than 20%
Hint: Use
cellClassRuleson the profitMargin columnHighlight rows with
rgba(244, 67, 54, 0.1)for products with revenue less than $1,000Hint: Use
rowClassRulesand checkparams.data.salesRevenue
Once complete, your grid should look like the example below. If you're stuck, check out the source code to see how it's done:
Summary Copy Link
Congratulations! You've completed the tutorial and learned how to style AG Grid using a combination of the Theming API, custom CSS, and conditional formatting.
As recap, here's a simple table summarising the different styling requirements and the recommended approaches:
| Requirement | Recommended Approach |
|---|---|
| Global colours, spacing, fonts | Theme with withParams() |
| Light/dark mode | Theme modes with data-ag-theme-mode |
| Style specific elements | Custom CSS targeting .ag-* classes |
| Cells styled based on their value | cellClassRules |
| Rows styled based on row data | rowClassRules |
Next Steps Copy Link
Explore these topics to learn more:
- Try the Theme Builder - Visual tool for creating themes
- Theming API Docs - Complete theming reference