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


背景

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

要件

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


図1:画面LAYOUT想像図

利用ツール

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


図2:jqueryは健在

基本LAYOUT

まず全体を描く。bootscrapにLAYOUTする方法複数(gridfloatpositiondisplayflex )あります。flexは一番柔軟で、中身に合わせて自動で改行されたり、適切に配置できるありますが、今回の要件は固定位置で表示するので、gridを選びました。


<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分割のうち、左側は8(col-8)、右側は4(col-4)で配置する
2. 更に左側の列の中に2つの行を配置し、それぞれ1つだけ列を持つ

以下の感じになります。

図3:LAYOUT効果

枠線追加

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


<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>

以下は効果

更にpadやmarginを微調整する必要なら、bootstrapをご参考ください。

高さ固定

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

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


<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 で試せます。


<!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/[email protected]/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>