CSS 模式#
本文档描述了我们用于组织和编写 JupyterLab CSS 的模式。JupyterLab 是使用位于 packages
中的一组 npm 包开发的。这些包中的每一个都有自己的样式,但依赖于主主题包中定义的 CSS 变量。
CSS 检查清单#
CSS 类名在代码中内联定义。我们过去将它们作为所有大写文件级
const
,但我们正在逐渐放弃这种做法。包的 CSS 文件位于
style
子目录中,并导入到插件的index.css
中。尽可能使用
theme-light-extension
和theme-dark-extension
包中的 JupyterLab 默认 CSS 变量来为包设置样式。但是,各个包不应该 npm 依赖于这些包,以使主题能够被替换。插件会谨慎地定义额外的公共/私有 CSS 变量,并符合以下描述的约定。
CSS 变量#
我们在 JupyterLab 中使用原生 CSS 变量。这样做是为了能够对内置和第三方插件进行动态主题化。截至 2017 年 12 月,所有流行浏览器(除了 IE)的最新稳定版本都支持 CSS 变量。如果 JupyterLab 部署需要支持这些浏览器,可以使用服务器端 CSS 预处理器,例如 Myth 或 cssnext。
CSS 变量的命名#
我们使用以下约定来命名 CSS 变量
所有 CSS 变量都以
--jp-
开头。变量名中的单词应为小写,并用
-
分隔。下一段应指代组件和子组件,例如
--jp-notebook-cell-
。下一段应指代任何状态修饰符,例如
active
、not-active
或focused
:--jp-notebook-cell-focused
。最后一段通常与 CSS 属性相关,例如
color
、font-size
或background
:--jp-notebook-cell-focused-background
。
公共/私有#
JupyterLab 中的一些 CSS 变量被认为是我们公共 API 的一部分。其他变量被认为是私有的,不应被第三方插件或主题使用。公共变量和私有变量之间的区别很简单
所有私有变量都以
--jp-private-
开头所有没有
private-
前缀的变量都是公共的。公共变量应在
:root
伪选择器下定义。这确保了公共 CSS 变量可以在浏览器开发工具的顶级<html>
标签下进行检查。尽可能地,私有变量应在除
:root
之外的适当选择器下定义和作用域。
CSS 变量使用#
JupyterLab 在文件 packages/theme-light-extension/style/variables.css 中包含一组默认的 CSS 变量。
为了确保 JupyterLab 中的设计一致性,所有内置和第三方扩展应尽可能在其样式中使用这些变量。有关这些变量的文档可以在 variables.css
文件本身中找到。
插件可以在其自己的 index.css
文件中自由定义额外的公共和私有 CSS 变量,但应谨慎使用。
同样,我们认为此包中公共 CSS 变量的名称是我们 CSS 的公共 API。
文件组织#
我们正在以以下方式组织我们的 CSS 文件
顶层
packages
目录中的每个包都应在其style
子目录中包含任何用于对其自身进行样式设置所需的 CSS 文件。所有本地样式应合并到
style/base.css
文件中。顶层
index.css
文件由buildutils
作为integrity
脚本的一部分进行模板化。它按依赖关系顺序导入 CSS,最后是本地./base.css
。外部库的 CSS 由其package.json
中的style
字段确定。如果需要其他文件或外部库没有style
字段,我们使用jupyterlab: { "extraStyles": { "fooLibrary": ["path/to/css"] } }
模式在我们的package.json
中声明它们。对于不应添加到index.css`, update ``SKIP_CSS
inbuildutils/src/ensure-repo.ts
的导入。
CSS 类名#
CSS 类命名约定#
我们有一个相当正式的方法来命名我们的 CSS 类。
首先,CSS 类名与扩展 lumino.Widget
的 TypeScript 类相关联
每个此类小部件的 .node
应具有与 TypeScript 类名称匹配的 CSS 类
class MyWidget extends Widget {
constructor() {
super();
this.addClass('jp-MyWidget');
}
}
其次,子类应同时具有父类和子类的 CSS 类
class MyWidgetSubclass extends MyWidget {
constructor() {
super(); // Adds `jp-MyWidget`
this.addClass('jp-MyWidgetSubclass');
}
}
在这两种情况下,使用大写字母的 CSS 类名保留用于存在命名 TypeScript Widget
子类的情况。这些类是 TypeScript 类提供样式公共 API 的一种方式。
第三,Widget
的子节点应在 CSS 类名中具有第三个部分,该部分对组件进行语义命名,例如
jp-MyWidget-toolbar
jp-MyWidget-button
jp-MyWidget-contentButton
一般来说,父 MyWidget
应将这些类添加到子节点中。这适用于子节点是普通 DOM 节点或 Widget
实例/子类本身的情况。因此,CSS 类的通用命名形式为 jp-WidgetName-semanticChild
。这使得能够以独立于子节点实现或它们本身具有的 CSS 类的样式来对这些子节点进行样式设置。
第四,一些 CSS 类用于修改小部件的状态
jp-mod-active
: 应用于处于活动状态的元素jp-mod-hover
: 应用于处于悬停状态的元素jp-mod-selected
: 应用于选中的元素
第五,一些 CSS 类用于区分不同类型的部件
jp-type-separator
: 应用于作为分隔符的菜单项jp-type-directory
: 应用于文件浏览器中作为目录的元素
边缘情况#
随着时间的推移,我们发现这些规则无法完全解决一些边缘情况。在这里,我们尝试澄清这些边缘情况。
何时父级应向子级添加类?
上面我们指出,父级(MyWidget
)应向子级添加 CSS 类,以指示子级的语义功能。因此,Widget
的子类 MyWidget
应向自身添加 jp-MyWidget
,并向工具栏子级添加 jp-MyWidget-toolbar
。
如果子级本身是 Widget
,并且本身已经具有适当的 CSS 类名,例如 jp-Toolbar
?为什么不使用 .jp-MyWidget .jp-Toolbar
或 .jp-MyWidget > .jp-Toolbar
等选择器?
原因是这些选择器依赖于工具栏具有 jp-Toolbar
CSS 类的实现。当 MyWidget
添加 jp-MyWidget-toolbar
类时,它可以独立于子级的实现来设置子级的样式。添加 jp-MyWidget-toolbar
类的另一个原因是,如果 DOM 结构高度递归,则通常的后代选择器可能不够具体,无法仅针对所需的子级。
如有疑问,父级向子级添加选择器不会造成太大损害。
常用 CSS 选择器#
我们使用 CSS 选择器来决定显示哪些上下文菜单项,以及在使用键盘快捷键时调用哪个命令。以下常用 CSS 选择器旨在用于添加上下文菜单项和键盘快捷键。
针对部件及其子级的 CSS 类
jp-Activity
: 应用于主工作区中的元素jp-Cell
: 应用于单元格jp-CodeCell
: 应用于代码单元格jp-CodeConsole
: 应用于控制台jp-CodeConsole-content
: 应用于控制台中的内容面板jp-CodeConsole-promptCell
: 应用于控制台中活动提示单元格jp-DirListing-content
: 应用于文件浏览器目录列表的内容jp-DirListing-item
: 应用于文件浏览器目录列表中的项目jp-FileEditor
: 应用于文件编辑器jp-ImageViewer
: 应用于图像查看器jp-InputArea-editor
: 应用于单元格输入区域编辑器jp-Notebook
: 应用于笔记本jp-SettingEditor
: 应用于设置编辑器jp-SideBar
: 应用于侧边栏jp-Terminal
: 应用于终端
描述部件状态的 CSS 类
jp-mod-current
: 应用于当前文档上的元素jp-mod-completer-enabled
: 应用于可以托管补全器的编辑器jp-mod-commandMode
: 应用于处于命令模式的笔记本jp-mod-editMode
: 应用于处于编辑模式的笔记本jp-mod-has-primary-selection
: 应用于具有主选区的编辑器jp-mod-in-leading-whitespace
: 应用于在行首空白处具有选区的编辑器jp-mod-tooltip
: 当页面上存在工具提示时,应用于主体
针对数据属性的 CSS 选择器
[data-jp-code-runner]
: 应用于可以运行代码的小部件[data-jp-interaction-mode="terminal"]
: 当代码控制台处于终端模式时应用[data-jp-interaction-mode="notebook"]
: 当代码控制台处于笔记本模式时应用[data-jp-isdir]
: 应用于描述文件浏览器项目是否为目录[data-jp-undoer]
: 应用于可以撤销的小部件[data-type]
: 应用于描述元素类型,例如“document-title”、“submenu”、“inline”