“Writing-mode”で縦書きを実装してみた

2017.05.04

流通しているjsで解決したり、縦書きそのものを諦めるという手段もありましたが、どうしてもCSS主体で実装してみたかった……。そこら辺の事情と実装の実態とをまとめてみました。

この記事は 約 11 分で読めます。

,

“writing-mode”で縦書きにしたかった理由

端的に言えば、以下の3つ。

  1. 自社のメディアサイトを形にしたかった
  2. 読む速度というのも、デザインしてみたかった
  3. SEOへの配慮やブラウザごとの違いも対策したかった

どうせメディアサイトを作るなら、「縦書き&明朝体」で作りたかった。「見せる」より「読む」あるいは「読ませる」。そのためのメディアサイトを立ち上げたかったというのが、縦書きにこだわった理由の一つ。だから、今回立ち上げたサイトには装飾はあまり施していない。どう見せるかで言えば、だいぶレトロな雰囲気、日に焼けた新聞紙や文庫本をイメージした体裁を目指したつもりではある。

自分自身、横書きの書籍よりも縦書きの書籍の方が好み。教科書や専門書以外では、横書きの書籍より縦書きの書籍の方が数段格上に思えるイメージがあるし、何より日本語はやはり縦書き向きにできているように思う。日本人の物書きとしては、「縦書き&明朝体」で読んでもらえるようにしたかったという想いが根底にあった。

また、これは実際にエビデンスがある話ではないのだけれども、横書きの文章よりも縦書きの文章の方が読む速度が遅くなる、ような気がしている。目の形や筋肉の動きもあるのだろうけど、横の方が読み飛ばしやすく、パッ、パッと文章を追いかけてしまう感覚がある。それに比べると、縦書きの方はどうしても遅くなる。速読的な手法で先の文章を見ながら読むというテクニックもあるものの、単純な速度で行けば横の動きには劣るはず。(科学的、生物学的な根拠はないので、「はず」としか言えない)

遅いより早い方がいいのではないか、と思われるかもしれないが、遅くなることでじっくり読んでもらえるという可能性も出てくる。というよりは、パパッと読み飛ばしてもらいたくないから、縦書きを選んだ。(という部分の、デザイン性まで汲んでもらえれば万々歳)

行間を読んでもらいたい、じっくり奥行きのある文章を楽しんでもらいたい。そういう想いもあって、あえて「遅く読まざるを得ない」縦書きを目指してみた。とはいえ、横書きには横書きのメリットもあるだろうし、Webというのはどうしても「横」の文化だから、本文にあたる部分以外はおおよそ「横」のままにしてある。

三つ目の理由は、流通しているjsを使わない理由に当たる。表示速度としては、自分の作ったものも大して変わらないが、処理の仕方にどうも癖があるらしい。ただただ、縦書きで表示すればいいというのではなく、Webサイト、Webメディアとして成長させていきたいという想いはある。捨てる気はさらさらない。

だから、jsで対策したからOKとばかりに、「Firefoxでは〜」とか「商用利用はNG」、「回り込みには〜」や「一文字ずつrotate」を認めるよりは、”writing-mode”で生じる問題に向き合って、一つ一つ解決していこうと思ったのが、「”writing-mode”での縦書き」にこだわった理由だろうか。

そもそもの、”writing-mode”とはなんなのか。

CSSのパラメータの一つ。対応状況や何ができるかは他のサイト、特に縦書きWeb普及委員会を見ていただければ幸い。早い話、左から右へ書く欧文的な横書き以外の言語にも対応しようという動きの一つ。これを使えば、同じ横書きでも右から左というのもできるし、もちろん上から下へという縦書きも可能になる。

まだまだ、各ブラウザごとの対応がバラバラだったり、痒い所に手が届くほどのものにはなっておらず、実験的なパラメータ、タグであるのは間違いない。これを使って縦書きをやってみる。

縦書きにするなら、”writing-mode: vertical-rl;”

傍線の扱い、英数字の扱い、文章の流れる方向やブラウザごとのベンダープレフィックスなど、細かい話は先ほどの縦書きWeb普及委員会辺りをご覧いただいて、ご利用ください。それでも基本的には、CSSに”writing-mode: vertical-rl;”で縦書きにはなる。classなりに指定してもいいし、”style=”みたいにhtmlに書いてもいい。

ただ、この「縦書きにはなる」が相当な曲者で使いこなすには案外骨が折れる。どういうことかは使っていただくのが一番早いのだけれども、分かりやすく言えば、「色んなCSSパラメータを改めて設定する必要がある」。厳密な表現ではなく、一部は親要素の設定を引き継いでくれるのだけれども、widthやheight、text-alignなんかは割と無視されがち。デザインが崩れそうでしょ?

じゃあどうするのか、を2つに分けてお答えする。

Writing-modeで縦書きにしたい要素が、サイズ固定の場合

ナビゲーションのボタンを、画像でなくテキストでやりたい、とか。あるいは特定の要素の中が縦書きになればいい、とか。あるいは、「多少崩れても問題ない」ケースもどちらかというとこっちかな。

使うポイントを絞ってご利用すれば、OK

サイズが固定なら、”writing-mode: vertical-rl;”を指定する要素のwidth、heightも指定してあげてください。もしくは、その中の要素をインライン要素でマークアップして、そこだけが縦書きになるように、”writing-mode: vertical-rl;”を指定してください。

