How to Add Custom Styling to a Standard Lightning Datatable in LWC

How to Add Custom Styling to a Standard Lightning Datatable in Salesforce Lightning Web Component (LWC)

Lightning Web Components (LWC) allow us to build powerful and modern web applications on the Salesforce platform. However, LWC does not provide any attribute out of the box for custom styling of datatables. Customizing the look and feel of standard components, such as the lightning-datatable, can be challenging. It is especially complex when it comes to applying custom styles.

In this post, we will guide you through how to add custom styling to a standard datatable. We will change the background color of specific rows. This change will be based on a condition.

Use Case: Applying Custom Colors Based on Account Revenue Ranges

Let’s assume you’re displaying a list of accounts and want to highlight each row differently based on the account’s annual revenue:

  • Accounts with revenue below $10,000,000 will have a red background.
  • Accounts with revenue between $10,000,000 and $50,000,000 will have a yellow background.
  • Accounts with revenue greater than $50,000,000 will have a green background.

We’ll walk through an example where custom styles are loaded from a static resource. These styles are then applied conditionally to the rows in the Datatable in LWC.

Custom Styling in Standard Lightning Data Table in LWC

Step-by-Step Guide

Step 1: Set Up Static Resource for CSS

Create a CSS file that contains the custom styles. Upload this CSS file to Salesforce as a static resource.

customDTStyle.css

.dtRevenueStyleGreen {
  color: #fff;
  background-color: lightseagreen !important;
  overflow-wrap: break-word;
  white-space: pre-line;
}

.dtRevenueStyleRed {
  color: #fff;
  background-color: red !important;
  overflow-wrap: break-word;
  white-space: pre-line;
}

.dtRevenueStyleYellow {
  color: black;
  background-color: yellow !important;
  overflow-wrap: break-word;
  white-space: pre-line;
}
Step 2: Upload the CSS file in the Static Resource
  1. Navigate to Setup > Static Resources.
  2. Create a new static resource with name “customDTStyle”.
  3. Upload the customDTStyle.css file.

Step 3: Set Up the Lightning Web Component

Create your Lightning Web Component. Here’s the basic structure of the accountList component:

accountList.html

<template>
    <div class="myTable">
        <lightning-card title="Account List">
            <template if:true={showSpinner}>
                <lightning-spinner alternative-text="Loading"></lightning-spinner>
            </template>
            <template if:false={showSpinner}>
                <lightning-datatable key-field="Id" data={displayAccList} columns={columns} hide-checkbox-column></lightning-datatable>
            </template>
        </lightning-card>
    </div>
</template>

accountList.js

import { LightningElement, track } from 'lwc';
import getAccounts from '@salesforce/apex/AccountController.getAccounts';
import { loadStyle } from 'lightning/platformResourceLoader';
import CUSTOM_DT_STYLE from '@salesforce/resourceUrl/customDTStyle';

const columns = [
    { 
        label: 'Account Name', 
        fieldName: 'Name', 
        type: 'text',
        cellAttributes: { class: { fieldName: 'revenueClass' }, },
        hideDefaultActions: true 
    },
    { 
        label: 'Annual Revenue', 
        fieldName: 'AnnualRevenue', 
        type: 'currency',
        cellAttributes: { class: { fieldName: 'revenueClass' }, alignment: 'left' },
        hideDefaultActions: true 
    }
];

export default class AccountList extends LightningElement {
    @track columns = columns;
    @track displayAccList = [];
    @track sortBy = 'AnnualRevenue';
    @track sortDirection = 'desc';
    showSpinner = true;
    isCssLoaded = false;

    renderedCallback() {
        if (this.isCssLoaded) return;
        this.isCssLoaded = true;
        loadStyle(this, CUSTOM_DT_STYLE).then(() => {
            console.log("Loaded Successfully");
        }).catch(error => {
            console.error("Error in loading the colors", error);
        });
    }

    async connectedCallback() {
        await this.loadAccounts();
    }

    async loadAccounts() {
        debugger;
        try {
            await this.delay(1000);
            const result = await getAccounts();
            if (result) {
                let accounts = JSON.parse(JSON.stringify(result));
                accounts.forEach(acc => {
                    // Check if the 'AnnualRevenue' attribute exists, if not, set it to 0
                    if (!('AnnualRevenue' in acc) || acc.AnnualRevenue === null) {
                        acc.AnnualRevenue = 0; // Set to 0 if not present or null
                    }
                    acc.revenueClass = acc.AnnualRevenue < 10000000 ? 'dtRevenueStyleRed' : 
                   (acc.AnnualRevenue >= 10000000 && acc.AnnualRevenue <= 50000000) ? 'dtRevenueStyleYellow' : 
                   'dtRevenueStyleGreen';
                });

                // Separate top five accounts
                const topFive = accounts.slice(0, 5);
                const rest = accounts.slice(5);

                this.displayAccList = [...topFive, ...rest];
            }
        } catch (error) {
            console.error("Error in loadAccounts:", error);
        } finally {
            this.showSpinner = false;
        }
    }

    delay(ms) {
        return new Promise(resolve => setTimeout(resolve, ms));
    }
}

accountList.js-meta.xml

<?xml version="1.0" encoding="UTF-8"?>
<LightningComponentBundle xmlns="http://soap.sforce.com/2006/04/metadata">
    <apiVersion>62.0</apiVersion>
    <isExposed>true</isExposed>
    <targets>
        <target>lightning__HomePage</target>
    </targets>
</LightningComponentBundle>
Key Highlights
  • Dynamic CSS Loading: We use loadStyle to load the customDTStyle.css file from the static resource. This is done in the renderedCallback, ensuring that the styles are applied only after the component renders.
  • Conditional Styling: By using the cellAttributes property “revenueClass” in the datatable, we can apply dynamic styling. This styling will be based on the revenue amount of the accounts.

Apex Class

public with sharing class AccountController {
    @AuraEnabled(cacheable=true)
    public static List<Account> getAccounts() {
        return [SELECT Id, Name, AnnualRevenue FROM Account ORDER BY AnnualRevenue DESC NULLS LAST LIMIT 20 ];
    }
}
Demo:
Reference

SFDC Data Table Documentation

Leave a comment