SLDS Styling in LWC – Clean UI Practices

LWC uses Shadow DOM for encapsulation, but SLDS remains the recommended styling approach for clean Salesforce UI. Learn how to build polished, consistent component layouts.

1. Component CSS Files

Each LWC component has its own CSS file. Styles are automatically scoped to that component.

Component Structure


myComponent/
  myComponent.html
  myComponent.js
  myComponent.css
  

CSS File


/* myComponent.css */
.button-primary {
    background-color: #0076d6;
    color: white;
    padding: 10px 20px;
    border: none;
    border-radius: 4px;
    cursor: pointer;
}

.button-primary:hover {
    background-color: #004a9e;
}

.card {
    border: 1px solid #e0e0e0;
    border-radius: 4px;
    padding: 20px;
    margin-bottom: 20px;
}

.card-title {
    font-size: 18px;
    font-weight: bold;
    margin-bottom: 10px;
}

.card-body {
    font-size: 14px;
    color: #333;
}
  

HTML Using Styles


<template>
    <div class="card">
        <h3 class="card-title">Account Details</h3>
        <div class="card-body">
            <p>Name: {account.Name}</p>
            <p>Phone: {account.Phone}</p>
        </div>
    </div>
    
    <button class="button-primary" onclick={handleClick}>
        Save
    </button>
</template>
  

2. Shadow DOM Encapsulation

CSS inside a component doesn't affect parent/sibling components, and vice versa.

✅ Benefits of Encapsulation


/* Parent component CSS - doesn't affect child */
.card {
    border: 3px solid red;
}

<template>
    <c-child-component></c-child-component>
</template>

/* Child component CSS - stays scoped */
.card {
    border: 1px solid blue;  /* This takes precedence in child */
}
  

3. Using Lightning Design System (SLDS)

LWC integrates with SLDS for consistent Salesforce styling:


<template>
    <div class="slds-box slds-var-m-around_medium">
        <h2 class="slds-var-text-heading_large">Account</h2>
        
        <div class="slds-form">
            <div class="slds-form-element">
                <label class="slds-form-element__label">Name</label>
                <div class="slds-form-element__control">
                    <input type="text" class="slds-input" />
                </div>
            </div>
        </div>

        <button class="slds-button slds-button_brand">
            Save
        </button>
    </div>
</template>
  

4. Dynamic Styling

Conditional Classes


<template>
    <button 
        class={buttonClass}
        onclick={handleClick}>
        Click me
    </button>
</template>

// JavaScript
export default class ButtonComponent extends LightningElement {
    isActive = false;

    get buttonClass() {
        return this.isActive ? 'slds-button slds-button_brand' : 'slds-button';
    }

    handleClick() {
        this.isActive = !this.isActive;
    }
}
  

Inline Styles


<template>
    <div style={boxStyle}>
        Dynamic styled content
    </div>
</template>

export default class DynamicStyleComponent extends LightningElement {
    backgroundColor = '#f5f5f5';
    padding = '20px';

    get boxStyle() {
        return `background-color: ${this.backgroundColor}; padding: ${this.padding};`;
    }
}
  

5. Communicating with Parent Styles

Use CSS custom properties to allow parents to style children:

Child Component


/* childComponent.css */
.container {
    background-color: var(--container-bg, white);
    color: var(--container-color, black);
    padding: var(--container-padding, 10px);
}
  

Parent Component


/* parentComponent.css */
c-child-component {
    --container-bg: #e8f4f8;
    --container-color: #003366;
    --container-padding: 20px;
}
  

6. Styling Best Practices

Use SLDS Variables


/* Good - use SLDS spacing */
.card {
    padding: var(--lwc-spacing_medium);  /* 1rem */
    margin-bottom: var(--lwc-spacing_large);  /* 1.5rem */
}

.title {
    font-size: var(--lwc-fontSize_heading_large);
    color: var(--lwc-colorTextDefault);
}
  

Avoid Deep Styling


/* ❌ Don't try to style child components from parent */
.child-component .card {
    /* This won't work due to Shadow DOM */
}

/* ✅ Pass CSS variables instead */
.parent {
    --card-border: 2px solid red;
}

/* In child component CSS */
.card {
    border: var(--card-border, 1px solid gray);
}
  

7. Responsive Design


/* Component CSS */
.grid {
    display: grid;
    grid-template-columns: repeat(auto-fit, minmax(300px, 1fr));
    gap: 20px;
}

.card {
    padding: 20px;
    border: 1px solid #e0e0e0;
}

@media (max-width: 768px) {
    .grid {
        grid-template-columns: 1fr;
    }

    .card {
        padding: 15px;
    }
}
  

8. Common Styling Patterns

Flex Layout


.container {
    display: flex;
    justify-content: space-between;
    align-items: center;
    gap: 10px;
}

.sidebar {
    flex: 0 0 250px;  /* Fixed width */
}

.content {
    flex: 1;  /* Take remaining space */
}
  

Grid Layout


.form {
    display: grid;
    grid-template-columns: 1fr 1fr;
    gap: 15px;
}

.form-row {
    grid-column: span 2;  /* Full width */
}

@media (max-width: 768px) {
    .form {
        grid-template-columns: 1fr;
    }

    .form-row {
        grid-column: span 1;
    }
}
  

Key Takeaways