Sp-dev-docs: Can't get grid system working using office fabric ui react

Created on 24 May 2019  路  9Comments  路  Source: SharePoint/sp-dev-docs

Category

  • [x ] Question

CSS classes aren't being applied to my app:
image

app.module.scss:
@import "~@microsoft/sp-office-ui-fabric-core/dist/sass/SPFabricCore.scss";

package.json:

{
  "name": "resource-directory",
  "version": "0.0.1",
  "private": true,
  "engines": {
    "node": ">=0.10.0"
  },
  "scripts": {
    "build": "gulp bundle",
    "clean": "gulp clean",
    "test": "gulp test"
  },
  "dependencies": {
    "@microsoft/rush-stack-compiler-3.3": "^0.2.13",
    "@microsoft/sp-core-library": "1.8.1",
    "@microsoft/sp-lodash-subset": "1.8.1",
    "@microsoft/sp-office-ui-fabric-core": "^1.8.2",
    "@microsoft/sp-property-pane": "1.8.1",
    "@microsoft/sp-webpart-base": "1.8.1",
    "@types/es6-promise": "0.0.33",
    "@types/react": "16.4.2",
    "@types/react-dom": "16.0.5",
    "@types/webpack-env": "1.13.1",
    "immer": "^3.1.2",
    "jest": "^24.8.0",
    "office-ui-fabric-react": "^6.185.0",
    "react": "16.7.0",
    "react-dom": "16.7.0",
    "testcafe": "^1.1.4"
  },
  "resolutions": {
    "@types/react": "16.4.2"
  },
  "devDependencies": {
    "@microsoft/sp-build-web": "1.8.1",
    "@microsoft/sp-tslint-rules": "1.8.1",
    "@microsoft/sp-module-interfaces": "1.8.1",
    "@microsoft/sp-webpart-workbench": "1.8.1",
    "gulp": "~3.9.1",
    "@types/chai": "3.4.34",
    "@types/mocha": "2.2.38",
    "ajv": "~5.2.2"
  }
}

component/tasks.tsx:


import * as React from "react";
import { Resources, ResourceItem } from "./../ResourceDirectory";
import {
  DocumentCard,
  DocumentCardActivity,
  DocumentCardDetails,
  DocumentCardPreview,
  DocumentCardTitle,
  IDocumentCardPreviewProps
} from "office-ui-fabric-react/lib/DocumentCard";

const ResourceCard = ({ resources }) => {
  return (
    <div className="ms-DocumentCardPreview root-127">
      <div>
        <ul className="">
          {resources.map((r: any) => (
            <li key={r.Title}>
              <div className="ms-Image">
                <img
                  className="ms-Image-image ms-Image-image--portrait is-notLoaded is-fadeIn image-134"
                  role="presentation"
                  alt=""
                />
              </div>
              <a href={r.Link} className="ms-Link">
                {r.Title}
              </a>
            </li>
          ))}
        </ul>
      </div>
    </div>
  );
};

export const Tasks = ({ resources }) => {
  // Parse resources into cards
  const uniqueLetters: string[] = [
    ...new Set(resources.map((x: ResourceItem) => x.Title.charAt(0)))
  ].sort() as string[];

  // Render out letter cards
  const getResourcesByLetter = (letter: any) => {
    const resourceItems: IDocumentCardPreviewProps[] = resources.filter(
      (resource: any) => resource.Title.charAt(0) === letter
    );

    return resourceItems;
  };

  return (
    <div className={`task-letter-container ${styles["ms-Grid"]}`}>
      <div className="ms-Grid-row">
        {uniqueLetters.map(letter => {
          return (
            <DocumentCard className="ms-Grid-col ms-sm-12 ms-md-4" key={letter}>
              <DocumentCardTitle title={`Letter: ${letter}`} />
              <ResourceCard resources={getResourcesByLetter(letter)} />
            </DocumentCard>
          );
        })}
      </div>
    </div>
  );
};

fluent-ui spfx-general answered question

Most helpful comment

@StfBauer Many thanks for your detailed explanation. Referring to your comments and taking a second look at my web part is trying to achieve, I agree that ms-Grid in the web part is not the best approach, and I will rewrite.

