MDN 为我们的开放网页文档提供了兼容性表格的标准格式; 它是对比所有浏览器之间,包含 DOM,HTML,CSS,JavaScript,SVG 等技术的文档。本文将介绍如何使用我们的功能将兼容性数据添加到MDN页面。

重要: 数据的生成方式已经发生了变更。历史上我们的表格是直接插在页面中的,并且数据是手动生成的。这很没效率,很难维护而且数据也没有弹性。所以我们正在把我们的兼容性表格迁移到一个repo里 (https://github.com/mdn/browser-compat-data) 并且正在用程序的方式生成它。

在这个指南中我们写了关于添加新的相容的数据到MDN的方式的文档, 但是我们仍然在用旧的方法来保证文档覆盖率, 正如你所见,手动表格依然存在于 MDN 上. 如果你需要用旧方法的话, 看看这篇文章: Old compatibility tables

注意: 如果您需要本指南任何步骤的帮助,欢迎您在MDN论坛上与我们联系。

如何访问 data repo

数据存储在一个 GitHub repo 中,到 https://github.com/mdn/browser-compat-data 查看。想要访问它,你必须拥有一个 GitHub 账号,fork浏览器兼容数据仓库到你自己的账户,然后克隆你的fork到你的本地机器。

选择要贡献的数据类型

首先,确定一下你想为何种 Web 技术贡献兼容性数据。可以是一个 HTML 元素、CSS 属性、JS 语法或者 JS API接口。我们鼓励您贡献 API 接口的数据, 因为已经有人在贡献 HTML、JS 和 CSS 的数据了。你可以在表格 Browser Compat Data migration 中查看各个需要添加兼容性数据的 Web 技术的数据状态。

电子表格的使用步骤如下:

  1. 直接挑选一个还未开始或者还未完成数据录入的功能点,在“Who”一栏中填入你的名字, 最好能够和你的MDN用户名保持一致,以便我们在需要联系你的时候能够查找到你的邮件地址.
  2. 如果该功能点不在表格上,那么你可以参照现有的格式在合适的位置上加一行。注意要使用同等的粒度(例如,HTML以标签元素为单位、CSS以选择器或者属性值为单位、JS以对象为单位、JS API以特定的接口为单位)
  3. 当你已经开始录入数据的时候,把对应状态栏的下拉选项置于“In progress”(进行中)状态。
  4. 一旦添加完数据,并且向主仓库提交了一个拉取请求(pull request),那么把对应状态栏的下拉选项置于“PR done”状态。
  5. 当你的数据已经成功合并到主分支,或者已经添加到npm包里面的时候,请尽量更新对应的状态栏到相应的状态。
  6. 当你更新了你的功能文档页面,并且使用新的脚步命令使其可以在每一个页面都可以动态的生成合适的数据表格的时候,你就需要在电子表格中修改对应功能的状态为“Article updated”(文章已更新)。这意味着你已经完成了这一功能的所有数据录入工作。

准备添加数据

在添加新数据之前,你应该保证您的 fork 是主 repo 的最新版本(它们应包含相同的内容)。在您的 fork 里添加一个包含您的更改的分支,然后把它pull到您本地的仓库,这样你就可以开始贡献了:

下面是更新您的分支的一个简单方法:

将浏览器兼容信息的主 repo 添加到远端服务器列表中

在您的终端或命令行中进入您的fork的本地仓库,用以下命令将(服务器上的)主 repo 添加到远端服务器列表中(您只需执行以下命令一次):

git remote add upstream https://github.com/mdn/browser-compat-data.git

如果您不确定自己是否做到了这一点, 您可以检查您仓库已经在用的远端服务器列表:

git remote -v

让您的分支与服务器上的内容同步

现在,只要您想更新您的分支,就可以这样做:

  1. 确定您已切换到在主分支:

    git checkout master
  2. 使用以下命令来获取服务器上最新的内容:

    git fetch upstream
  3. 用rebase将主仓库的内容合并到您的master分支中:

    git rebase upstream/master
  4. 将来自主 repo 的更新 push 回您自己的 repo 中:

    git push -f

创建您用来工作的分支:

接下来,打开您在服务器上的fork(它的地址可能是https://github.com/your-username/browser-compat-data)并且创建一个新分支来存储您的改动。步骤如下:

  1. 点击"Branch: Master"按钮;
  2. 在"Find or create a branch..."文本输入框中输入一个新的分支名;
  3. 点击下方出现的"Create branch name-of-branch from Master"按钮。

举个例子,如果您想补充WebVR API的信息,您可以创建一个名为“webvr”的分支.

切换到新分支

此时,回到您的终端或命令行,用以下命令将您的新分支同步到您本地的fork中:

git pull

现在用以下命令切换到您的新分支

git checkout -b name-of-branch

现在您可以开始进行您对浏览器兼容信息的补充和修改了。

添加数据

为添加新的数据,您需要新建文件以存储您的兼容性数据。对于不同技术的数据,您需要创建的文件也有所不同:

  • HTML:被包含在 browser-compat-data/html/elements 中,每个HTML元素对应一个文件。文件需要以元素的小写的名称命名,例如div.json
  • CSS:每个CSS属性或选择器对应一个文件。它们被包含在对应的目录中(请参考browser-compat-data/css)。文件需要以CSS特性的小写的名称命名,如background-color.json或者hover.json
  • JS:被包含在browser-compat-data/javascript/builtins中,每个JavaScript对象对应一个文件。文件要以JavaScript对象的准确名称命名,保留其大小写,如Date.json或者InternalError.json
  • APIs:API中的每个接口对应一个文件。它们在browser-compat-data/api中。每个文件要以接口的准确名称命名,保留其大小写,例如WebVR API的文件为VRDisplay.jsonVRDisplayCapabilities.json等等。

注意:您会留意到,该仓库还包含了浏览器拓展HTTP的数据。These data sets are basically finished as they stand, but more features may need to be added in the future.

Each file you create has to follow the pattern defined in the schema contained within our repo; you can see the detailed schema description here.

基本的兼容性数据的结构

让我们来看一下如下例子。一个CSS属性JSON文件需要以下的结构:

{
  "css": {
    "properties": {
      "border-width": {
        "__compat": {
          ...
        }
      }
    }
  }
}

首先有一个css对象,其中包含了一个properties对象。每个您要设定兼容性数据的特性都对应一个properties对象中的成员。而每一个这些成员都有一个__compat成员,__compat成员中则是实际的数据。

The above data is found in the browser-width.json file — compare this to the rendered browser-width support table on MDN.

Other types of features work in the same way, but with different object names:

  • CSS selectors work in basically the same way as CSS properties, except that the top-level object structure is css.selectors instead of css.properties. 请以 cue.json 作为参考示例。
  • HTML data works in basically the same way, except that the top-level object structure is html.elements. 请以article.json作为参考示例。
  • JS内置对象对应的顶级结构是javascript.builtins;请以 Array.json 作为参考示例。

在一个HTML、CSS和JS页面中,通常您只需要有一个特性。API则有些不同——它们总是包含多个子特性 (see Sub-features, below).

一个特性中的基础结构

在一个特性的__compat成员中,您需要包含以下成员:

  • mdn_url: Contains the URL of the reference page for this feature on MDN. Note that this needs to be written without the locale directory inside, e.g. /docs/... not /docs/en-US/... (or whatever). This is added in by the macro when the data is put on the page, for localization purposes.
  • support: Contains members representing the browser support information for this feature in all the different browsers we want to report.
  • status: Contains members reporting the standards track status of this feature.

The names of the browser members are defined in the schema (see Browser identifiers). You should use the full list of currently defined identifiers. If you wish to add another browser, talk to us first, as this could have a wide-ranging impact and should not be done without careful thought.

In a basic browser compat data file, you'll only need to include "version_added" inside the browser identifier members (we'll cover Advanced cases later on). The different values you might want to include are as follows:

  • A version number: If you know the exact version in which a browser started to support your feature, use a string representing the number, e.g. "47".
  • true: If a browser supports a feature but you don't know the exact version number, use the value true. This equivalent to the {{CompatVersionUnknown}} macro call in the old manual tables.
  • false: If a browser does not support a feature, use the value false. This is equivalent to the the {{CompatNo}} macro call in the old manual tables.
  • null: If you don't know whether a browser supports a feature or not, use the value null. This is equivalent to the {{CompatUnknown}} macro call in the old manual tables.

Inside the status member, you'll include three submembers:

  •  "experimental": This should be set to true if the feature is experimental, or false otherwise.
  • "standard_track": This should be set to true if a feature is on some kind of standards track (most commonly W3C/WHATWG, but there are also other standards efforts such as Khronos, TC39, etc.) or false otherwise.
  • "deprecated": This should be set to true if the feature is deprecated, or false otherwise.

The feature data for border-width (also see border-width.json) is shown below as an example:

"__compat": {
  "mdn_url": "https://developer.mozilla.org/docs/Web/CSS/border-width",
  "support": {
    "chrome": {
      "version_added": "1"
    },
    "webview_android": {
      "version_added": "2"
    },
    "edge": {
      "version_added": true
    },
    "edge_mobile": {
      "version_added": true
    },
    "firefox": {
      "version_added": "1"
    },
    "firefox_android": {
      "version_added": "1"
    },
    "ie": {
      "version_added": "4"
    },
    "ie_mobile": {
      "version_added": "6"
    },
    "opera": {
      "version_added": "3.5"
    },
    "opera_android": {
      "version_added": "11"
    },
    "safari": {
      "version_added": "1"
    },
    "safari_ios": {
      "version_added": "3"
    }
  },
  "status": {
    "experimental": false,
    "standard_track": true,
    "deprecated": false
  }
}

添加描述说明

There is a fourth, optional, member that can go inside the __compat member — description. This can be used to include a human-readable description of the feature. You should only include this if it is hard to see what the feature is from glancing at the data. For example, it might not be that obvious what a constructor is from looking at the data structure, so you can include a description like so:

{
  "api": {
    "AbortController": {
      "__compat": {
        ...
      },
      "AbortController": {
        "__compat": {
          "mdn_url": "https://developer.mozilla.org/docs/Web/API/AbortController/AbortController",
          "description": "<code>AbortController()</code> constructor",
          "support": {
            ...
          }
        }
      }

      ... etc.
    }
  }
}

子特性

In a page where the compat table has more than one row, you'll need multiple subfeatures inside each feature to define the information for each row. This can happen, for example, when you've got the basic support for a feature stored in one row, but then the feature also has a new property or value type that was addded much later in the specification's life and is only supported in a couple of browsers.

As an example, see the compat data and corresponding MDN page for the background-color property. The basic support exists inside the __compat object as explained above, then you have an additional row for browsers' support for "alpha channel for hex values", which contains its own __compat object.

{
  "css": {
    "properties": {
      "background-color": {
        "__compat": {
          ...
        },
        "alpha_ch_for_hex": {
          "__compat": {
            ...
          },
        }
      }
    }
  }
}

For an API, you've got the top two levels defined as api.name-of-the-interface, then a top-level __compat section to define the overall browser compatibility of the interface, then a sub-feature for each of the methods, properties, and constructors contained inside the interface. The basic structure looks like this:

{
  "api": {
    "VRDisplay": {
      "__compat": {
        ...
      },
      "cancelAnimationFrame": {
        "__compat": {
          ...
        }
      },
      "capabilities": {
        "__compat": {
          ...
        }
      },

      ... etc.
      
    }
  }
}

See VRDisplay.json for a full example.

添加数据:高级场景

There are some advanced features that you'll want to include in browser compat data. The aim of this section is to list the most common ones, providing an example of each to show how you can implement them in your own compat data.

Including a footnote

Often compat tables will include footnotes related to certain entries that explain useful details or strange behavior that developers will find useful. As an example, the Chrome Android entry for VRDisplay.capabilities (see also VRDisplay.json)  (at the time of writing) had a footnote "Currently supported only by Google Daydream." To include this in the capabilities data, we added a "notes" submember inside the relevant "chrome_android" submember; it would look like this:

"chrome_android": {
  "version_added": true,
  "notes": "Currently supported only by Google Daydream."
}

包含浏览器厂商的前缀

If a feature is supported behind a vendor prefix in one or more browsers, you'll want to make that clear in the browser compat data. 例如您可能有一个特性在Firefox浏览器中要用-moz-前缀才被支持,要在兼容性数据中指明这一点,您需在对应的"firefox"子成员中增加一个"prefix"子成员。它看起来是这样的:

"firefox": {
  "version_added": true,
  "prefix": "-moz-"
}

Including browser preferences or flags

Some features may be supported in a browser, but they are experimental and turned off by default. If a user wants to play with this feature they need to turn it on using a preference/flag.

To represent this in the compat data, you need to add the "flags" submember inside the relevant browser identifier submember. The value of "flags" is an array of objects each of which contains of three members:

  • "type": The type of flag or pref this is. The most common value is "preference", which is set inside the browser (for example, using about:config in Firefox, or chrome://flags in Chrome), but you might also sometimes use a value of "compile_flag", which is a preference set when the browser build is compiled.
  • "name": This is a string representing the name of the preference that needs to have a value set on it. For example, "Enable Experimental Web Platform Features" is a preference that exists in Chrome, found in chrome://flags.
  • "value_to_set": This is a string representing the value that needs to be set on the preference, for example "true".

So to add a preference/flag to the Chrome support for a feature, you'd do something like this:

"chrome": {
  "version_added": "50",
  "flags": [
    {
      "type": "preference",
      "name": "Enable Experimental Web Platform Features",
      "value_to_set": "true"
    }
  ]
},

If a feature is behind two or more flags, you can add additional objects to the "flags" array, like in this case, for example:

"firefox": {
  "version_added": "57",
  "flags": [
    {
      "type": "preference",
      "name": "dom.streams.enabled",
      "value_to_set": "true"
    },
    {
      "type": "preference",
      "name": "javascript.options.streams",
      "value_to_set": "true"
    }
  ]
},

包含特性不再被支持的版本

有时一个特性在浏览器的某个版本被加进去,然后又因为该特性过时而被被移除掉。这可以在"version_removed"子成员中体现。该子成员是一个代表特性被移除的版本的字符串。例如:

"firefox": {
  "version_added": "35",
  "version_removed": "47",
},

Including multiple support points for the same browser entry

Sometimes you'll want to add multiple support data points for the same browser inside the same feature.

As an example, the text-align-last property (see also text-align-last.json) was added to Chrome in version 35, supported behind a pref.

The support mentioned above was then removed in version 47; also in version 47, support was added for text-align-last enabled by default.

To include both of these data points, you can make the value of the "chrome" submember an array containing two support information objects, rather than just a single support information object:

"chrome": [
  {
    "version_added": "47"
  },
  {
    "version_added": "35",
    "version_removed": "47",
    "flags": [
      {
        "type": "preference",
        "name": "Enable Experimental Web Platform Features",
        "value_to_set": "true"
      }
    ]
  }
],

Note: You should put the most current or important support point first in the array — this makes the data easier to read for people who just want to scan it for the latest info.

包含一个可选的名字

Occasionally browsers will support a feature under a different name to the name defined in its specification. This might be for example because a browser added experimental support for a feature early, and then the name changed before the spec stabilized.

To include such a case in the browser compat data, you can include a support information point that specifies the alternative name inside an "alternative_name" member.

Note: The alternative name might not be an exact alias — it might have differing behaviour to the standard version.

Let's look at an example. The border-top-right-radius property (see also border-top-right-radius.json) was supported in Firefox:

  • From version 4 onwards with the standard name border-top-right-radius.
  • From version 49 onwards with a -webkit- prefix, for browser compatibility purposes.
  • From version 1 onwards with the alternative name -moz-border-radius-topright. Support for this alias was removed in version 12.

To represent this in the data, we used the following JSON:

"firefox": [
  {
    "version_added": "4",
    "notes": "Prior to Firefox 50.0, border styles of rounded corners were always rendered as if <code>border-style</code> was solid. This has been fixed in Firefox 50.0."
  },
  {
    "prefix": "-webkit-",
    "version_added": "49",
    "notes": "From Firefox 44 to 48, the <code>-webkit-</code> prefix was available with the <code>layout.css.prefixes.webkit</code> preference. Starting with Firefox 49, the preference defaults to <code>true</code>."
  },
  {
    "alternative_name": "-moz-border-radius-topright",
    "version_added": "1",
    "version_removed": "12"
  }
],

将变更推送回主仓库

在您添加完您的兼容性数据之后,您应该先用以下命令测试一下:

  • npm run lint — 测试所有兼容性数据以确保JSON的格式和书写风格正确,例如正确的缩进和没有遗漏逗号等等。该命令会打印出一个很长的文件名和测试结果的列表;if an error is found, the linter will throw an error on the file it is found in, giving you useful debugging info like line number, error message, etc.
  • npm run show-errors — validates the JSON against the data schema, and highlights errors such as invalid browser version numbers being used.
  • npm run render 'dotted.path.to.feature' — allows you to preview the markup for the compat table for a data file in the repo. As an example, npm run render 'css.properties.background' shows the table markup for the background property.

If it is looking OK, you then need to commit it and push it back up to your remote fork on GitHub. You can do this easily with terminal commands like this:

git add .
git commit -m 'adding compat data for name-of-feature'
git push

Now go to your remote fork (i.e. https://github.com/your-username/browser-compat-data) and you should see information about your push at the top of the files list (under "Your recently pushed branches"). You can create a pull request (starting the process of pushing this to the main repo) by pressing the "Compare & pull request" button, then following the simple prompts on the subsequent screen.

At this point, you just need to wait. A reviewer will review your pull request, and merge it with the main repo, OR request that you make changes. If changes are needed, make the changes and submit again until the PR is accepted.

将数据插入MDN页

Once your new data has been included in the main repo, you can start dynamically generating browser compat tables based on that data on MDN pages using the {{Compat}} macro. This takes a single parameter, the dot notation required to walk down the JSON data and find the object representing the feature you want to generate the compat table for.

Above the macro call, to help other contributors finding their way, you should add a hidden text that is only visible in MDN contributors in edit mode:

<div class="hidden">
<p>此页面上的兼容性表格由结构化数据生成。如果你想贡献数据,可以看看 <a href="https://github.com/mdn/browser-compat-data">https://github.com/mdn/browser-compat-data</a>并向我们发送 pull request.</p>
</div>

As an example, on the Accept-Charset HTTP header page, the macro call looks like this: {{Compat("http.headers.Accept-Charset")}}. If you look at the accept-charset.json file in the repo, you'll see how this is reflected in the JSON data.

As another example, The compat table for the VRDisplay.capabilities property is generated using {{Compat("api.VRDisplay.capabilities")}}. The macro call generates the following table (and corresponding set of notes):


Update compatibility data on GitHub
DesktopMobile
ChromeEdgeFirefoxInternet ExplorerOperaSafariAndroid webviewChrome for AndroidEdge MobileFirefox for AndroidOpera for AndroidSafari on iOSSamsung Internet
Basic support
Experimental
Chrome No support NoEdge Full support 15Firefox Full support 55
Notes
Full support 55
Notes
Notes Windows support was enabled in Firefox 55.
Full support 64
Notes
Notes macOS support was enabled in Firefox 64.
IE No support NoOpera ? Safari ? WebView Android No support NoChrome Android Full support 56
Notes Disabled
Full support 56
Notes Disabled
Notes Only works in an experimental version of Chrome. (Other builds won't return any devices when Navigator.getVRDisplays() is invoked.)
Notes Daydream View supported in Chrome 56.
Notes Google Cardboard supported in Chrome 57.
Disabled From version 56: this feature is behind the WebVR preference. To change preferences in Chrome, visit chrome://flags.
Edge Mobile ? Firefox Android Full support 55Opera Android ? Safari iOS ? Samsung Internet Android Full support 6.0

Legend

Full support  
Full support
No support  
No support
Compatibility unknown  
Compatibility unknown
Experimental. Expect behavior to change in the future.
Experimental. Expect behavior to change in the future.
See implementation notes.
See implementation notes.
User must explicitly enable this feature.
User must explicitly enable this feature.

注意: 文件名通常与给予JSON结构内的接口的标签相匹配,但事实并非总是如此。 当宏调用生成表时,他们遍历所有文件,直到找到相关的JSON使用,所以文件名不是关键。 说到这一点,你应该始终尽可能直观地命名它们。

文档标签和贡献者

最后编辑者: wbamberg,