電脳麻将UI 〜 layout

電脳麻将 では以下の端末からのアクセスを想定し、CSSによるレスポンシブデザインで最適な表示になるよう調整しています。

PC画面
横幅が広いことを利用したレイアウトを行う。
スマホ画面
iPhone SE のアスペクト比を基準とし、それより「細い」画面も想定したレイアウトを行う。
タブレット画面
iPad Pro のアスペクト比を基準とし、それより「長い」画面も想定したレイアウトを行う。

スマホとタブレットは viewport の設定で横幅を 800px に固定します*1

<meta name="viewport" content="width=800">

これにより端末の差異を画面の高さでだけ判別できるようになり、描画も 800px を基本とした座標系で行うことができるようになります。画面が縦幅に収まらないことは想定し、その場合は 電脳麻将UI 〜 scale - koba::blog で説明した方法で高さを調整します。

端末の種別は以下の5種類とし、それぞれでレイアウト方法を調整します。

端末種別 想定サイズ
PC画面 1400 x 720 px*2
スマホ画面(縦) 800 x 1400 px
スマホ画面(横) 800 x 450 px
タブレット画面(縦) 800 x 1000 px
タブレット画面(横) 800 x 600 px

各端末種別ごとの画面イメージは以下の通りです。

PC画面


スマホ画面(横)


タブレット画面(縦)

整理すると以下となります。調整が必要な部分を太字で示しました。

端末種別 麻雀卓 ボタン類 検討画面 リンク類
PC画面 標準サイズ 卓内左上 卓外右方 卓外上方
スマホ画面(縦) 標準サイズ 卓外下方卓外下方 卓外上方
スマホ画面(横) 縮小サイズ卓内右端 卓内重畳 卓内重畳
タブレット画面(縦) 標準サイズ 卓外下方卓外下方 卓外上方
タブレット画面(横) 標準サイズ 卓外下方 卓内重畳 卓内重畳

CSSの メディアクエリ を使って端末種別を判定し、以下の調整を行います。

@media screen and (min-width: 820px)
PC画面と判定し、検討画面を再配置する。
@media screen and (min-height: 1000px)
スマホ・タブレット画面(縦)と認識し、ボタン類と検討画面を再配置する。
@media screen and (max-height: 680px)
スマホ・タブレット画面(横)と認識し、リンク類を再配置する*2
@media screen and (max-height: 450px)
スマホ画面(横)と認識し、麻雀卓を縮小サイズ、ボタン類を再配置する。

HTMLは以下の階層をしています。

  body
    #navi
      .navi         /* リンク類(卓外上方) */
    #space          /* 余白 */
    #board          /* 縮小による高さ調整の範囲 */
      .board            /* 麻雀卓 */
      .analyzer         /* 検討画面 */
      .controller       /* ボタン類 */
      .navi             /* リンク類(卓内重畳) */
    .version

具体的なレイアウト設定(Stylus で記述)は以下の通りです*3

body.board
    width: 800px
    margin: 0 auto
    background: black
    color: white
    #board
        display: block
    > .version
        border-top: solid 1px white

body.analyzer
    #board > .analyzer
        display: block

#space
    display: none
    background: #666

#board
    display: none
    position: relative
    .board
        width: 800px
        height: 680px
    .controller
        width: auto
        height: auto
    > .analyzer
        display: none
        position: absolute
        top 0
        transform: translate(50px, 100px)
        width: 700px
        height: 300px
    .navi
        display: none

/* PC画面の差分 */
@media screen and (min-width: 820px)
    body.board
        #board .controller
            position: absolute
            top: 0
            transform: translate(80px, 100px)
            width: auto
            height: auto
        > .version
            border-top: none
    body.analyzer
        width: 1400px
        #board > .analyzer
            position: relative
            transform: none
            width: 590px
            height: 680px
        #board
            .board
                float: left
            > .analyzer
                float: right

/* スマホ・タブレット画面(縦)の差分 */
@media screen and (min-height: 1000px)
    body.analyzer
        #board > .analyzer
            position: relative
            transform: none
            width: auto
            height: 300px

/* スマホ・タブレット画面(横)の差分 */
@media screen and (max-height: 680px)
    body.board
        height: 100dvh
        #navi
        > .version
            display: none
        #space
            display: block
            height: 100px
        #board .navi
            display: block

/* スマホ画面(横)の差分 */
@media screen and (max-height: 450px)
    body.board
        #board
            .board
                height: 450px
            .controller
                position: absolute
                top: 0
                right: 0
            > .analyzer
                transform: translate(30px, 30px)

#board.analyzer はデフォルトでは非表示なことに注意してください。body 要素にクラス board があれば #board を、さらにクラス analyzer があれば .analyzer の非表示をキャンセルします。

以下で実際の動作を確認できます(卓をクリックすると検討画面が開きます)。

*1:800px とするのはPCの解像度と合わせるためです

*2:現在の実装ではリンク類が非表示になっていますが、再配置するようリファクタリング中です

*3:現在リファクタリング中のコードです