As a quick fix I can confirm the following suggestion works

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

Many thanks again for your explanation.

All 9 comments

Thank you for reporting this issue. We will be triaging your incoming issue as soon as possible.

@simkessy Can you please share in addition the CSS/SCSS File you used too?

Hi,

@simkessy Can you please share in addition the CSS/SCSS File you used too?

Me too, please can you let me know a fix / workaround.

This is quite critical as we have a web part that heavily uses the ms-Grid layout

Here is my package.json file:

`
{
"name": "testwebpart",
"version": "0.0.1",
"private": true,
"engines": {
"node": ">=0.10.0"
},
"scripts": {
"build": "gulp bundle",
"clean": "gulp clean",
"test": "gulp test"
},
"dependencies": {
"@microsoft/sp-core-library": "1.8.2",
"@microsoft/sp-lodash-subset": "1.8.2",
"@microsoft/sp-office-ui-fabric-core": "1.8.2",
"@microsoft/sp-webpart-base": "1.8.2",
"@pnp/common": "1.3.2",
"@pnp/logging": "1.3.2",
"@pnp/odata": "1.3.2",
"@pnp/sp": "1.3.2",
"@pnp/spfx-property-controls": "1.15.0",
"@types/es6-promise": "0.0.33",
"@types/react": "16.7.22",
"@types/react-dom": "16.8.0",
"@types/webpack-env": "1.13.1",
"moment": "^2.24.0",
"react": "16.7.0",
"react-dom": "16.7.0",
"office-ui-fabric-react": "6.143.0"
},
"resolutions": {
"@types/react": "16.7.22"
},
"devDependencies": {
"@microsoft/sp-build-web": "1.8.2",
"@microsoft/sp-module-interfaces": "1.8.2",
"@microsoft/sp-webpart-workbench": "1.8.2",
"@microsoft/rush-stack-compiler-2.9": "0.7.7",
"gulp": "~3.9.1",
"@types/chai": "3.4.34",
"@types/mocha": "2.2.38",
"ajv": "~5.2.2"
}
}

`

@StfBauer I just used what's generated by Yoeman. I later realized that I needed to use the ${styles.row} and ${styles.column} etc and somehow determine what class @includes I should use. In the end, I ended up using your article about how to import bootstrap and using the :global {} pattern.

Honestly, I think working with Fabric with SPFx isn't very clear or well documented. I've found myself having to do a lot of research to do something every beginner developer can figure out with Bootstrap / Material UI etc.

@StfBauer I just used what's generated by Yoeman. I later realized that I needed to use the ${styles.row} and ${styles.column} etc and somehow determine what class @includes I should use. In the end, I ended up using your article about how to import bootstrap and using the :global {} pattern.

Honestly, I think working with Fabric with SPFx isn't very clear or well documented. I've found myself having to do a lot of research to do something every beginner developer can figure out with Bootstrap / Material UI etc.

Please could you post an example of how you got ms-Grid to render, I.e. what import statement did you use and a sample of your SCSS

This was all working fine until I update to SPFX 1.8.2

@simkessy the documentation indeed could be improved, but there are also some things that I like to explain here.

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.

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.

@StfBauer Many thanks for your detailed explanation. Referring to your comments and taking a second look at my web part is trying to achieve, I agree that ms-Grid in the web part is not the best approach, and I will rewrite.

As a quick fix I can confirm the following suggestion works

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

Many thanks again for your explanation.

Closing issue as "answered". If you encounter similar issue(s), please open up a NEW issue. Thank you.

Issues that have been closed & had no follow-up activity for at least 7 days are automatically locked. Please refer to our wiki for more details, including how to remediate this action if you feel this was done prematurely or in error: Issue List: Our approach to locked issues

Was this page helpful?
0 / 5 - 0 ratings

Related issues

mikeparkie picture mikeparkie  路  3Comments

bengtmoss picture bengtmoss  路  3Comments

christianbueschi picture christianbueschi  路  3Comments

waldekmastykarz picture waldekmastykarz  路  3Comments

patrick-rodgers picture patrick-rodgers  路  3Comments