2017/04/06

HTML/CSSだけで縦書きの入力フォームをつくる

和風サイトを開発しようと思い立ち、「もちろん“和風”なんだから縦書きでしょ!」と安易な気持ちで始めたのだが、かなり苦労したのでここにまとめておく。

heading(h1タグやh2タグ)やparagraph(pタグ)などの通常のテキストは、writing-modeプロパティにvertical-rlを指定するたけで簡単に縦書きにできる。
しかし、入力フォーム(inputやtextarea、select、button)はwriting-modeプロパティの指定だけでは縦書きにできなかった。

そこで、HTMLとCSSだけで縦書きの入力フォームをつくる方法をまとめる。(かなり脳筋なやり方だけど)

writing-mode とは


まずは縦書きにするもっとも簡単な方法であるwriting-modeプロパティについて。

writing-mode プロパティは、テキストの行のレイアウトを水平または垂直に、ブロックの流れる方向を左向きまたは右向きに定義します

このプロパティは、ブロックの流れる方向 を指定します。これは、ブロックレベルのコンテナが積まれる方向と、インラインレベルのコンテンツがブロックコンテナ内で流れる方向です。このように、writing-mode プロパティはブロックレベルのコンテンツの順序も決定します。
writing-mode - CSS | MDN
テキストだけでなく、ブロックの流れる方向も変わるところがポイント。

writing-modeプロパティには、以下の5つの値が設定できる。

  • horizontal-tb
    • もっとも一般的な値(デフォルト)
    • 左から右、上から下へ流れる
  • vertical-rl
    • 国語の教科書や文庫本のような体裁
    • 上から下、右から左へ流れる
  • vertical-lr
    • 上から下、左から右へ流れる
  • sideways-rl
    • horizontal-tbを右に90度傾けた形
    • 2017/04/6時点では、Firefox43以上のみ対応
  • sideways-lr
    • horizontal-tbを左に90度傾けた形
    • 2017/04/06時点では、Firefox43以上のみ対応

tbはtop-bottom、rlはright-left、lrはleft-rightを略したものになっている。
詳しくは、下図を参照ください。



入力フォームを縦書きにする


writing-modeプロパティについて理解できたところで、本題となる「入力フォームの縦書き化」を行う。まずは普通にHTMLを書く。
この時点では縦書き・横書きを意識しなくても大丈夫。
<!-- index.html -->
<form class="vertical-form">
  <div class="field">
    <label class="label" for="name">名前</label>
    <input id="name" class="inputfield" type="text" placeholder="山田 太郎">
  </div>
  
  <div class="field">
    <label class="label" for="message">用件</label>
    <textarea id="message" class="inputfield" placeholder="用件をかいてください"></textarea>
  </div>
  
  <div class="field">
    <button type="submit">送信</button>
  </div>
</form>


次に、先ほど紹介したwriting-modeプロパティを使って、ラベルを縦書きにし、ブロックを右から並ぶようにする。
この際、inputやtextarea、buttonは縦書き(縦向き)にならないので注意。
※ サンプルではSCSSを使っているが、CSSプリプロセッサを使わなくてもOK
/* style.sass */
form {
  writing-mode: vertical-rl;
  > .field {
    > .label {
      display: block;
    }
  }
}


このままだと、inputやtextarea、buttonが縦書き・縦向きになってくれないので、transform: rotateを使って無理やり向きを変える。
向きを変えるとフィールドの右側に隙間ができてしまうので、margin-rightを使って調整する。
/* style.sass */
form {
  writing-mode: vertical-rl;
  
  > .field {
   width: 80px;
 
    > .label {
      display: block;
    }

    > .inputfield {
      writing-mode: initial;
      transform: rotate(90deg);
      transform-origin: top left;

      width: 120px;
      height: 20px;
      margin-right: -140px;
    }
    
    > button {
      writing-mode: initial;
      transform: rotate(90deg);
      transform-origin: top left;

      width: 80px;
      height: 30px;
      margin-right: -80px;
    }
  }
}

入力フィールドにはwriting-mode: initialを指定すると、入力した際のテキストやplaceholder、ボタン名が縦書きになってくれる。
(詳しい理由はわかっていないので、ご存知の方は教えてください。)

また、transform-originプロパティにtop leftを指定し、左上を中心に90度rotate(回転)させる。
すると、入力フィールドの右側に隙間ができるので、margin-rightでネガティブマージンを使って隙間を調整する。



これで縦書きの入力フォームの完成!

もっとスマートな方法があると思うのだが、私には見つけられなかった。
他に良い方法があったら、ぜひ教えてください。


以上



written by @bc_rikko

3 件のコメント :

  1. はじめまして。縦書きのフォームの記事、とても参考になります!
    質問なのですが、こちらiPhoneでの対応方法はご存知でしょうか...!
    iphoneだとフォームの中の文字が横向きになったままで、苦戦しています。
    もしご存知でしたら教えて頂きたいです。

    返信削除
    返信
    1. コメントいただき、ありがとうございました!

      手元にiPhoneがないので試せないのですが、MDNやCan I useを見る限りiOSも対応しているようです。
      https://developer.mozilla.org/en-US/docs/Web/CSS/writing-mode
      https://caniuse.com/#search=writing-mode

      おそらくiOSやAndroidの場合はベンダープレフィックスが必要になると思いますので、付けて試してみてください。
      ```
      /* 例 */
      -webkit-writing-mode: vertical-rl;
      ```

      削除
    2. あ、ごめんなさい。フォームの中が横向きのままということですね。

      フォーム内はtransformをつかって無理やり回転させてます。
      ですので、こちらもベンダープレフィックスをつけてみてください。

      ```css
      /* 例 */
      -webkit-writing-mode: vertical-rl;
      -webkit-transform: rotate(90deg);
      ```

      削除