PHP*_*Pst 19 css multilingual internationalization right-to-left
请考虑以下情形:您正在开发一个多语言Web应用程序.如果您要定位的所有语言都是LTR或者RTL,则不需要特定于语言的CSS规则.但是,如果您的目标语言是语言LTR和混合RTL语言,则需要为每种语言指定页面的阅读方向.
如果您添加dir='ltr'或dir='rtl'到<body>元素,你在逻辑上应该期望它应该做必要的魔法.
但是,您实际上需要切换规则中的所有right和left设置,例如text-direction和margin.你还需要改变的规则一样margin: 0 10px 0 20px;,以margin: 0 20px 0 10px;
W3C标准可以通过允许两个与方向相关的规则的值来避免这个问题.换句话说,代替-right和-left(如在margin-right和中margin-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 */
Run Code Online (Sandbox Code Playgroud)
实质上,在您当前可以输入基于left或right基于方向的单词的所有规则/值中,您可以改为编写near或far.
鉴于当前版本的CSS目前存在缺陷,我正在寻找一些建议来简化双向大型网络应用程序的创建和维护.
既然你把问题改成了一个事先考虑而不是事后的想法.
你说,"如果你在逻辑上添加dir='rtl'或dir='ltr'归属于<body>元素,那么你会期望它能够发挥作用." 魔术显然是要转换,"所有right与left所有人left一起使用right的规则就像text-direction和margin."
但是,我并不同意在任何情况下你所希望的都是合乎逻辑的结果.有些实例text-direction和margin使用不一定与text-direction主站点有关.因为margin,这似乎是不言而喻的,因为很多时候margin可以用于某种形式的与文本完全无关的元素的定位.那text-direction不会自动翻转可能不太明显,但仍然有效.假设有一个英文(LTR)网站,其中包含阿拉伯语(RTL)的块引用.现在一个转换的主要语言希伯来语(RTL),但仍然有阿拉伯文的报价-这应该不是自动翻转到LTR,因为它是不正确的.
诸如浮动元素,绝对定位元素等(使用right和left值)之类的东西可能会或可能不会因为它们而被定位text-direction.
基本上,它归结为这样一个事实:当一个人设计一个旨在以多种语言翻转的网站时text-direction,必须在每个阶段仔细考虑该元素应该基于LTR或RTL配置做什么.
这意味着,在我看来,CSS没有弱点.任何弱点都在于设计实施.
所以,最好的方法是选择你的标准方向(比如说LTR)并将其作为你的直接CSS的"基础"计划.
然后,对于因RTL更改而要翻转的元素,可以通过将类应用于<body>to to target或使用属性选择器来编写其他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;
}
Run Code Online (Sandbox Code Playgroud)
这是像LESS或SASS(SCSS)这样的预处理器(Dave在他的回答中提到LESS)可以证明有用(参见下面的更新),但这仍然是一个需要预先考虑的解决方案.
如果你不希望代码充斥着过多的CSS
您可以为RTL css设置单独的样式表,该样式表在确定该站点是特定方向时加载.这可能的缺点是它将"切换"代码与原始代码分开,因此维护可能更具挑战性(关于受主代码中的RTL转换影响的元素的好评论文档可以弥补这一点).
这是一个通过像LESS这样的预处理器使过程更简洁的想法.此示例使用LESS 1.4(目前处于测试阶段)的功能.
构建一个mixin以应用所需的选择器
.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) {}
}
Run Code Online (Sandbox Code Playgroud)
然后根据需要在其他选择器中使用它
.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);
}
Run Code Online (Sandbox Code Playgroud)
生成这个完成的代码
.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;
}
Run Code Online (Sandbox Code Playgroud)
构建一些helper mixins,其语法与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;
}
}
Run Code Online (Sandbox Code Playgroud)
使用它们可以同时为每个方向定义近距离和远距离
.test1 {
.padding-near(10px, 30px, 2px, 40px);
.margin-near(0, 10px, 0, 20px);
.float-near(right);
}
.test2 {
.float-near(left);
}
Run Code Online (Sandbox Code Playgroud)
生成这个完成的代码(注意.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;
}
Run Code Online (Sandbox Code Playgroud)
在发布这个问题大约四年后,这个需求最终将由 w3 解决。https://drafts.csswg.org/css-逻辑/
接受物理方向关键字值(上、下、左或右)的属性被重新定义为也接受适当的流相关方向关键字。在这种情况下,可以使用流量相对值来代替相应的物理值。对于采用多个关键字的属性,不允许使用流相关值和物理值的组合(除非在未来的规范中另有规定)。