CSSの論理プロパティの使い方を徹底解説、margin-block-start, margin-inline-endなど
Post on:2021年3月25日
CSSでマージンを与える際に、margin-left, margin-rightのように物理プロパティを使用している思います。もちろん問題はないですが、CSS GridやFlexboxで使われている論理プロパティを使用する機会も増えてくると思います。
CSSの論理プロパティの基礎知識、inlineとblockの仕様、論理として使用できるプロパティ、論理プロパティの実装例を紹介します。
Digging Into CSS Logical Properties
by Ahmad Shadeed
下記は各ポイントを意訳したものです。
※当ブログでの翻訳記事は、元サイト様にライセンスを得て翻訳しています。
- はじめに
- writing-modeによるinlineとblockの違い
- inlineとはどういう意味ですか?
- startとendを正しく理解する
- 論理として使用できるプロパティは何ですか?
- 論理プロパティの実装例
- デフォルトで論理的なCSSのプロパティ
- 論理プロパティに私が望むこと
- 終わりに
はじめに
CSSの論理プロパティの基本的な考え方は、プロパティに物理的な方向(left, rightなど)を使用しないということです。その代わりに、HTMLドキュメントの方向に依存するプロパティを使用します。これらのプロパティを論理プロパティと呼びます。
論理プロパティの例を見てましょう。
論理プロパティの例
アバター画像とテキストを含むカードがあります。左から右(LTR)のレイアウトではマージン(オレンジの箇所)は画像の右側にあり、右から左(RTL)のレイアウトではマージンは画像の左側に反転させる必要があります。
論理プロパティを使用しない場合は、下記のように実装されます。
1 2 3 4 5 6 7 8 |
.avatar { margin-right: 1rem; } html[dir="rtl"] .avatar { margin-right: 0; margin-left: 1rem; } |
RTLではmargin-rightが必要ないため、0でリセットされていることに注目してください。大規模なプロジェクトでこれを実装するとなるとどうでしょうか?
この実装ではCSSが多すぎます。
論理プロパティを使用すると、この問題が解決されます。
1 2 3 |
.avatar { margin-inline-end: 1rem; } |
margin-inline-endを使用するだけでよく、HTMLドキュメントの方向に基づいて異なる動作をします。非常に便利だと思いませんか?
writing-modeによるinlineとblockの違い
論理プロパティを使用する時、inlineやblockというキーワードをよく見かけます。それぞれの意味を調べてみました。
CSSのinlineとblock
inlineとblockは、writing-modeによって意味が変わります。英語などの横書きの言語では、inlineは水平方向で、blockは垂直方向です。日本語などの縦書きの言語では、inlineは垂直方向で、blockは水平方向になります。
この記事では、横書き言語の論理プロパティにフォーカスを当てます。
inlineとはどういう意味ですか?
inlineは英語やアラビア語などの言語において、水平方向のことです。startは左から右へのレイアウト(英語など)では左、右から左へのレイアウト(アラビア語など)では右を意味し、endはRTLでは右、LTRでは左を意味します。
英語の場合、inlineは水平方向で、endは右
下記の例では、画像の右側にマージンがあります。しかしRTLレイアウトの場合は、マージンは左側にあるべきです。startとendはコンテキスト(LTRまたはRTL)に基づいて機能することを知っておく必要があります。
論理プロパティだと、LTRとRTLで異なる。
startとendを正しく理解する
startとendは道に例えると間違えない
startとendの意味をより明確にするために、それを解説するビジュアルを用意しました。
LTRとRTLの違いによるstartとendの違い
LTRの場合、startは左側にあり、endは右側にあります。RTLの場合、その逆になります。
読む方向
startとendの意味を覚えるもう1つの方法は、読む方向を覚えておくことです。英語の場合は左から右へ読み、アラビア語の場合は、右から左へ読みます。
言語によって読む方向が異なる
論理として使用できるプロパティは何ですか?
CSSのほとんどのプロパティは、論理プロパティとして使用できます。一般的なものは次のとおりです。
- width, height
- margin, padding, border
- float, poition
- text alignment
たくさんあるので、この記事にすべての論理プロパティをリストすることはできません。MDNの全リストをご覧ください。
論理プロパティの実装例
論理プロパティの基本を解説したので、実際のUIを例に使用方法を解説します。
Example 1: CSSの最小化
このコンポーネントには、下記の要件があります。
- 左右にパディング
- 左にボーダー
- アイコンの右にマージン
LTRレイアウトのCSSをどのように管理するか見てみましょう。
1 2 3 4 5 6 7 8 9 |
.card { padding-left: 2.5rem; padding-right: 1rem; border-left: 6px solid blue; } .card__icon { margin-right: 1rem; } |
RTLレイアウトの場合は、それぞれの方向を反転させます。
1 2 3 4 5 6 7 8 9 10 |
html[dir="rtl"] .card { padding-right: 2.5rem; padding-left: 1rem; border-left: 0; border-right: 6px solid blue; } html[dir="rtl"] .card__icon { margin-right: 1rem; } |
繰り返しになりますが、これは大変な作業です。
論理プロパティを使えば、上記のCSSを下記のように最小化することができます。
1 2 3 4 5 6 7 8 9 |
.card { padding-inline-start: 2.5rem; padding-inline-end: 1rem; border-inline-start: 6px solid blue; } .card__icon { margin-inline-end: 1rem; } |
Example 2: テキストの揃え
時々、テキストを右寄せにする必要がある場合がありませんか?
下記の例では、文字数に制限があるフォームで、ユーザーがそれを理解しやすくするために、文字数制限についてラベルをつけています。
文字数制限について記したラベルがあるフォーム
英語ではラベルを右に揃える必要がありますが、アラビア語では左に揃える必要があります。これは、CSS論理プロパティの優れた使用例です。
1 2 3 |
.indicator { text-align: end; } |
論理プロパティを使用しない場合、下記のようになってしまいます。
1 2 3 4 5 6 7 |
.indicator { text-align: right; } html[dir="rtl"] .indicator { text-align: left; } |
Example 3: ポジショニング
要素が絶対配置されている場合、leftまたはrightプロパティを処理する必要があります。基本的な例を見てみましょう。
絶対配置されている要素の場合
論理プロパティを使用しない場合、下記のようになります。
1 2 3 4 5 6 7 8 9 10 |
.menu__toggle { position: absolute; right: 1rem; top: 1rem; } html[dir="rtl"] .menu__toggle { right: auto; left: 1rem; } |
insetプロパティを使用すると、上記のCSSを減らすことができます。サポートは完全ではありませんが、これは未来です。
inset-inline-endプロパティは、LTRの場合はright、RTLの場合はleftに相当します。上記のように実装するには、下記のように定義します。
1 2 3 4 5 |
.menu__toggle { position: absolute; inset-inline-end: 1rem; top: 1rem; } |
また、topをinset-block-startにすることもできますが、縦書きのサイトは扱っていないため、ここでは必要ありません。
Example 4: CSSのフロート
2021年にfloatを使うことに疑問を感じている人もいるかもしれません。図形があり、その図形を囲むようにテキストを表示したい場合、floatを使用しないと機能しません。
フロートを使用したテキストのまわりこみ
LTRのCSSを見てましょう。
1 2 3 4 5 |
img { float: left; shape-outside: circle(50%); margin-right: 20px; } |
RTLの場合、上記のCSSは次のようになります。
1 2 3 4 5 |
html[dir="rtl"] img { float: right; margin-right: 0; margin-left: 20px; } |
論理プロパティを使用すると、CSSを次のように短縮できます。
1 2 3 4 5 |
img { float: inline-start; shape-outside: circle(50%); margin-inline-end: 20px; } |
デフォルトで論理的なCSSのプロパティ
CSS FlexboxとGridはデフォルトで、どちらも論理的です。つまり、ドキュメントの方向に基づいて自動的に反転します。CSS FlexboxとGridを使用すれば、多言語に対応したグリッドやコンポーネントを構築するために必要な労力は最小限に抑えることができます。
例えば、下記はGridで実装しています。ドキュメントの方向(LTRでもRTLでも)に応じてアイテムが自動的に配置されます。
CSS FlexboxとGridはデフォルトで、どちらも論理的
論理プロパティに私が望むこと
2021年現在、私がCSSの論理プロパティに望むことはbackground-positionをサポートすることです。
目的は背景画像としてアイコンを配置し、方向に応じて反転させることです。残念ながら、background-position-inlineのようなプロパティはないため、下記のように実装しています。
1 2 3 4 5 6 7 8 |
.input { background: url("mail.svg") left 0.5rem center/24px no-repeat; padding-inline-start: 2.4rem; } html[dir="rtl"] { background: url("icon.svg") right 0.5rem center/24px no-repeat; } |
終わりに
RTLのスタイルについてさらに詳しく知りたい場合は、RTL Styling 101で広範なガイドを作成しました。参考にしてください。
リソース
- CSS Logical Properties on MDN
- CSS Logical Properties by Adrian Roselli
- Building Multi-Directional Layouts by Ahmad El-Alfy
CSSのデバッグに関する電子書籍を書いていることをお知らせします。
興味がある場合は、debuggingcss.comにアクセスして、本に関する最新情報を購読してください。
コメントや提案があれば、@shadeed9までお願いします。
sponsors