19

このシナリオを考えてみましょう。多言語のWebアプリケーションを開発しています。ターゲットとするすべてLTRの言語がまたはの場合RTL、言語固有のCSSルールは必要ありません。ただし、ターゲット言語がLTRRTL言語の組み合わせである場合は、各言語のページの読み方を指定する必要があります。

dir='ltr'要素にまたはdir='rtl'を追加する場合<body>、論理的には、要素が必要な魔法を実行することを期待する必要があります。

ただし、実際には、やなどのルールですべてrightと設定を切り替える必要があります。また、次のようなルールを変更する必要がありますlefttext-directionmarginmargin: 0 10px 0 20px;margin: 0 20px 0 10px;

W3C標準では、方向関連のルールにさらに2つの値を許可することで、この問題を回避できます。-rightつまり、 andの代わりに-left(andのようにmargin-rightmargin-left、次のようなものを許可できます。

div.foo { margin-near: 100px; } 
/* This would be equivalent to margin-left in LTR, and margin-right in RTL */

div.bar { margin-far: 100px; } 
/* This would be equivalent to margin-right in LTR, and margin-left in RTL */

left本質的に、現在またはright方向ベースの単語を入力できるすべてのルール/値では、代わりにnearまたはを書くことができますfar

CSSの現在のバージョンの現在の弱点を考えると、双方向の大規模なWebアプリの作成保守を合理化するためのいくつかの提案を探しています。

4

7 に答える 7

7

質問を後付けではなく先見の明の1つに変更したので。

それほど論理的ではありません

あなたは、「論理的に要素に追加dir='rtl'またはdir='ltr'属性を付ける<body>と、それが魔法を実行することを期待します」と述べています。どうやら魔法は、「とのようなルールですべてとすべてで」変換rightするleftことleftです。righttext-directionmargin

しかし、すべての場合において、あなたが望むものが必ずしも論理的な結果であることに同意しません。必ずしもメインサイトのに関連していないインスタンスtext-directionと使用法があります。の場合、これは自明のように思われます。テキストとはまったく関係のない要素の何らかの形の配置に何度も使用される可能性があるためです。それが自動的に反転することはあまり明白ではないかもしれませんが、それでも有効です。アラビア語(RTL)のブロック引用符が含まれる英語(LTR)サイトがあるとします。これで、主要言語をヘブライ語(RTL)に変換しますが、アラビア語の引用符が残っています。これは、正しくないため、自動的にLTRに切り替わらないようにする必要がありますmargintext-directionmarginmargintext-direction

フロート要素、絶対位置要素など(rightおよびleft値を使用)のようなものは、のためにそのまま配置される場合とされない場合がありますtext-direction

つまり、基本的には、多言語対応のサイトを設計するtext-direction際に、LTRまたはRTLの構成に基づいて要素が何をすべきかを各段階で検討する必要があるという事実に要約されます。

これが意味することは、私の意見では、CSSには弱点がないということです。弱点は設計の実装にあります。


デザインにおける純粋な人間の予見

したがって、適切な方法は、標準の方向(LTRなど)を選択し、それをストレートCSSを使用した「基本」計画にすることです。

次に、RTLの変更のために反転する要素について、<body>ターゲットにクラスを適用するか、のような属性セレクターを使用して、それを説明する追加のCSSをコーディングしますbody[dir=rtl]。次に、各要素を検討して、その変更の影響を受けるかどうかを検討します。影響を受ける場合は、cssを追加します(方向セレクターを追加して、オーバーライドする特異性を追加します)。

.someClass {
    color: red;
    margin: 0 10px 0 20px;
    float: right;
}

body[dir=rtl] .someClass {
    margin: 0 20px 0 10px;
    /* kept float as right */
}

.someOtherClass {
    border: 1px 10px 1px 1px;
    margin: 0 30px 0 50px;
    float: left;
}

body[dir=rtl] .someOtherClass {
    border: 1px 1px 1px 10px; /* changed border for text */
    margin: 0 50px 0 30px;
    float: right;
}

これは、 LESSSASS(SCSS) (Daveが彼の回答でLESSに言及)のようなプリプロセッサが役立つことが証明できる場所です(以下の私の更新を参照)が、それでも事前の検討が必要なソリューションです。

余分なCSSでいっぱいのコードを望まない場合

サイトがその特定の方向であると判断されたときにロードされるRTLcss用に別のスタイルシートを持つことができます。これの考えられる欠点は、「切り替え」コードを元のコードから分離するため、メンテナンスがより困難になる可能性があることです(メインコードのRTL変換の影響を受ける要素に関する優れたコメントドキュメントでこれを補うことができます)。


(更新)LESSを使用して支援しますか?

これは、LESSのようなプリプロセッサを使用してプロセスをより簡潔にすることについての考えです。この例では、LESS 1.4(現在ベータ版)の機能を使用しています。

アイデア1

  • 利点:すべての値を1つのセレクター変更に変更したままにします。
  • 短所:引数に値をコーディングするための作業が増えます。

ミックスインを作成して、目的のセレクターをに適用します

.rtl(...) {
  //getting the number of arguments 
  //(weeding out nested commas in parenthesis to do it)
  //they are expected to be grouped in pairs of TWO, 
  //as (property, value, property, value, etc.)
  @mainArgs: @arguments;
  @numArgs: unit(`"@{mainArgs}".replace(/\([^)]*\)/g,"").split(',').length`);

  //keep everything in one selector
  body[dir=rtl] & {
     //start the loop at 1
    .rtlPropLoop(@numArgs);
  }
  //loop to change all properties
  .rtlPropLoop(@total; @index: 1; @prop: extract(@mainArgs, @index); @value: extract(@mainArgs, (@index + 1))) when (@index =< @total) {
      //need to define all properties that could be switched
      //I've done just four here

      .setProp(ML) { //margin left
        margin-left: @value;
      }
      .setProp(MR) { //margin right
        margin-right: @value;
      }
      .setProp(FL) { //float
        float: @value;
      }
      .setProp(TD) { //text direction
        text-direction: @value;
      }
     //... define more possible values to switch

      //call setProp
      .setProp(@prop);
      //continue loop
      .rtlPropLoop(@total, (@index + 2));
  }
  //end loop
  .rtlPropLoop(@total, @index) when (@index > @total)  {}
}

次に、必要に応じて他のセレクターで使用します

.test {
  margin: 0 20px 0 10px;
  float: right;
  .rtl(ML, 20px, MR, 10px, FL, left);
}

.test2 a span {
  float: left;
  text-direction: rtl;
  .rtl(TD, ltr, FL, right);
}

この完成したコードの作成

.test {
  margin: 0 20px 0 10px;
  float: right;
}
body[dir=rtl] .test {
  margin-left: 20px;
  margin-right: 10px;
  float: left;
}
.test2 a span {
  float: left;
  text-direction: rtl;
}
body[dir=rtl] .test2 a span {
  text-direction: ltr;
  float: right;
}

アイデア2

  • 利点:必要な構文と同様の構文を使用できます。LESS1.3.3で動作するように簡単に変更できます。
  • 短所:1つのセレクターで複数の値が変更されると、過剰な出力cssが生成されます。

CSSで期待するような構文でヘルパーミックスインを構築する

//define global variable for opposite direction
@oppDir: rtl;

//generic helper mixins used inside other helpers
//to auto flip right/left values
.flipSides(left) {
  @newSide: right;
}
.flipSides(right) {
  @newSide: left;
}

//specific property helper mixins
.padding-near(@top, @right, @bottom, @left) {
  padding: @top @right @bottom @left;
  body[dir=@{oppDir}] & {
    padding: @top @left @bottom @right;
  }
}
.margin-near(@top, @right, @bottom, @left) {
  margin: @top @right @bottom @left;
  body[dir=@{oppDir}] & {
    margin: @top @left @bottom @right;
  }
}
.float-near(@side) {
  float: @side;
  .flipSides(@side);
  body[dir=@{oppDir}] & {
    float: @newSide;
  }  
}

それらを使用して、各方向の近距離と遠距離の両方を一度に定義します

.test1 {
  .padding-near(10px, 30px, 2px, 40px);
  .margin-near(0, 10px, 0, 20px);
  .float-near(right);
}

.test2 {
  .float-near(left);
}

この完成したコードの作成(.test1反対方向の繰り返しに注意してください)

.test1 {
  padding: 10px 30px 2px 40px;
  margin: 0 10px 0 20px;
  float: right;
}
body[dir=rtl] .test1 {
  padding: 10px 40px 2px 30px;
}
body[dir=rtl] .test1 {
  margin: 0 20px 0 10px;
}
body[dir=rtl] .test1 {
  float: left;
}
.test2 {
  float: left;
}
body[dir=rtl] .test2 {
  float: right;
}
于 2013-04-24T12:55:23.227 に答える
6

残念ながら、CSSは左右の概念で動作し、これが正しい動作です。CSSをLTRからRTLに移行するのに役立つツールがあります。私が知っているのはCSSJanusで、これは-left/-rightプロパティなどを反転させます。

于 2012-10-13T18:38:32.213 に答える
4

これが必要な場合は、 lesscssのようなものを使用する必要があると思います。

これに対処するための標準が作業中にありますが、私はそれをサポートするブラウザを知りません。たとえそうだとしても、それはレガシーブラウザのサポートによって抑制される可能性があります(しかし、これが問題にならなかったのはいつですか?)。

技術的な課題はさておき、これが完了したら、それをうまく実装することを想像します。それでも、左/右へのすべての参照を外部化してから、レスポンシブデザインでメディアクエリが使用されるのと同様の方法を使用する必要があります。モバイルブラウザ。

于 2012-10-13T18:42:18.807 に答える
3

私はクロージャスタイルシートを使用していますが、これはコマンドラインフラグと同じくらい簡単です。

すべてをLTRとして定義し(direction:ltr必要に応じて使用)、--output-orientation=RTLコンパイル中に使用して、反転したCSSを生成します。最後に、(サーバー上の)ロケールを決定するときに、テンプレートに挿入するCSSも決定します。

ClosureでのLRフリッピングの詳細については、https://code.google.com/p/closure-stylesheets/#RTL_Flippingをご覧ください。

于 2013-04-28T16:11:09.783 に答える
0

SASS / LESSを使用して弱点を克服しようとした1つのソリューションの追加の背景については、http://anasnakawa.github.io/bi-app-sass/を確認してください。

于 2013-08-21T15:37:01.340 に答える
0

この質問を3年間行った後、4方向の単語の代わりに論理的な方向の語彙を使用する傾向があることを知ってください。

CSS論理プロパティはこの問題に対処するようになりました。Flexモデルの使用start/endキーワードBlinkがキーワードをサポートするようになりstart/end/before/afterました。ei

ul, menu, dir {
    -webkit-margin-before: 1em;
    -webkit-margin-after: 1em;
    -webkit-margin-start: 0px;
    -webkit-margin-end: 0px;
    -webkit-padding-start: 40px;
}
于 2016-06-02T06:58:21.237 に答える
0

この質問を投稿してから約4年後、このニーズは最後にw3で対処される予定です。https://drafts.c​​sswg.org/css-logical/

物理的な方向キーワード値(上、下、左、または右)を受け入れるプロパティは、適切なフロー相対方向キーワードも受け入れるように再定義されます。このような場合、対応する物理値の代わりにフロー相対値を使用できます。複数のキーワードを使用するプロパティの場合、フロー相対値と物理値の組み合わせは許可されません(将来の仕様で特に指定されていない限り)。

于 2017-10-07T10:28:44.057 に答える