在 SharePoint 框架中使用 Office UI Fabric Core 和 Fabric React

Office UI Fabric是用于在 Office 365 和 SharePoint 中构建体验的官方前端框架。 SharePoint 提供与 Fabric 的无缝集成,使 Microsoft 能够在各种 SharePoint 体验(如新式团队网站、新式页面和新式列表)之间提供可靠且一致的设计语言。 此外,在生成自定义 SharePoint 解决方案时,Office UI Fabric适用于SharePoint 框架中的开发人员。

Microsoft 使用 SharePoint 中的 Fabric Core 和 Fabric React。 Microsoft 定期将更新推送到 SharePoint Online,同时也可以更新 Fabric Core 和 Fabric React 版本。 这些更新可能会与第三方客户解决方案相冲突,后者可能是使用早期版本的 Fabric Core 和 Fabric React 生成,这可能导致自定义异常。 造成这些类型的中断的主要原因是在两个 Fabric 库中使用了全局 CSS 样式。 无论如何都要避免此类冲突。

在 React 和 JavaScript 上下文的以下演示文稿中详述了全局 GSS 样式的挑战:JS 中的 React CSS

为了实现可靠性,我们需要解决的主要问题之一就是全局 CSS 样式。 此帐户在 HTML 标记中不使用全局类名,而是在 Sass 声明文件中使用 Fabric Core mixin 和变量。 这涉及到在 Sass 文件中导入 Fabric Core 的 Sass 声明,然后适当地使用变量和 mixin。

目标

SharePoint 框架的目标是允许 Microsoft 和客户基于 SharePoint 构建丰富、出色且一致的用户体验。

根据这些目标,以下是主要设计原则:

  • 客户应能在他们的解决方案中平稳可靠地使用 Fabric Core 和 Fabric React。
  • Microsoft 将推出更新的体验,即在 SharePoint 中使用更新版本的 Fabric Core 和 Fabric React,而不会与客户的解决方案发生冲突。
  • 客户可以针对解决方案的需求来自定义和替代默认样式、设计和组件。

Office UI Fabric 有两个部件应可供开发人员使用:

  • Office UI Fabric Core 这是整体设计语言的一套核心样式、版式、响应式网格、动画、图标以及其他基本构建基块。

  • Office UI Fabric React 这是一组基于 Fabric 设计语言构建的 React 组件,可用于基于 React 的项目中。

Office UI Fabric Core 包

SharePoint 框架 Fabric Core npm 程序包 (@microsoft/sp-office-ui-fabric-core) 包含可以安全地在 SharePoint 框架组件中使用的部分受支持 Fabric Core 样式。

以下核心样式在程序包中受支持:

  • 版式
  • 布局
  • 颜色
  • 主题
  • 本地化

以下内容在程序包中尚不受支持:

  • 动画
  • 图标

从 SharePoint 框架 Yeoman 生成器版本 1.3.4 开始,默认项目(Web 部件和扩展)模板附带新的 @microsoft/sp-office-ui-fabric-core 程序包,并使用来自程序包的核心样式,而不是全局 CSS 样式。

更新现有项目

要在现有项目中使用 Fabric Core 程序包,请将程序包作为依赖项安装:

npm install @microsoft/sp-office-ui-fabric-core --save

安装后,你就可以将 Fabric Core Sass 声明导入 Sass 定义文件中,并使用以下部分所述的 mixin 和变量。

使用 Fabric Core 样式

若要使用 Fabric Core 样式,需要在 Sass 文件中导入 SPFabricCore 声明。

注意

确保安装了 @microsoft/sp-office-ui-fabric-core npm 程序包。

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

现在,你可以使用核心样式作为 mixin 和变量。

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

Office UI Fabric React

建议使用包含在 SharePoint 框架 Yeoman 生成器项目中的 Office UI Fabric React 包的版本。 例如,SharePoint 框架 v1.7.0 版本使用 Fabric React v5.131.0

注意

Fabric React 版本 2.x 或更早版本在 SharePoint 框架中不受支持。

安装 Fabric React 程序包后,就可以从 Fabric React 捆绑包中导入所需组件。

//import Button component from Fabric React Button bundle
import { Button } from 'office-ui-fabric-react/lib/Button';

//use it in your component
render() {
  ...
  <div>
    <Button>click me</Button>
  </div>
  ...
}

Fabric React 程序包包括 Fabric React 组件中使用的受支持的 Fabric Core 样式。 建议从 Fabric React 程序包而不是 @microsoft/sp-office-ui-fabric-core 程序包导入 Fabric Core 样式,以确保在组件中使用正确的样式。

由于 Yeoman 生成器已在解决方案中安装了 @microsoft/sp-office-ui-fabric-core 程序包,因此如果你决定使用 Fabric 组件并减小组件捆绑包的大小,则建议卸载该程序包。

npm uninstall @microsoft/sp-office-ui-fabric-core --save

然后,可以从 Fabric React 包中提供的 SASS 声明导入核心样式。

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

