互換性一覧表

MDN には、オープンなウェブ文書のための互換性一覧表の標準形式があります。これは、すべてのブラウザーにわたって共有される DOM, HTML, CSS, JavaScript, SVG などの技術の文書で使用されます。この記事では、 MDN のページに互換性データを追加するための機能の使い方について説明します。

重要: データの生成方法が変更されました。以前は、一覧表はページに挿入され、データは手動で入力されていました。これは効率的ではなく、保守が困難であり、データに柔軟性がありませんでした。そのため、ブラウザーの互換性データを移行してデータリポジトリ (https://github.com/mdn/browser-compat-data を参照) に格納し、プログラムで表を生成するようにしました。

MDN のローカライズで古い互換性一覧表を見かけたら、新しい一覧表に置き換える方法について discourse のスレッドを確認してください。

メモ: このガイドの手順について助けが必要な場合は、MDN ディスカッションフォーラムで相談してください。

データリポジトリにアクセスする方法

データは GitHub リポジトリに保存されています - https://github.com/mdn/browser-compat-data を参照してください。アクセスするには GitHub アカウントを取得し、 browser-compat-data を自分のアカウントでforkフォークし、forkしたものをローカルマシンにcloneクローンする必要があります。

データを追加する機能の選択

まず、 browser-compat-data を追加する機能を探します。 たとえば、HTML 要素、CSS プロパティ、JS 言語機能、JS API インターフェースなどが考えられます。既に HTML、JS、CSS を扱っている人がいるので、 API の機能について手伝うことをお勧めします。リポジトリにデータを追加する必要がある機能の状態は、ブラウザー互換性データ移行スプレッドシートにあります。

使用する手順は次のとおりです。

  1. 作業が始まっていない、または終了していない機能を選んでください。 "Who" 列に名前を記入し、できれば MDN ユーザー名を併記していただければ、必要な時にメールアドレスを見つけて連絡を取ることができます。
  2. 作業したい機能がスプレッドシートにまだ挙がっていない場合は、適切な場所に行を追加して、すでに存在する書式をコピーしてください。同じ粒度 (たとえば、 HTML の場合は要素ごと、 CSS の場合はプロパティまたはセレクターごと、 JS の場合はオブジェクトごと、 API の場合はインターフェイスごと) を使用してください。
  3. データの追加作業を開始したら、 status を "In progress" にしてください。
  4. データを追加してメインリポジトリにプルリクエストを提出したら、 status を "PR done" にしてください。
  5. データがリポジトリにマージされると、 npm パッケージに追加され、必要に応じて status が更新されます。
  6. 新しいマクロを使用して、各ページで適切なデータ表を動的に生成するように機能の文書ページを更新したら、 status を "Article updated" を設定してください。この時点で作業は完了です。

データの追加の準備

新しいデータを追加する前に、forkがメインリポジトリの (同じ内容を含む) 最新であることを確認し、fork内に追加を格納するための新しいbranchブランチを作成し、そのbranchをローカルのcloneにプルすれば、その中で作業を始められます。

forkが最新であることを、次のように簡単な方法で確認してみましょう。

メインの browser-compat-data リポジトリをリモートとして追加

端末またはコマンドラインでforkのローカルにcloneした場所へ行き、次のようにしてリモートにメイン (upstream) リポジトリを指すよう追加します (これを行う必要があるのは一度だけです)。

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

もしこれをしたか不明確であれば、次のようにレポジトリがどのリモートを指しているかを確認することができます。

git remote -v

リモートのコンテンツでforkを更新する

では、forkを更新したいときは、次のようにできます。

  1. master branchにいることを確認します

    git checkout master
  2. 以下のように更新されたレポジトリのコンテンツをfetch (フェッチ) します

    git fetch upstream
  3. ローカルのmasterの内容をメイン (upstream) リポジトリのmasterの内容にrebaseリベースします

    git rebase upstream/master
  4. 以下のようにしてここまでの変更をあなたがforkしたリモートへ反映します。

    git push

作業用の新しいbranchの作成

次に、あなたのforkしたremote(普通はhttps://github.com/your-username/browser-compat-data)に行き、以下の手順で新しいbranchを作成します。変更したい内容をここに追加していくことになります。

  1. Branch: Masterボタンをクリックします
  2. 新しいbranchの名前をFind or create a branch...と書かれたところに入力します
  3. Create branch name-of-branch from Masterと書かれたボタンを押します

例えば、WebVR APIについてデータを追加したい場合webvrという名前がbranch名として考えられるでしょう。

新しいbranchへの切り替え

ここから先は作業が端末またはコマンドラインに戻ります。ローカルにcloneしたものを更新して新しく作成したbranchを使えるようにするには、下のコマンドを使います。

git pull

そして以下のように新しく作成したbranchに切り替えます。

git checkout name-of-branch

これでデータを追加するための準備が完了しました!

データの追加

データを追加するには、新たに実装状況を書いたファイルを作成する必要があります。作成する必要があるファイルは、どの技術分野について作業しようとするかによって異なります。

  • HTML: HTMLの要素ごとに一つのファイルがbrowser-compat-data/html/elementsに格納されています。ファイル名は要素の名前をすべて小文字でつけるべきです(SOULD) 例) div.json
  • CSS: CSSのプロパティないしセレクターごとに一つのファイルがbrowser-compat-data/css以下の適切なディレクトリに格納されています。ファイル名はその機能の名前をすべて小文字でつけるべきです(SHOULD) 例) background-color.json, hover.json
  • JS: JavaScriptオブジェクトごとに一つのファイルがbrowser-compat-data/javascript/builtinsに格納されています。ファイル名は大文字小文字を含めて完全にオブジェクト名と一致させるべきです(SHOULD) 例) Date.json, InternalError.json
  • APIs: APIのインターフェイスごとに一つのファイルがbrowser-compat-data/apiに格納されています。ファイル名は大文字小文字を含めて完全にインターフェイス名と一致させるべきです(SHOULD) 例) WebVR APIにはVRDisplay.jsonVRDisplayCapabilities.jsonなどがあります

Note: このレポジトリにはBrowser ExtensionsHTTPについてのデータも含まれています。基本的にこれらはすでにいじるところはないですが、将来的に追加的に機能を追加する必要があるかもしれません(MAY)

あなたが作成するファイルは、このレポジトリに含まれているスキーマで定義されている構造に従わなければなりません。詳細なスキーマの説明はこちらで見ることができます。

基本的な互換性データの構造

では例を見ていきましょう。例としてCSSプロパティのJSONファイルに求められる基本構造を次に示します。

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

まずcssオブジェクトがあります。その中にpropertiesオブジェクトがあります。propertiesオブジェクトの中には、互換性データとして定義したい特定の機能につき一つのメンバーが必要です。それぞれのメンバーは__compatをメンバーに持ち、この中に実際のデータを記述します。

上記のデータはborder-width.jsonにあります。MDNにある描画されたborder-widthの実装状況の表と見比べてみてください。

他の種類の機能についても同様ですが、ただしオブエジェクトの名前が異なります。

  • CSSセレクターはCSSプロパティと基本的に同様ですが、最上位のオブジェクト構造がcss.propertiesではなくcss.selectorsです。例としてcue.jsonを見てください。
  • HTMLについても基本的に同様ですが、最上位のオブジェクト構造がhtml.elementsです。例としてarticle.jsonを見てください。
  • JavaScriptビルトインオブジェクトについての最上位のオブジェクト構造はjavascript.builtinsです。例としてArray.jsonを見てください。

HTMLやCSS、JavaScriptのページにおいて、普通一つだけの機能について記述するでしょう。しかしAPIインターフェイスについては少し事情が異なります。なぜなら常に複数のサブ機能を持つからです (下の Sub-features を参照してください)。

機能内の基本構造

Inside a feature __compat member, you need to include the following members:

  • 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 /ja/docs/.... 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.
  • false: If a browser does not support a feature, use the value false.
  • null: If you don't know whether a browser supports a feature or not, use the value null.

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.

脚注を含める

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. imagine you had a feature that was supported with a -moz- prefix in Firefox. To specify this in the compat data, you'd need to add a "prefix" submember inside the relevant "firefox" submember. It would look something like this:

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

ブラウザーの設定やフラグを含める

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"
    }
  ]
},

対応が削除されたバージョンを含める

Sometimes a feature will be added in a certain browser version, but then removed again as the feature is deprecated. This can be easily represented using the "version_removed" submember, which takes as its value a string representing the version number it was removed on. For example:

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

同じブラウザーの項目に複数の対応ポイントを含む

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"
  }
],

変更のメインリポジトリへの反映

Once you are finished with adding your compat data, you should first test it using the following commands:

  • npm run lint — tests all the compat data to make sure the JSON is valid, and is written in the correct style, for example correct indentation, no missing commas, etc. It will print out a long list of file names and test results; 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">
The compatibility table on this page is generated from structured data. 
If you'd like to contribute to the data, please check out 
<a href="https://github.com/mdn/browser-compat-data">https://github.com/mdn/browser-compat-data</a> 
and send us a pull request.
</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
デスクトップモバイル
ChromeEdgeFirefoxInternet ExplorerOperaSafariAndroid webviewAndroid 版 ChromeAndroid 版 FirefoxAndroid 版 OperaiOSのSafariSamsung Internet
capabilities
実験的非推奨
Chrome 未対応 なしEdge 完全対応 15Firefox 完全対応 55
補足
完全対応 55
補足
補足 Windows support was enabled in Firefox 55.
完全対応 64
補足
補足 macOS support was enabled in Firefox 64.
IE 未対応 なしOpera ? Safari ? WebView Android 未対応 なしChrome Android 完全対応 56
補足 無効
完全対応 56
補足 無効
補足 Only works in an experimental version of Chrome. (Other builds won't return any devices when Navigator.getVRDisplays() is invoked.)
補足 Daydream View supported in Chrome 56.
補足 Google Cardboard supported in Chrome 57.
無効 From version 56: this feature is behind the WebVR preference. To change preferences in Chrome, visit chrome://flags.
Firefox Android 完全対応 55Opera Android ? Safari iOS ? Samsung Internet Android 完全対応 6.0

凡例

完全対応  
完全対応
未対応  
未対応
実装状況不明  
実装状況不明
実験的。動作が変更される可能性があります。
実験的。動作が変更される可能性があります。
非推奨。新しいウェブサイトでは使用しないでください。
非推奨。新しいウェブサイトでは使用しないでください。
実装ノートを参照してください。
実装ノートを参照してください。
ユーザーが明示的にこの機能を有効にしなければなりません。
ユーザーが明示的にこの機能を有効にしなければなりません。

Note: The filenames often match the labels given to the interfaces inside the JSON structures, but it is not always the case. When the macro calls generate the tables, they walk through all the files until they find the relevant JSON to use, so the filenames are not critical. Saying that, you should always name them as intuitively as possible.