How to get CSS styles to work in a Fluent UI React Panel control

Sometimes this should be obvious and they just aren’t. I use the Panel component in Fluent UI React / Office Fabric from time to time. I’ve always struggled to work with styles there coming out of my web part’s module.scss file. That’s because they simply aren’t being applied.

Let’s look at this simple example web part:

import * as React from "react";
import { override } from "@microsoft/decorators";
import styles from './MyWebPart.module.scss';
import { Panel, PanelType } from 'office-ui-fabric-react/lib/Panel';


export default class ReportPanel extends React.Component<IMyWebPartProps, {
    showPanel: boolean
}> {

    constructor(props: IMyWebPartProps) {
        super(props);

        this.setState({
            showPanel: true
        });
    }


    @override
    public render(): React.ReactElement<{}> {
        return (
            <React.Fragment>
                <div className={styles.myWebPart}>
                    <Panel isOpen={this.state.showPanel}  onDismiss={() => { this.setState({ showPanel: false }); }} headerText={'My Panel Header'}>
                            <p className={styles.panelBody}>
                                Some text
                            </p>
                            <p className={styles.title}>
                                Page Analytics
                            </p>
                    </Panel>
                </div>
            </React.Fragment>);
    }
}

Note we have two styles in the body of the panel named panelBody and title. Here’s what our module.scss looks like:

@import '~office-ui-fabric-react/dist/sass/References.scss';

.myWebPart {
  .title {
        @include ms-font-l;
    }

  .panelBody {
        margin-top: 10px;
        margin-bottom: 10px;
    }

}

We would expect that our panelBody and title styles would be applied normally. That’s not he case though. Think of the panel as a whole new surface. That means you need to wrap your panel contents in a top-level div element first. You can use the same top level style as your web part, but you could probably create a new one if you wanted as well. Here’s the updated code snippet:

import * as React from "react";
import { override } from "@microsoft/decorators";
import styles from './MyWebPart.module.scss';
import { Panel, PanelType } from 'office-ui-fabric-react/lib/Panel';


export default class ReportPanel extends React.Component<IMyWebPartProps, {
    showPanel: boolean
}> {

    constructor(props: IMyWebPartProps) {
        super(props);

        this.setState({
            showPanel: true
        });
    }


    @override
    public render(): React.ReactElement<{}> {
        return (
            <React.Fragment>
                <div className={styles.myWebPart}>
                    <Panel isOpen={this.state.showPanel} isBlocking={false} type={PanelType.smallFixedFar} onDismiss={() => { this.setState({ showPanel: false }); }} headerText={'My Panel Header'}>
                        <div className={styles.myWebPart}>
                            <p className={styles.panelBody}>
                                Some text
                            </p>
                            <p className={styles.title}>
                                Page Analytics
                            </p>
                        </div>
                    </Panel>
                </div>
            </React.Fragment>);
    }
}

I suspected something like this was always the cause. Finally I found some validation in it. This issue was opened a few years ago. It was quickly closed because the Fluent teams doesn’t seem to use SPFx much even though SPFx developers are some of the largest users of Fluent. I suspect this also applies to other surface like Modal.

Published by coreyroth

Corey Roth is the Vice President of Product Strategy at AvePoint where he helps build the tyGraph product line for data analytics in Microsoft 365. Corey is an thirteen-time recipient of the Microsoft MVP award in Office Apps and Services. Corey has always focused on rapid adoption of new Microsoft technologies including Microsoft 365 and Azure.

Leave a comment