CSSのボックスモデルにおける古い方法とこれからの方法 -論理プロパティにおける考え方
Post on:2019年1月10日
現在のところ、margin-top, padding-bottomのように物理プロパティをボックスモデルで使用していると思います。しばらくはそのままで問題ないですが、CSS GridやFlexboxで使われている論理プロパティを使用する機会が増えるでしょう。
CSSの論理プロパティにおける考え方、注意点、そして英語や日本語など言語で変化する使い方について紹介します。
New CSS Logical Properties!
by Elad Shechter
下記は各ポイントを意訳したものです。
※当ブログでの翻訳記事は、元サイト様にライセンスを得て翻訳しています。
訳者注: 記事内の日本語サイトとは横書きではなく、縦書きが想定されています。
はじめに
わたし達デベロッパーのほとんどが、leftとright、topとbottom、という観点から考えていました。これはインターネットの初期の頃はテキスト主体のものが多かったためで、今日存在する複雑なWebサイト構造を目的としたものではありません。
そして多くの人が多言語Webサイトのニーズを考慮していませんでした。
これからのCSSは、論理プロパティに。
最近まで、RTL/LTR対応Webサイトのような複数の方向を持つWebサイトをサポートする最良の方法はSASSとSASS変数を使用することでした(もっと詳しく知りたい方は、私の記事「The Best Way to RTL Websites with SASS!」を読んでください)。
CSSは新しい論理プロパティにより、使用する言語の種類(英語・アラビア語・日本語など)に関係なく、最小限のスタイルの変更で、Webサイトを制御するための強力な機能が得られます。
それでは始めましょう!
CSSの論理プロパティにおける考え方
CSSのボックスモデルについて説明する時、下記のような図がよく使用されます。
ボックスモデル(物理プロパティ: 古い方法)
確かにこの図は当時は正しいもので、もちろん今でもそうですが、margin-left, padding-right, border-topのような古い物理プロパティは最後の日がくるかもしれません。
新しい論理プロパティを使い始めるには、left/rightやtop/bottomについて考えるのをやめて、それらをinline-start, inline-end, block-start, block-endに置き換える必要があります。
ボックスモデル(論理プロパティ: 新しい方法)
インライン軸
英語を例にしましょう。読む方向は左側から始まり、右側で終わります。これはプロパティのインライン要素です。「display: inline;」で配置された要素を考えるとき、想像するのはとても簡単です。各アイテムは行に沿って表示されます。
例えばpadding-inline-startだと、言語が始まる側のpaddingになります。
-
- 英語の場合
- padding-inline-startは、padding-leftと同じ
-
- アラビア語の場合
- padding-inline-startは、padding-rightと同じ
-
- 日本語の場合
- padding-inline-startは、padding-topと同じ
ブロック軸
topとbottomのプロパティだと、topがWebサイトの始まり、bottomが終わりです。覚えておくのは非常に簡単です。「display: block;」の要素が複数上から順に積み重なっていると想像してみてください。
あなたはこう思うかもしれません。
常にそうなりませんか?
正確に言うと、もう少し複雑です。
現時点では他の方法を利用できなかったため、すべてのWebサイトはすべての言語で上から順に積み重なります。
日本語およびその他の東部言語で書かれたWebサイトは、上から下ではなく、右から左に始まります。これを理解するためはに、スクリーンを右に90度回転させることを想像してください。Webサイトのスクロールは垂直ではなく、代わりに水平になります。
-
- 英語・アラビア語の場合
- padding-block-startは、padding-topと同じ
-
- 日本語およびその他の東部言語の場合
- padding-block-startは、padding-rightと同じ
日本語の場合、水平スクロールに
新しいボックスモデルのプロパティ
インラインとブロック軸を理解したと思うので、新しいボックスモデルのプロパティを確認しておきましょう。
英語の場合、プロパティは下記のようになります。
- margin
-
- margin-block-start = margin-top
- margin-block-end = margin-bottom
- margin-inline-start = margin-left
- margin-inline-end = margin-right
- padding
-
- padding-block-start = padding-top
- padding-block-end = padding-bottom
- padding-inline-start = padding-left
- padding-inline-end = padding-right
- border
-
- border-block-start = border-top
- border-block-end = border-bottom
- border-inline-start = border-left
- border-inline-end = border-right
論理ディメンション
widthとheightのプロパティもこの新しい方法に合わせて対応する必要があります。インラインとブロック軸を理解したら、ディメンションを理解するのも簡単です。英語では、widthプロパティはinline-sizeに、heightプロパティはblock-sizeに置き換えます。
英語・アラビア語の場合(LTR/RTL)
- widthは、inline-sizeに
- heightは、block-sizeに
日本語のように上から下の言語の場合、逆になります。
- widthは、block-sizeに
- heightは、inline-sizeに
min/maxは、プロパティの開始時にmin/maxを追加するだけです。
- min-inline-size: 300px; max-block-size: 100px;
ボックスモデルの古いプロパティと新しいプロパティ
positionの新しい値
positionプロパティは以前の値(top/right/left/bottom)は、新しい名称(inset-block-start/ inset-inline-end/inset-block-end/inset-inline-start)に変わります。すべて接頭辞insetが付いています。
英語の場合(LTR)
- topは、inset-block-startに
- bottomは、inset-block-endに
- leftは、inset-inline-startに
- eightは、inset-inline-endに
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 |
/* 古いプロパティで記述した場合 */ .popup{ position:fixed; top:0; bottom:0; left:0; right:0; } /* 新しいプロパティで記述した場合 */ .popup{ position:fixed; inset-block-start:0; /*top - 英語の場合*/ inset-block-end:0; /*bottom - 英語の場合*/ inset-inline-start:0; /*left - 英語の場合*/ inset-inline-end:0; /*right - 英語の場合*/ } |
一見すると、なぜこんな複雑な名称に変更したのか疑問に思うかもしれません。しかし、それには理由があります。
新しい名称では、padding/margin/borderに似た方法で組み合わせることができます。これは、positionにこれまで存在しなかった新しい機能です。
1 2 3 4 |
.popup{ position:fixed; inset:0 0 0 0; /*top, right, bottom, left - 英語の場合*/ } |
古いプロパティだと、下記のようになります。
古いプロパティの場合
そして、新しいプロパティは、下記のようになります。
新しいプロパティの場合
floatの新しい値
floatはとても簡単です。left/rightの値をinline-start/inline-endに置き換えるだけです。
英語の場合(LTR)
- float: left;は、float: inline-start;に
- float: right;は、float: inline-end;に
text-alignの新しい値
floatよりも簡単で、left/rightの値をstart/endに置き換えます。
英語の場合(LTR)
- text-align :left;は、text-align: start;に
- text-align :right;は、text-align: end;に
その他の新しい値
resizeプロパティ: 主にtextareaに使用され、その値はhorizontal/verticalをinline/blockに置き換えます。
英語の場合(LTR)
- resize: inline;は、resize: horizontal;に
- resize: block;は、resize: vertical;に
background-position: どのブラウザにもまだ実装されていませんが、MDNを見ると、background-position-inlineとbackground-position-blockが用意されています。しかし、まだ完全なドキュメントはありません。
備考: transform-originプロパティなども同時に実装されると想定できます。
CSS GridとFlexbox
CSS GridとFlexboxの素晴らしいニュースは、これら2つはすでに論理プロパティの新しい方法で実装されているため、変更する必要がないことです。
論理プロパティを使用したワークフロー
最初は複雑に見えるかもしれませんが、これらの値を使うことは非常に簡単です。スタイルを書いている間、言語間サポートについて心配する必要はありません。
古い物理プロパティの代わりに、論理プロパティを使用して、それらをあなたの好みの言語に合わせます。
言語に応じた配置の適用
ブロック軸の配置(Webサイトの流れ)とインライン軸の配置(テキストを読む方向)を定義できる2つのプロパティを解説します。
writing-modeプロパティ(ブロック軸)
Webサイトの流れを定義します。ほとんどの場合、上から下になりますが、前述のように、特定の言語は右から左(日本語)、さらには左から右(モンゴル語)に流れることがあります。どちらの場合も垂直スクロールではなく、水平スクロールになります。
備考: 現在のところ、writing-modeには3つの値があります。これらの名称は少し紛らわしいものとなっています。その理由としては、その名称にはブロック軸の方向があり、さらにその場合のテキストの配置(インライン軸)がどうなるかということです。テキストの配置は冗長であり、混乱を招くだけなので、これは明らかにイライラするものです。
この混乱を避けるために、値のインライン軸部分を無視し、値のブロック軸部分のみを参照することをお勧めします。
writing-modeプロパティの値
- writing-mode: horizontal-tb;は、上から下に(英語)
- writing-mode: vertical-rl;は、右から左に(日本語)
- writing-mode: vertical-lr;は、左から右に(モンゴル語)
私の個人的な意見としては、潜在的な混乱をなくすために、値に含まれるのはtb/rl/lr(ブロック軸部分)だけであることを望みます。
日本語の定義例を見てましょう。
1 2 3 |
html{ writing-mode: vertical-rl; } |
それぞれ下記のようになります。
writing-modeプロパティの値とスクロールの方向
directionプロパティの値(インライン軸)
directionプロパティはテキストを左から右へ開始するか、右から左へ開始するかを定義します。ただし、デフォルトのwriting-modeプロパティがアクティブの場合に限られます。writing-modeを縦書きに定義すると、テキストの方向(左から右)は上から下に変わります。あるいは、anrtl(右から左)値では、下から上に変わります。
アラビア語の定義例を見てましょう。
1 2 3 |
html{ direction: rtl; } |
この定義をするだけで、上から下のWebサイトを水平スクロールの右から左のWebサイトに変換されることは驚くべきことです。
この動作が確認できるデモを作成しました。
Firefoxがベストビューです。プルダウンで言語を変更してみてください。
See the Pen Logical Properties by Elad Shechter (@elad2412) on CodePen.
ブラウザのサポート
- ボックスモデルのすべてのプロパティ(margin/padding/border)、および新しいwidth/height(inline-size, block-size) プロパティは、Edgeを除くすべての主要ブラウザで機能します。
- text-alignの新しい値は、Edgeを除くすべての主要ブラウザで機能します。
- float/position/resiezeの新しい値は、Firefoxのみで機能します。
論理プロパティに関する注意点
これらの新しい方法が原因で、わたし達は新しい問題に直面することになります。例えば、marginのすべてのプロパティをショートハンドで記述すると「margin: 10px 20px 8px 5px;」となり、どのように解釈されるのか予測できません。Webサイトが物理プロパティの場合、値は「margin-top/margin-right/margin-bottom/margin-left」と解釈されます。そして論理プロパティの場合は「margin-block-start/margin-inline-end/margin-block-end/margin-inline-start」と解釈されます。
英語のサイトであれば、物理プロパティと論理プロパティは同じに機能します。しかし、他の言語のサイトであれば、marginのようにショートハンドを使うと、directionプロパティまたは新しいプロパティwriting-modeに従って機能します。
これはまだ未解決の問題です。私はGithubのcsswg-draftにこの問題を解決することができる提案を加えました。より良い解決策があると思われる場合は、そこにコメントすることができます。
とりあえずの解決策としては、論理プロパティを使用したい場合は、ショートハンドを使用せずに完全なプロパティ名を記述する必要があります。
オプションの解決策
1 2 3 4 5 6 7 8 9 10 |
html{ flow-mode:physical; /*or*/ flow-mode:logical; } .box{ /*flow-modeの値に従って解釈される*/ margin:10px 5px 6px 3px; padding:5px 10px 2px 7px; } |
レスポンシブデザインの問題
完全に機能するデモを作成しようとした時、メディアクエリでmax-widthの新しいプロパティmax-inline-sizeを使用しようとしました。しかし、それはmax-widthのように振る舞い、日本語のような言語ではmax-heightのように振る舞います。残念ながら、ブラウザは現在メディアクエリでこのプロパティを解釈していません。
1 2 3 4 5 6 7 |
/*機能しない*/ @media (max-inline-size:1000px){ .main-content{ background:red; grid-template-columns:auto; } } |
考慮すべき変更
私がこの記事を書いたとき、論理プロパティのコンセプトを詳しく学んで理解した後、まだ見つからないものがありました、それらは将来取り込まれるべきだと思います。
- line-heightは、line-sizeでも構わない
- border-widthは、border-sizeでも構わない
少なくとも、border-widthはどうにかしてほしいと思います。論理プロパティで更新されたばかりで、その名称にはまだ「width」という単語があります。
例: border-block-start-width
しかし、W3Cの誰かがこの記事を読むと思います。
終わりに -参考記事
私の経験から学んだことが、あなたのためになることを願っています。
- テキストの扱いについて
- 私のCSSに関する記事
私の名前はElad Shechterで、CSSおよびHTMLの設計とアーキテクチャを専門とするWeb開発者で、Investing.comに勤務しています。
sponsors