全ての画面幅で指定箇所で良い感じの改行を実現するベストプラクティス会議
8分目次
クライアントさんから「ここで改行させないでくれ」という要望受けたことない人って存在するんですかね?もちろん、短いテキストであればギリ朝飯前ですが、長いテキストの改行部分をきっちり指定されるとなかなかフロントの地獄を感じます。
「そんなん言われたことがない」という超幸運の持ち主に要望を説明すると
👆 イケてるブラウザではドラッグで大きさを変更できます(PCのみ)。
この上の図の横幅を大きくしたり縮めてください。その際に例えば極端な例ではありますが「必ずビックリマークの場所で改行してくれ」といった具合です。さらに厄介なことに背景画像との兼ね合いでここの位置で折り返すようにしてくれといった要望も大変多いのです……。「単純に<br />
を挟めばいいじゃん」と思うかもしれませんね。<br />
で区切ったものが下です。
全てのサイズでこの(👇)ようになっている分にはいいです。要件が満たせています。
ただ現実は甘くありません……これ(👇)……。
……この気持ち悪さわかりますか?あるサイズまでは当然きれいに表示されますが、ひとたび小さい画面で見たときに改行が鬱陶しく感じてしまうことがあるんですよね。また、これではクライアントさんの「必ず(=どの画面幅でも)ビックリマークの場所で改行してくれ」という要件にも応えられていません。なので<br />
以外のアプローチか、<br />
と+αのアプローチを取る必要があります。
もうこの時点で頭を抱えるレベルですごく面倒。さらに悪いことにどんなアプローチを取ったとしてもテキスト修正時にめっぽう弱い。つまり保守性の弱さがやりたくない理由として挙げられます。文字数や文字内容が変われば気持ちよく区切れる箇所も変わってきますからそのたびにコードの編集を余儀なくされます。……と、いった具合に良いことは全くない一方、デメリットは枚挙に暇がなく、結果として得られるものはクライアントさんの自己満足だけだったりします(もちろんABテストの上でその改行がなければCV落ちるなどのデータがあればまだ理解できますが)。
「今は様々なデバイスサイズがあってそのどれもで違和感ないように改行箇所を指定するのは現実的に難しいのです……」と伝えて「はいそうですか」と納得してくれる物わかりのいい人もいれば、「いーや、絶対ここで改行させたい」というこだわりの強い人もいます。難しいとはいうものの、もちろん技術的に可能なことではあるので、個人的なベストプラクティスはこれに落ち着いたという備忘録です。
画像やJSを使うという手ももちろんありますが、CSSで解決する問題はCSSで解決したいなぁということで今回はCSS縛りの方法です
方法1: font-sizeのvw指定とbrタグをメディアクエリで表示切り替え
個人的にはこれかなぁと。のちに紹介する方法2も同様ですが、画面幅によって文字サイズを変更する以外に思いつく方法がありません。
p{
font-size: 5vw;
}
こうすればCSSもそこまで複雑化せずに画面幅によって固定の位置にテキストを取ることが可能です。あとは必要に応じて<br />
を入れればOKですがこのbreakタグにもpc、tab、spなどで画面幅によって表示切り替えできるクラスなど当てるといいですね。
<br class="pc" />
<br class="tab" />
<br class="sp" />
@medeia(max-width: 980px){
.pc{ display: none; }
}
@medeia(max-width: 481px)and(min-width: 981px){
.tab{ display: none; }
}
@medeia(min-width: 481px){
.sp{ display: none; }
}
👆 例としてこんな感じですね。
この方法のデメリット
- font-sizeでは最小限(min)サイズと最大(max)サイズが出せないため、メディアクエリ で細かく定義する必要がある
- font-sizeをvw指定するのがなんとも気持ち悪い
- テキストの修正案がきたときに計算し直す必要がある
1. font-sizeでは最小限(min)サイズと最大(max)サイズが出せないため、メディアクエリ で細かく定義する必要がある
例えばChromeでは10px未満は読みづらいとしています(そのため10px未満のフォントも強制的に10pxで表示される)。といった具合にあまりに大きすぎたり小さすぎるフォントは可読性やデザインを破壊しかねない原因になり得ます。そこで、下記のようなCSSを書く必要が出てくるわけですが
.iketeru__text{
font-size: 5vw;
}
@media(max-width: 480px){
.iketeru__text{
font-size: 10px;
}
}
@media(min-width: 1024px){
.iketeru__text{
font-size: 30px;
}
}
デザインによってはきれいなメディアクエリ指定ができない可能性もありますね(この背景画像のここら辺までしかテキストを表示させたくないみたいなパターンとかとか)。そうなると
.iketeru__text{
font-size: 5vw;
}
@media(max-width: 372px){
.iketeru__text{
font-size: 12px;
}
}
@media(max-width: 363px){
.iketeru__text{
font-size: 11px;
}
}
@media(max-width: 340px){
.iketeru__text{
font-size: 10px;
}
}
@media(min-width: 1150px){
.iketeru__text{
font-size: 30px;
}
}
@media(min-width: 1211px){
.iketeru__text{
font-size: 32px;
}
}
@media(min-width: 1290px){
.iketeru__text{
font-size: 34px;
}
}
地獄が爆誕します。肌が粟立つほど気持ち悪くないですか、これ。。
2. font-sizeをvw指定するのがなんとも気持ち悪い
気持ち悪いですよね、わかります。けどこれ以外どうしろってんだ。
3. テキストの修正案がきたときに計算し直す必要がある
vwで細かく調整してやっと任意の位置での改行に成功するも束の間。テキストの修正が来たときにははらわたが……。
方法2: font-sizeをcalcで画面幅ごとに変更しbrタグをメディアクエリで表示切り替え
画面幅によって文字サイズを可変させるコードがあります。それが下記です。
@media (min-width: 320px) {
p{
font-size: calc(0.625rem + ((1vw - 3.2px) * 4.5455));
min-height: 0vw;
}
}
@media (min-width: 1400px) {
p{
font-size: 50px;
}
}
320pxから1400pxまでの画面幅のときに14px〜40px間を推移するコードです。ちなみにこの計算式はFluid-responsive font-size calculatorというサイトで生成できます。
この方法のデメリット
- 他の人が見たときコードが複雑怪奇(保守性が最悪)
- テキストの修正案がきたときにかなり面倒な計算し直し作業がある
1. 他の人が見たときコードが複雑怪奇(保守性が最悪)
計算式にvwの単位が使われていることから画面幅ごとにフォントサイズが推移することはなんとなく分かるかと思いますが、それ以上のことは何もわかりません。コメントでフォントの大きさが可変であることを書いたとしても、どこをどのようにいじればいいかはまるでわかりません。保守性が最悪なこと極まりないですね。
2. テキストの修正案がきたときにかなりめんどな計算し直し作業がある
これも同じですね。ただ、vwの方が楽な気がするので僕はvwに落ち着いたわけです。
まとめ
わかりやすく課題を用意しました。
- 上の赤線の中に
Amazing Message Layout Powered by MonsterCSS
のテキストを収める - テキストの両端が赤線にぴったり沿う
- Layoutで折り返す
- 保守性(可読性)を考慮すること
- 赤線は画面幅によって可変する 上記条件での課題です。
僕は上のCSSの通りなのですがこれ以外に綺麗なコードは果たしてあるのだろうか。他に良い方法あったら切実に教えてもらいたい。