bootstrap画面Layout例（初心者今更聞けないいくつか）

# 背景
Html書く時、毎回画面LAYOUTに悩みます。はるか昔tableとgif使いましたが、CSS時代のやり方を勉強しなおし、要点を残し、将来の参考になればと思います。

# 要件
- こんな感じの画面を作りたい。
 - 画面は左右に分け、左側は更に上下に分ける
 - 画面全体はscroll発生しないよう自動調整する
 - 右はjstree使い、項目が多い時画面を突き破ることなく、自分内部でscroll

![rapture_20200715100516.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/32912/0d9e15fe-6635-d5cf-599b-156460b3e6a0.png)
図1：画面LAYOUT想像図

# 利用ツール

- [bootstrap](https://getbootstrap.com/docs/4.5/layout/overview/) ：LAYOUT担当。全体の配置、大きさ、枠線、色を制御。CSSのみ実現されjavascript書く必要ないところが便利。
- [jquery](https://jquery.com/) はjavascript内でhtmlを操作する時便利機能を提供する。今回はADDボタンとjstreeの初期化に利用。今更誰がjquery使うかと思いましたが、調べると意外に。
- [jstree](https://www.jstree.com/) はデータをツリー状表示用ライブラリ。今回動的にアイテムを追加し、画面の高さの影響を確認するために利用する。

![rapture_20200715104547.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/32912/cf6f3172-14aa-35ba-0e27-42d27d2d925c.png)
図２：jqueryは健在


# 基本LAYOUT
まず全体を描く。bootscrapにLAYOUTする方法複数（[grid](https://getbootstrap.com/docs/4.5/layout/grid/)、[float](https://getbootstrap.com/docs/4.5/utilities/float/)、[position](https://getbootstrap.com/docs/4.5/utilities/position/)、[display](https://getbootstrap.com/docs/4.5/utilities/display/)、[flex](https://getbootstrap.com/docs/4.5/utilities/flex/) ）あります。flexは一番柔軟で、中身に合わせて自動で改行されたり、適切に配置できるありますが、今回の要件は固定位置で表示するので、gridを選びました。

```html

<body>
    <div class="container-fluid">
      <div class="row">                  <!-- 行 -->
        <div class="col-8">              <!-- 左側 -->
          <div class="row">
            <div class="col">up</div>     <!-- 上 -->
          </div>
          <div class="row">
            <div class="col">down</div>   <!-- 下 -->
          </div>
        </div>
        <div class="col-4">right</div>    <!-- 右側 -->
      </div>
    </div>
</body>
```

grid layoutは
1. まずcontainerを立てる。container-fluidはcontainerと違って、画面いっぱい使えます。
1. 一つの行（row）
1. 行の中2列（col）がある
2. 全部12分割のうち、左側は８（col-8）、右側は４（col-4）で配置する
2. 更に左側の列の中に２つの行を配置し、それぞれ１つだけ列を持つ

以下の感じになります。
![rapture_20200715113509.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/32912/93fdf0b0-5234-a3e6-e527-8b061801caa6.png)
図３：LAYOUT効果

# 枠線追加
文字以外何もわからないので、枠線を入れる。

```html

<body>
    <div class="container-fluid">
      <div class="row">
        <div class="col-8 border border-warning">　　　　　　　<!-- 枠線 -->
          <div class="row">
            <div class="col border border-warning">up</div>
          </div>
          <div class="row">
            <div class="col border border-warning">down</div>
          </div>
        </div>
        <div class="col-4 border border-warning">right</div>
      </div>
    </div>
</body>
```
以下は効果
![rapture_20200715114022.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/32912/d74b305b-0a1a-36d5-3cd5-c488ac678e3e.png)

更にpadやmarginを微調整する必要なら、[bootstrap](https://getbootstrap.com/docs/4.5/utilities/spacing/)をご参考ください。

# 高さ固定

普通、内容に合わせて、タグの高さが変動します。高さを固定するには、`height`を明示します。bootstrapが提供する `vh-100` （ CSS の `height:100vh;` に相当する）を利用し、window(=viewport)の100% を使います。

もう一つ、`height` をパーセントで指定する時、親タグも `height` を指定が必要です、しないタグが自動拡張され、結局画面を突き破ります。


```html

<body class="vh-100 vw-100">　　　　　　　　　　　　　　　　　<!-- 全体の高さ -->
    <div class="container-fluid h-100 w-100">              <!-- 各層全部高さ設定 -->
      <div class="row h-100">
        <div class="col-8 border border-warning">
          <div class="row">
            <div class="col border border-warning">up</div>
          </div>
          <div class="row">
            <div class="col border border-warning">down
              <button id="add" class="btn btn-success">add</button>
            </div>
          </div>
        </div>
        <div class="col-4 border border-warning h-100">　　　<!-- 各層全部高さ設定 -->
            <div id="jstree" class="h-100 overflow-auto">   <!-- ここの高さ指定したい -->
              <ul>
                <li id="rootnode" data-jstree='{"opened":true,"selected":true}'>Root node</li>
              </ul>
            </div>
        </div>
      </div>
    </div>
</body>
```

#### おまけ
LAYOUTではないですが、jstree使う時、落とし穴を注意ください。

- jstree追加削除など変更したい時、`"check_callback" : true,` は必須
- jstreeのroot nodeに `data-jstree='{"opened":true}` 入れないとツリーが開かない



# 例全体
[jsfiddle](https://jsfiddle.net/izayoi/63401dcu/1/) で試せます。

```html

<!DOCTYPE html>
<html>
  <link rel="shortcut icon" type="image/x-icon" href="https://github.com/favicon.ico">

<link rel="stylesheet" href="https://stackpath.bootstrapcdn.com/bootstrap/4.5.0/css/bootstrap.min.css" integrity="sha384-9aIt2nRpC12Uk9gS9baDl411NQApFmC26EwAOH8WgZl5MYYxFfc+NcPb1dKGj7Sk" crossorigin="anonymous">
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/jstree/3.2.1/themes/default/style.min.css" />
  <head>
    <meta charset="UTF-8">
    <title>jstree bootstrap demo</title>
  </head>

<body class="vh-100 vw-100">
    <div class="container-fluid h-100 w-100">
      <div class="row h-100">
        <div class="col-8 border border-warning">
          <div class="row">
            <div class="col border border-warning">up</div>
          </div>
          <div class="row">
            <div class="col border border-warning">down
              <button id="add" class="btn btn-success">add</button>
            </div>
          </div>
        </div>
        <div class="col-4 border border-warning h-100">
            <div id="jstree" class="h-100 overflow-auto">
              <ul>　                        <!-- ↓↓↓↓　opened指定しないとツリー開けない -->
                <li id="rootnode" data-jstree='{"opened":true,"selected":true}'>Root node</li>  
              </ul>
            </div>
        </div>
      </div>
    </div>
</body>
<script src="https://code.jquery.com/jquery-3.5.1.slim.min.js" integrity="sha384-DfXdz2htPH0lsSSs5nCTpuj/zy4C+OGpamoFVy38MVBnE+IbbVYUew+OrCXaRkfj" crossorigin="anonymous"></script>
<script src="https://cdn.jsdelivr.net/npm/popper.js@1.16.0/dist/umd/popper.min.js" integrity="sha384-Q6E9RHvbIyZFJoft+2mJbHaEWldlvI9IOYy5n3zV9zzTtmI3UksdQRVvoxMfooAo" crossorigin="anonymous"></script>
<script src="https://stackpath.bootstrapcdn.com/bootstrap/4.5.0/js/bootstrap.min.js" integrity="sha384-OgVRvuATP1z7JjHLkuOU7Xw704+h835Lr+6QL9UvYjZE3Ipu6Tp75j7Bh/kR0JKI" crossorigin="anonymous"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/jstree/3.3.10/jstree.min.js"></script>
<script>
  $('#jstree').jstree({
    "core" : {
      "check_callback" : true, // これがないと修正系関数効かない
    },
    "plugins" : [
      "wholerow",
    ]
  });

  $('#add').on("click", function(e, data){
    $('#jstree').jstree().create_node('rootnode', "new item");
  });
</script>
</html>
```