例えば、「縦書きにしたいナビゲーション」があるのなら、navタグやulタグに”writing-mode: vertical-rl;”を指定するのではなく、その中の、リンクテキスト(=aタグ)に、”writing-mode: vertical-rl;”を指定してあげる方が、表示の制御もしやすくて便利です。

“writing-mode: vertical-rl;”で文章の方向性は制御できますが、要素の順番なんかは、”float”やFlexbox、”display:inline”などで工夫された方が事故りません。使いたい要素をぐっと絞って使ってください。

また、ブラウザごとに若干挙動が異なりますが、CSSで”column-width”と”column-count”も指定してあげてください。Firefox系とWebkit系とで挙動が変わるのですが、要素のwidthとheight、はみ出して欲しくない横幅に”column-width”、コラムを何分割するのかを”column-count”で指定しておくと、大きく崩れることを防げます。サイズ固定なら、これだけである程度の悲劇は防げます。

問題は、サイズが固定ではないブログの本文みたいな部分を縦書きにしたい時。これも、一応なんとかしました。それが、次。

サイズが流動的な部分は、”js”が必須

ブラウザごとに挙動が相当異なることや、Writing-modeがいかに厄介かが分かるのが、こちらのケース。ここはポリシーを曲げて、流通している縦書き実現jsに頼ってもいいかもしれません。

仮面ライター通信でも、jsで対処しましたが、その経緯も一応ご説明しておきましょう。

Firefoxの比較的新しいものでは問題ないのですが、Webkit系のブラウザでは、writing-modeを指定した要素は、どうやら”float”や、”position:fixed”を指定した要素のように、ちょっと特殊な扱いを受けているようなのです。writing-modeを指定した親要素にwidthが指定してあっても、column-widthが未指定ならそのまま横へはみ出していきますし、column-widthを指定してあげて、”column-count:1″とでも指定して横幅をはみ出さないようにしてあげても、今度は下の要素と重なっていきます。

“column-height”というパラメータは指定できないのですが、どうやらそういう枠(=column?)以外は確保しないようで、column-widthで折り返せるようになっても、上手くいかない、と。何度かWebインスペクタで見てみても、高さ情報を保有していなかったようなので、割と長い時間悩んでしまいました。

が、”writing-mode”を設定した子要素、例えば、


<div class="tategaki">
  <p class="tategaki-inner">縦書きの中身</p>
</div>

“tategaki-inner”の横幅はどうも保有されているらしい、と。だったら、中身の”tategaki-inner”は、親要素である”tategaki”の横幅の何個分なのかを算出し、その分だけ”tategaki”の高さを動的に確保してあげれば対処できるのではないか、というところでjsを組んで実装してみたのが、仮面ライター通信の個別のダミー記事になります。

実際の不細工なjsはこちら。


$(window).on('load resize',function(){
	var ua = navigator.userAgent.toLowerCase();
	var ver = navigator.appVersion.toLowerCase();
	// Google Chrome
	var isChrome = (ua.indexOf('chrome') > -1) && (ua.indexOf('edge') == -1);
	// Firefox
	var isFirefox = (ua.indexOf('firefox') > -1);
	// Safari
	var isSafari = (ua.indexOf('safari') > -1) && (ua.indexOf('chrome') == -1);
	if(!isFirefox) { // Firefoxは特に問題がなかったので、それ以外
		var box = $('.write-h'); // 縦書きを指定したclass
		box.wrapInner('<div class="write-inner"></div>'); // 中身のパラメータを取るため、子要素として囲む
  		var inner = $('.write-inner');
  		var gap = 14; // column-gapの高さ 動的に取った方がカッコイイけども、1rem = 14pxの設定だったので... ^^;
  		var boxh = box.outerHeight() + gap; // 外側の高さ + column-gap
  		var colh = (box.outerHeight() + "px");

  		var h = ((Math.ceil(inner.width() / box.width()) * boxh) - gap + "px"); // 最後のgap分は不要なので
  		box.parent().css("height",h).css("display","-webkit-box").css("display","-ms-flexbox").css("display","flex");
  		box.css("height",colh); // column-count:1 で綺麗にやりたかったので、columnの高さ、writing-modeを指定した要素の高さを指定。最後に指定しないと上手くいかないらしい、というのもここで設定した理由
	}
});

あくまでも、仮面ライター通信で丁度よくなるように組んだものなので、これで上手くいかなくてもご容赦ください。

“write-h”より”write-v”の方がそれっぽいclass名だったなと思いつつ、自分の恥ずかしい部分も隠さずに晒しておこうかと。これぐらいの情報を書いておけば、もっと腕のある人たちがブラッシュアップしてくれるでしょうし、”writing-mode”で縦書きを組んでみようとする人へのヒントにもなるのではというところで、本記事を締めたいと思います。codeも少なく、読みにくい解説でスンマセンm(_ _)m。

執筆者プロフィール

長谷川雄治(はせがわ・ゆうじ)

物書きな作れるWebコンサルタント。
HTML/CSSのマークアップやWordPressのカスタマイズ案件を経験し、サービス構築やブランディング、サイト設計や戦略プランニング、各種原稿、書類作成まで担う。
独自色の強いコンテンツマーケティングの人という立ち位置も見出だしつつあり、不足しているものを補うべく、日々実践中。

2017.05.04

2018.04.30

Loading...
Facebook Messenger for Wordpress