Article
0 comment

SharePoint Framework and the Office UI Fabric grid system

A while a GitHub issue in the sp-dev-docs came to my attention, where someone had a problem titled as Can’t get grid system working using office fabric ui react. I took a closer look on why it is so challenging to get the grid system running right now and in SPFx projects in general. There are some catches you need to be aware.

Some of those issues are already documented in the a blog post on How to make your web parts responsive to the parent container or How to use Bootstrap in SharePoint Framework projects. Here is the rest of the story.

Office UI Fabric is somewhat like the first and foremost first third-party Framework that you may want to use in all your projects to create a seamless experience with the rest of the Office 365 platform. It is not exclusively to SharePoint or SharePoint Framework Projects.

My reply and solution to this issue

To apply the same CSS properties used by other classes you can call functions in SASS aka mixin. It is what happens, for example, in this class:

.row {
    @include ms-Grid-row;
    @include ms-fontColor-white;
    background-color: while;
    padding: 20px;
  }

That generates the following output:

.helloWorld_2adf359f .row_2adf359f {
  margin: 0 -8px;
  -webkit-box-sizing: border-box;
  box-sizing: border-box;
  color: "[theme:white, default: #ffffff]";
  background-color: while;
  padding: 20px
}

.helloWorld_2adf359f .row_2adf359f::after,
.helloWorld_2adf359f .row_2adf359f::before {
  display: table;
  content: '';
  line-height: 0
}

.helloWorld_2adf359f .row_2adf359f::after {
  clear: both
}

The hash at the end of the class names makes sure that one web part doesn’t overlap style definitions of another web part on the page. By no means, this doesn’t make your web part “Type-safe” because this is a “concept” by no means something CSS is aware. CSS only has a binary state attached. It works, or it doesn’t work.

To make use of the classes that got these predefined properties via the mixin. You always have to use in the React Control like this.

<div className={styles.row}>

This way, you build your grid base on the settings of the Office UI grid. This output the web part, for example, in this form.

Screenshot 2019-05-31 at 12 22 45

The black container is actually where the grid column gets assigned too. It is working in 1.8.2 by modifying the default provisioned web part with the following CSS.

@import '~@microsoft/sp-office-ui-fabric-core/dist/sass/SPFabricCore';

.helloWorld {
  .container {
    // uncommented because of invalid display max-width: 700px;
    //Before grid
    //after grid
    margin: 0px auto;
    box-shadow: 0 2px 4px 0 rgba(0, 0, 0, 0.2), 0 25px 50px 0 rgba(0, 0, 0, 0.1);
  }

  .row {
    @include ms-Grid-row;
    @include ms-fontColor-white;
    // background-color: $ms-color-themeDark;
    background-color: while;
    padding: 20px;
  }

  .column {
    @include ms-Grid-col;

    @include ms-xl6;
    @include ms-xlPush3;
    @include ms-lgPush3;
    @include ms-lg6;
    background-color: black;

    @media screen and (min-width: 1024px) and (max-width: 1365px) {
      background-color: lime;
    }
  }

  .title {
    @include ms-font-xl;
    @include ms-fontColor-white;
  }

  .subTitle {
    @include ms-font-l;
    @include ms-fontColor-white;
  }

  .description {
    @include ms-font-l;
    @include ms-fontColor-white;
  }

  .button {
    // Our button
    text-decoration: none;
    height: 32px;

    // Primary Button
    min-width: 80px;
    background-color: $ms-color-themePrimary;
    border-color: $ms-color-themePrimary;
    color: $ms-color-white;

    // Basic Button
    outline: transparent;
    position: relative;
    font-family: "Segoe UI WestEuropean", "Segoe UI", -apple-system, BlinkMacSystemFont, Roboto, "Helvetica Neue", sans-serif;
    -webkit-font-smoothing: antialiased;
    font-size: $ms-font-size-m;
    font-weight: $ms-font-weight-regular;
    border-width: 0;
    text-align: center;
    cursor: pointer;
    display: inline-block;
    padding: 0 16px;

    .label {
      font-weight: $ms-font-weight-semibold;
      font-size: $ms-font-size-m;
      height: 32px;
      line-height: 32px;
      margin: 0 4px;
      vertical-align: top;
      display: inline-block;
    }
  }
}

The workaround you did use :global is the only option if you like to use the Office UI Fabric grid classes in a web part. I guess you have used it like this in your code:

.helloWorld {

  :global{
    @import 'node_modules/office-ui-fabric-react/dist/css/fabric.css';
  }

The downside of this approach is that you get everything from Office UI Fabric included not only the grid system.


Besides those technical challenges, there are additional web design considerations to take into account using a grid in SPFx. Depending on where you place your web part on a page. The usage of the grid might be wrong.

Screenshot 2019-05-31 at 13 19 22

The result might look like this with multiple versions of a 12 grid on every web part, while grid systems should be used on a page but not in components such as a web part.

I don’t use a grid in web parts at all because of the known limitations. There are better options in the world, such as Flexbox and Grid Systems supported in CSS. Grid System right now not supported for IE11.

More to know: