Friday, May 1, 2020

Lightning Web Components: Custom Styling in Inner Web Elements

How to do custom styling in LWC?

Let say a developer needs to set height and width of lightning-textarea. However facing trouble in setting it with the conventional manner, like below:

customStylingCompLWC.html

<template>
    <lightning-card title="Custom Styling Component LWC">
        <lightning-layout>
            <lightning-layout-item>
               <lightning-textarea name="input2" label="Textarea field with a predefined value" value="initial value" class="customTextarea"></lightning-textarea>  
            </lightning-layout-item>
        </lightning-layout>
    </lightning-card>
</template>

customStylingCompLWC.css

.customTextarea .slds-form-element{
    background-color: red;
    min-height: 150px;
    min-width: 300px;
    display: inline-block;
}

Preview:


Now the question is, why the custom styling is not working as expected.

If you look at the DOM, its clearly shown that "customTextarea" class is added to wrapper component. So even if you increase the height, the height of inner element wont be changed. It will be changed only on wrapper component.  
Also if you perform something like:

.customTextarea .slds-textarea{
    height: 150px;
}

Unlike Aura Component, this wont work in LWC. Because inner element is closed in Shadow DOM.

Now how to achieve custom styling in LWC? 

Custom Styling is still achievable. However there are certain work around we have to perform. So if you notice the DOM, you will understand that the style is always loaded at the time of page load. And we know it that if we load our custom style at the time of loading only then it can work.
So here you are:

Steps:
1. Load your custom css file in Static Resource.
2. import your file in your js controller.
3. load your style in connected callback().

Example:

customStylingComponentLWC.js

import { LightningElement } from 'lwc';
import { loadStyle } from 'lightning/platformResourceLoader';
import CSS_FILE from '@salesforce/resourceUrl/customStylingCSS';

export default class CustomStylingComponentLWC extends LightningElement {
    connectedCallback() {
        loadStyle(this, CSS_FILE)
        .then(() => {});
    }
}

customStylingCSS (static resource)

.slds-textarea{
    background-color: red;
    min-height: 150px;
    min-width: 300px;
    display: inline-block;
}

Preview:


** components are created as a part of proof of concept. it can be modified and optimized as per requirement.**


References: