Office UI FabricのResponsive Grid

今回はOffice UI Fabtic(以下"OfficeUI")の[レスポンシブグリッド](http://dev.office.com/fabric/styles#responsive-grid)について解説します(昨日の記事では「レスポンシブルグリッド」と鮮やかに誤表記を決めておりました)。

## レスポンシブグリッド？

まずはそもそもレスポンシブルグリッドって何？という所から話が始まります(筆者の場合)。凛知ってるよ！[「クラウド」の前にバズったキーワード](https://ja.wikipedia.org/wiki/グリッド・コンピューティング)のことだって……と言いたいところですが、Web開発周りのキーワードなのでおそらく他人の空似でしょう。

とはいえ、あらためてレスポンシブグリッドって何？と言われると、そういえば何だろうという気分になってきます。[Responsive Web Design - Grid-View](http://www.w3schools.com/css/css_rwd_grid.asp)のページを見ると、以下のような説明がされています。

 * 多くのWebページはgrid-viewというWebページ内を複数のカラムに分けた形で構成されている
 * grid-viewはWebページ内のデザインに有用
 * grid-vewのカラムはしばしば12等分された形になっており、トータルで幅が100%になる
 * ブラウザウインドウのサイズ変更に合わせて要素がまとめられたり広げられたりする

つまるところ、レスポンシブグリッドを使用したWebデザインにしておくと、ブラウザのウインドウサイズが変更されるようなケースに対応できる、ということですね。おそらくスマートフォンでの閲覧など、図らずも画面サイズが変更されるような状況と同じになった場合でも対応可能なのでしょう。

## OfficeUIのレスポンシブグリッド機能

### OfficeUIのレスポンシブグリッド

レスポンシブグリッドの概要が何となく分かったところで、OfficeUIのレスポンシブグリッド機能を試してみます。先の説明にもありましたが、カラムが12分割される形になっています。

グリッド分割の例を以下に示します。「ms-u-smX」のようなクラスによりカラムの幅を指定できます。

![img200.png](https://qiita-image-store.s3.amazonaws.com/0/61137/00706627-c50e-68a3-640e-f2e4f667757c.png)

上記のサンプルコードは以下のようになります。

```html
<!DOCTYPE html>
<html ng-app="App">
  <head>
    <meta charset="utf-8" />
    <title>Grid Sample</title>
    <link rel="stylesheet" href="//appsforoffice.microsoft.com/fabric/1.0/fabric.min.css">
    <link rel="stylesheet" href="//appsforoffice.microsoft.com/fabric/1.0/fabric.components.min.css">
    <script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.4.8/angular.min.js"></script>
    <style>
      .my-fill { border: thin solid; border-radius: 2px; margin-bottom: 1px; text-align: center; }
    </style>
  </head>
  <body ng-controller="AppController">
    <div class="ms-Grid">
      <div class="ms-Grid-row">
        <div class="ms-Grid-col ms-u-sm6 ms-u-md8 ms-u-lg12">
          <h4>Office UI FabricのGridサンプル</h4>
        </div>
      </div>
    </div>
    <div class="ms-Grid">
      <div class="ms-Grid-row">
        <div class="ms-Grid-col ms-u-sm6 ms-u-md8 ms-u-lg12" ng-repeat="grids in gridList">
          <div class="ms-Grid-col {{grids.className}} my-fill" style="background:{{grids.color}};" ng-repeat="grid in grids.repeatList">
            {{grids.label}}
          </div>
        </div>
      </div>
    </div>
    <script>
      var app = angular.module('App', []);
      app.controller('AppController', ['$scope',
        function($scope) {
          $scope.gridList = [
            { className: "ms-u-sm1",  maxRepeat: 12, color: "#ff7f7f" },
            { className: "ms-u-sm2",  maxRepeat:  6, color: "#ff7fbf" } ,
            { className: "ms-u-sm4",  maxRepeat:  3, color: "#ff7fff" },
            { className: "ms-u-sm6",  maxRepeat:  2, color: "#bf7fff" },
            { className: "ms-u-sm12", maxRepeat:  1, color: "#7f7fff" },
          ];
          for (var i in $scope.gridList) {
            $scope.gridList[i].label = $scope.gridList[i].className.replace(/^.*-/, "");
            $scope.gridList[i].repeatList = [];
            for (var j = 0; j < $scope.gridList[i].maxRepeat; j++) {
              $scope.gridList[i].repeatList.push(j);
            }
          }
        }
      ]);
    </script>
  </body>
</html>
```

### (参考)Bootstrapのレスポンシブグリッド

ちなみに、Bootstrapでもほぼ同じようなレスポンシブグリッド機能が用意されています。表示は以下のようになります。

![img201.png](https://qiita-image-store.s3.amazonaws.com/0/61137/83403240-6f83-13be-f554-5140f2badabf.png)

サンプルコードは以下の通りです(OfficeUIのAdvent CalendarなのにBootstrapのサンプルコード……)。

```html
<!DOCTYPE html>
<html ng-app="App">
  <head>
    <meta charset="utf-8" />
    <title>Grid Sample(Bootstrap)</title>
    <!-- Latest compiled and minified CSS -->
    <link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.6/css/bootstrap.min.css" integrity="sha384-1q8mTJOASx8j1Au+a5WDVnPi2lkFfwwEAa8hDDdjZlpLegxhjVME1fgjWPGmkzs7" crossorigin="anonymous">
    <!-- Latest compiled and minified JavaScript -->
    <script src="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.6/js/bootstrap.min.js" integrity="sha384-0mSbJDEHialfmuBBQP6A4Qrprq5OVfW37PRR3j5ELqxss1yVqOtnepnHVP9aJ7xS" crossorigin="anonymous"></script>
    <script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.4.8/angular.min.js"></script>
    <style>
      .my-fill { border: thin solid; border-radius: 2px; margin-bottom: 1px; text-align: center; }
    </style>
  </head>
  <body ng-controller="AppController">
   <div class="container">
      <div class="row">
        <div class="col-sm-12">
          <h4>BootstrapのGridサンプル</h4>
        </div>
      </div>
      <div class="row" ng-repeat="grids in gridList">
        <div class="{{grids.className}} my-fill" style="background: {{grids.color}};" ng-repeat="grid in grids.repeatList">
          {{grids.label}}
        </div>
      </div>
    </div><!-- container -->
    <script>
      var app = angular.module('App', []);
      app.controller('AppController', ['$scope',
        function($scope) {
          $scope.gridList = [
            { className: "col-sm-1",  maxRepeat: 12, color: "#ff7f7f" },
            { className: "col-sm-2",  maxRepeat:  6, color: "#ff7fbf" } ,
            { className: "col-sm-4",  maxRepeat:  3, color: "#ff7fff" },
            { className: "col-sm-6",  maxRepeat:  2, color: "#bf7fff" },
            { className: "col-sm-12", maxRepeat:  1, color: "#7f7fff" },
          ];
          for (var i in $scope.gridList) {
            $scope.gridList[i].label = $scope.gridList[i].className.replace(/^.*?-/, "").replace(/-/, "");
            $scope.gridList[i].repeatList = [];
            for (var j = 0; j < $scope.gridList[i].maxRepeat; j++) {
              $scope.gridList[i].repeatList.push(j);
            }
          }
        }
      ]);
    </script>
  </body>
</html>
```

## レスポンシブグリッドでのUIコンポーネント配置

レスポンシブグリッドの使用例としてボタンを配置してみます。以下の例ではms-u-sm4のカラムにボタンを配置すると以下のような表示になります。

![img203.png](https://qiita-image-store.s3.amazonaws.com/0/61137/0f159754-22bd-2598-2ec3-a32e0ab1be26.png)

ちなみにBootstrapでは、「form-control」クラスを指定すると以下の例の右側のボタンのようにカラムの横幅いっぱい(少し余白がありますが)にボタンが広がります。これに対し、OfficeUIにはform-control的なクラスは用意されておらず、スタイルシードで「width:100%;」を指定する形になります(表示は上記の右側ボタンのような感じになります)。

![img204.png](https://qiita-image-store.s3.amazonaws.com/0/61137/36c78e59-db65-d5e6-3082-ebf58ce3bde4.png)

## まとめ

今日はOfficeUIのレスポンシブグリットについて解説しました。ほぼ同等の機能がBootstrapでも提供されているため理解しやすい概念ではないかと思います。

明日はOfficeUIのアイコンについて解説したいと思います。

## 参考URL

 * [Responsive Grid](http://dev.office.com/fabric/styles#responsive-grid)
 * [Responsive Web Design - Grid-View](http://www.w3schools.com/css/css_rwd_grid.asp)