了解这种方法及其缺点

解决方案中的 Fabric 组件被锁定到安装的 Fabric React 的特定版本。 需要更新 Fabric React 程序包来获取任何新组件(如果它们在较新的程序包版本中可用)。 由于 Fabric 组件包含在组件捆绑包中,因此可能会增加组件捆绑包的大小。 但是,当 Office UI Fabric React 用于 SharePoint 框架解决方案时,此方法是官方支持的唯一方法。

CSS 在使用 Office UI Fabric 时遇到的挑战

以下概念和参考提供有关在客户端 Web 部件上下文中使用 Office UI Fabric 所遇到问题的见解。

全局 CSS 样式

如何尽可能避免全局 CSS 样式是一个大问题。 现在,Fabric Core 和 Fabric React 都有全局样式。 缺乏从浏览器到管理样式作用域的本机解决方案使之成为一个难以解决的问题。

  • 作用域 CSS 处于早期讨论阶段。
  • iframe 不是隔离样式的一个好方法。
  • Web 组件是探讨作用域内样式的另一个标准,但仍处于讨论阶段。
  • React:JS 中的 CSS 讨论很好地解释了这一问题。

Web 上有许多关于全局命名空间威胁解决方案的其他文档。

CSS 特异性

CSS 特异性如何适用于 Web UI。 特异性较高的样式会替代特异性较低的样式,但需要注意的关键一点是如何应用特异性规则。 一般情况下,从高到低的优先顺序如下所示:

  • 样式属性(例如 style="background:red;"
  • ID 选择器(例如 #myDiv { }
  • 类选择器 (.myCssClass{})、属性选择器 ([type="radio"]) 和伪类 (:hover)
  • 类型选择器 (h1)

加载顺序。 如果两个类应用于一个元素并且它们具有相同特异性,则后面加载的类将优先加载。 如以下代码所示,按钮显示为红色。 如果样式标记的顺序发生更改,该按钮显示为绿色。 这是一个重要的概念,如果使用不当,用户体验可能会依赖于加载顺序,也就是说会产生不一致。

<style>
  .greenButton { color: green; }
</style>
<style>
  .redButton { color: red; }
</style>
<body>
  <button class="greenButton redButton"></button>
</body>

已考虑并放弃的其他方法

下面介绍了有关已考虑但放弃的其他方法的一些额外见解,放弃是因为它们未能实现使第三方开发人员能够安全地使用 Office UI Fabric 样式的关键目标。

Office UI Fabric Core

Web 部件开发人员将不需要显式执行任何操作来使作用域正常工作。 我们计划通过 CSS 特异性和后代选择器来解决这一问题。 Fabric Core 团队将提供 Fabric Core css 的多个副本(如 fabric-6.cssfabric-6-scoped.cssfabric-6.0.0.cssfabric-6.0.0-scoped.css)。

作用域内 CSS 文件中的所有样式都位于一个后代选择器内部,如 .ms-Fabric--v6-0-0 .ms-Icon--List。 在编译时,工具将收集用来生成 Web 部件的 Office UI Fabric Core 的版本。 此版本可能是附带 SharePoint 框架的版本。 此外,如果特定版本的 Office UI Fabric Core 位于 package.json 文件中,Web 部件开发者可以指定显式依赖项。

将 Web 部件 div 分配到此作用域,即 <div data-sp-webpart class="ms-Fabric--v6-0-0">。 该框架会加载 Fabric core 作用域内的 CSS 文件的特定主要版本。 如果 Web 部件是使用 Fabric Core CSS 6.0.0 版本构建的,则框架将在加载 Web 部件时下载 fabric-6-scoped.css

本页的剩余部分会包含无作用域的 Office UI Fabric Core 样式。 这样,按照 CSS 特异性规则,作用域内的 CSS 将在 Web 部件 div 中处于优先级别。 Web 部件及其内容将与开发者已选择的 Office UI Fabric Core 的特定版本一致。

不支持替代 Fabric Core 样式。

// Sample of how the scoping would work.
import { SPComponentLoader } from '@microsoft/sp-loader';

export default class MyWebPart {
    constructor() {
        super();

        SPComponentLoader.loadCss('https://static2.sharepointonline.com/files/fabric/office-ui-fabric-core/6.0.0/css/fabric-6.0.0.scoped.css');
    }
}

protected render(): void {
  <div className="ms-Fabric--v6-0-0">
    { // Rest of the web part UI }
  </div>
}

此策略的缺点

分析此策略一段时间后,可以确定后代选择器方法存在两个严重的缺陷,这使得生成永远不会产生问题的 Web 部件变得不可能。

缺乏可靠的嵌套支持

此方法只有在 Microsoft 用户体验(即页面和第一方 Web 部件)使用 Office UI Fabric Core 的无作用域版本(例如 ms-Icon--List)时才有效,而第三方 Web 部件仅使用作用域内的 Office UI Fabric Core css(如上所述)。

其原因在于在 Web 部件上应用的作用域内的 CSS 的特异性将替代页面上的无作用域 CSS。 请注意,如上所述,如果两个类的 CSS 特异性相同,那么它们的加载顺序将在 CSS 类的应用方式中起到一定的作用。 后面加载的类将得到优先处理。 因此,作用域内的 CSS 的更高特异性对于获得一致体验而言非常重要。

此外,多个扩展(一个包含在另一个中)不能使用不同的 Fabric Core 版本。 在以下的示例中,仅会应用 ms-Fabric--v6-0-0

<div className="ms-Fabric--v6-0-0">
  { // Rest of the web part UI }
    { // inside of this SPExtension trying to use different Fabric core version does not work }
    <div className="ms-Fabric--v8-0-0">
    </div>
</div>

下面是演示这一问题的更为简单的示例。

<html>
<head>
  <title>CSS specifity test</title>
  <style>
  .myButton {
      background-color: brown;
      color: brown;
      height: 20px;
      width: 40px;
  }
  </style>
  <style>
  .scope2 .myButton {
      background-color: green;
      color: green;
  }
  </style>
  <style>
  .scope3 .myButton {
      background-color: yellow;
      color: yellow;
  }
  </style>
  <style>
  .scope1 .myButton {
      background-color: red;
      color: red;
  }
  </style>
</head>
<body>
  <div>
    <span>These tests demonstrate descendant selectors, nesting and load order problems.</span>

    <div>
      <br/>
      <span>This test depicts that a descendant selector with the same specificity does not allow nesting.
      All buttons below do not take the innermost scope (i.e. they should be different colors), but they are all red.
      Further, if you change the ordering of the style tags, the colors will change. (i.e. the UI is load order dependant.)</span>
      <div class='scope1'>
        <button class='myButton'</button>
        <div class='scope2'>
          <button class='myButton'></button>
          <div class='scope3'>
            <button class='myButton'></button>
          </div>
        </div>
      </div>
    </div>
  </div>
</body>
</html>

从无作用域类中泄漏

后代选择器存在另一个问题。 请注意,在上面的示例中,来自无作用域的 myButton 类的高度和宽度样式将应用于所有按钮。 这意味着更改该样式可能会无意中破坏使用作用域内标记的 HTML。

例如,考虑到应用级别的某种原因,我们决定在 myButton 类上将高度设置为 0px。 这会导致使用 myButton 类的所有第三方 Web 部件的高度为 0 px,即导致用户体验的严重倒退。

安全使用旧版 Office UI Fabric Styles(SPFx v1.8.2 之后)

重要

以下指南适用于 SharePoint 框架 >= 1.8.2

请确保将 web 部件清单需求旧版 Fabric 核心样式加载到页面。 此步骤通过在解决方案清单中指定 loadLegacyFabricCss: true 来完成。

在 SPFx v1.8.2 版本之前,当加载无作用域的旧版 Fabric 核心样式时,会出现主机页面 bug。 因此,如果另一个解决方案需求此样式,那么此页面的其他解决方案将不能使用它们。 这导致在解决方案没有独立渲染时,它们的运作是看几率的。

要解决这个 bug,设置样式作用域为 .ms-SPLegacyFabricBlock 类并将其应用到需要加载 Fabric 核心样式表的 SPFx 解决方案。 为了为依赖于上述副作用的解决方案提供一条迁移路径,应用 .ms-SPLegacyFabricBlock 类到所有对第三方解决方案开放的 <div>。 在那段时间内,修改受影响的解决方案来声明旧版 Fabric 核心样式的依赖性。

重要

对于不声明其依赖项的解决方案,最终将从 DOM 中删除对 的显式引用.ms-SPLegacyFabricBlock。 此改动在删除类之前将通过现有频道与进行广泛沟通。

当解决方案在非 SPFx 提供的 DOM 元素中运行时(通常不支持),你将需要自行应用 .ms-SPLegacyFabricBlock 类。

在 SPFx 组件中使用 Office UI Fabric 图标

从 SharePoint Framework v1.8.2 开始, 使用 Office UI Fabric 图标呈现 SharePoint Framework 解决方案的方法有变动。

使用图标的旧版方式(SPFx 1.8.2 之前)

<i className={css('ms-Icon', 'ms-Icon--RecurringEvent')}></i>

更新的使用图标的方式(SPFx 1.8.2 之后)

使用无 JavaScript 框架选项构建的解决方案。

  1. @uifabric/styling包添加到你的package.json
  2. 进行类似于下面代码的代码更改, 以便将所需的图标添加到代码中:
import { getIconClassName } from '@uifabric/styling';

return `<i class="${getIconClassName('Mail')}" />`;

使用React选项或通常使用React构建的解决方案。

  1. office-ui-fabric-react包添加到你的package.json,如果尚未添加。
  2. 进行类似于下面代码的代码更改, 以便将所需的图标添加到代码中:
import { Icon } from 'office-ui-fabric-react/lib/Icon';

<Icon iconName='Mail' />

另请参阅