利用CSS逻辑和值实现多语言网站支持

974 阅读12分钟

现在,跨浏览器支持已经到了一个临界点,现在是看一下逻辑属性和值的好时机。如果你正在创建一个多语言的网站,逻辑属性和值是非常有用的。即使你不是,仍然有一些方便的新的速记方法,值得了解。

例如,我已经数不清我写了多少次这样的东西来居中。

.thing {
  margin-left: auto;
  margin-right: auto;
}

我们可以用margin: 0 auto; ,但这样一来,顶部和底部的边距就会被扔进混合物中。相反,我们可以用margin-inline 这个逻辑属性只选择左右边距。

CodePen嵌入回退

开始把事情想成 "内联 "或 "块"。

最后一个演示是非常整洁的,对吗?margin-inline 属性同时设置了margin-leftmargin-right 。同样地,margin-block 属性同时设置了margin-topmargin-bottom 。而且,我们不仅仅是在谈论页边距。逻辑属性也有类似的速记功能,可以设置borderpadding 。因此,如果你有一个视觉设计,要求只在边上有边框,你可以只使用border-inline ,而不是在每个物理方向上大费周章。

CodePen嵌入回退

Showing border-left and border-right with matching values combined together as border-inline as a single declaration, and another example showing padding-top and padding-bottoms et to 32 pixels combined to padding-block set to 32 pixels.

与其用物理术语思考,如左和右,我们可以考虑一个 "内联 "方向和一个 "块 "方向。

因此,当我们继续前进时,我们现在知道我们正在处理内联和块方向,而不是物理方向。内联处理左和右的方向,而块管理顶部和底部。

也就是说,直到写入模式发生变化时,事情就会被调换。

注意方向和书写模式

到目前为止,我们所看到的是CSS逻辑属性的例子。这些是CSS属性的版本,如marginpadding ,但以一种新的方式编写,放弃了物理方向(即左、右、顶和底)。

CSS是以英语为基础开发的,而英语是从左到右书写和阅读的。但并不是所有的语言都是如此。例如,阿拉伯语是从右到左阅读的。这就是为什么HTML有一个dir 属性。

<html dir="rtl">

CSS也有一个类似的属性(尽管建议使用HTML属性,以防止CSS无法加载)。

.foreign-language { direction: rtl; }

Two cards, one in english and one in arabic, Both cards have a subtitle in gray above a main heading in a larger black font. The english goes from left to right and indicates the direction with an arrow below the card. The arabic direction is reverse of the english.

信用:Ahmad Shadeed

中文、日文、韩文和蒙古文可以从左到右水平书写,也可以从上到下垂直书写。这些语言的大多数网站都是横着写的,与英语相同。

相对而言,垂直书写在日本网站上更为常见。有些网站同时使用垂直和水平文字的混合体。

baroku.co.jp

当垂直书写时,中文、日文和韩文是以右上方为起点进行书写的,而蒙古文则是从左到右进行阅读的。这正是我们为什么在CSS中使用 [writing-mode](https://css-tricks.com/almanac/properties/w/writing-mode/)属性,其中包括以下数值。

  • horizontal-tb :这是默认值,为英语或法语等语言设置从左到右的方向,为阿拉伯语等语言设置从右到左的方向。tb 代表 "从上到下"。
  • vertical-rl: 对于像中文、日文和韩文这样的语言,这将在垂直方向上把方向改为从右到左。
  • vertical-lr: 这用于垂直方向从左到右的语言,如蒙古语。

CSS的逻辑属性提供了一种写CSS的方法,即上下文。当使用逻辑属性时,间距和布局都取决于writing-mode 和方向(无论是由CSS还是HTML设置)。因此,在不同的语言中重复使用CSS样式成为可能。例如,BBC新闻,用十几种语言重建他们的网站。这比让用户依赖自动翻译有更好的体验。这也意味着他们可以更好地迎合世界不同地区的特定内容。不过,不同地区的视觉风格仍然是一样的。

让我们看一下下面的例子,看看物理属性的缺点。使用物理的margin-left属性(红色显示),一切在英语中看起来都很好。如果你重新使用这个CSS,但把书写模式改为rtl(如底部所示),那么在文本和图标之间就没有空间了,而且文本左边还有多余的空白空间。我们可以通过使用一个逻辑属性来避免这种情况。

Two buttons, both with an envelope icon and a label. The left-to-right version of the button on top shows the spacing between the icon and the label. The right-to-left version shows the spacing to the left of both the label and icon.

逻辑属性和值之所以如此有用,是因为它们会自动迎合语言的上下文。在像英语这样从左到右的语言中,margin-inline-start ,将设置左边的空白。对于像阿拉伯语、乌尔都语或希伯来语这样从右到左的语言,它将设置右侧边距--这就解决了上述例子中的布局问题。这就解决了从右到左的问题。如果你有垂直的文本,margin-inline-start 将迎合这种情况,在顶部增加页边距,这是任何垂直语言中你开始阅读的地方(这就是为什么它被称为margin-inline-start - 想想你从哪个方向开始阅读)。inline 的方向根据元素的writing-mode 而改变。当一个垂直的writing-mode ,它处理垂直方向的顶部和底部。看到事情是如何被调转的吗?

一个蒙古语书写方向的例子。 (来源:W3C)

逻辑属性和值的完整列表

有几十个CSS属性有一个逻辑替代语法。阿德里安-罗塞利(Adrian Roselli)有一个方便的可视化工具,你可以在我们都习惯的物理CSS属性和它们的逻辑属性对应物之间进行切换。horizontal-tb当方向是ltrwriting-mode ,这是一个很好的方法来可视化逻辑属性和它们映射到的物理属性。

CodePen嵌入回退

让我们进一步分解所有这些,并将每一个物理CSS属性映射到它的逻辑同伴,并排排列。本文中的表格在左栏显示传统的物理CSS,在右栏显示它们的逻辑对应物(使用从左到右的水平映射)。请记住,逻辑属性的全部意义在于它们是根据上下文变化的

确定大小

在水平书写模式下,inline-size 设置一个元素的宽度,而block-size 设置高度。在垂直书写模式下,情况正好相反:inline-size 设置高度,block-size 设置宽度。

CodePen嵌入回退

物理属性逻辑属性
widthinline-size
max-widthmax-inline-size
min-widthmin-inline-size
heightblock-size
max-heightmax-block-size
min-heightmin-block-size

用于确定大小的逻辑属性具有良好的跨浏览器支持

边框

这里的一切在现代浏览器中都有坚实的跨浏览器支持

物理属性逻辑属性
border-topborder-block-start
border-bottomborder-block-end
border-leftborder-inline-start
border-rightborder-inline-end

这里有一个使用border-inline-start 的例子,显示了英语、阿拉伯语和中文。

CodePen 嵌入回退

这里有一个例子,设置border-block-start 虚线和border-block-end 虚线。

CodePen Embed Fallback

还有一些逻辑属性用于单独设置边框的颜色、宽度和样式。

物理属性逻辑属性
border-top-colorborder-block-start-color
border-top-widthborder-block-start-width
border-top-styleborder-block-start-style

所以,这又是在用 "内联 "和 "块 "来思考,而不是物理方向,如lefttop 。我们也有用于边框的简明逻辑属性。

物理属性逻辑属性
border-top and border-bottomborder-block
border-left and border-rightborder-inline

边框

下面是所有单独的逻辑margin 属性。

物理属性逻辑属性
margin-topmargin-block-start
margin-bottommargin-block-end
margin-leftmargin-inline-start
margin-rightmargin-inline-end

这些逻辑属性具有全面的现代跨浏览器支持,包括三星互联网,并从12.2开始在Safari中得到支持。

而且,请记住,我们也有速记工具。

物理属性逻辑属性
margin-top and margin-bottommargin-block
margin-left and margin-rightmargin-inline

填充

Padding与margin超级相似。用padding 替换margin ,我们就得到了同样的属性列表。

物理属性逻辑属性
padding-toppadding-block-start
padding-bottompadding-block-end
padding-leftpadding-inline-start
padding-rightpadding-inline-end
padding-top and padding-bottompadding-block
padding-left and padding-rightpadding-inline

就像margin一样,padding的逻辑属性有很好的跨浏览器支持

定位

需要将一个元素的位置向某个方向偏移?我们也可以在逻辑上声明这些。

物理属性逻辑属性
top嵌入-块-开始
bottom内嵌-块-端
left嵌入线开始
right内嵌-内嵌-末尾
topbottom嵌入-块
leftright嵌入-内联

在水平书写模式下(从左到右,或从右到左)inset-block-start ,相当于设置top ,而inset-block-end ,相当于设置bottom 。在水平书写模式下,从左到右的方向,inset-inline-start 相当于left ,而inset-inline-end 相当于right ,从右到左的语言,反之亦然。

反之,对于垂直书写模式,inset-inline-start 相当于top ,而inset-inline-end 相当于bottom 。如果writing-mode 被设置为vertical-rlinset-block-start 相当于rightinset-block-end 相当于left 。如果writing-mode 被设置为vertical-lr ,情况则相反,因此inset-block-start 相当于left

逻辑属性写作模式相当于
inset-block-start`水平LTRtop
inset-block-start水平RTLtop
inset-block-start垂直LTRleft
inset-block-start垂直RTLright

下面是一个例子,说明同样的绝对定位CSS代码在四个不同的书写方向上是怎样的。

CodePen嵌入回退

所有现代浏览器都支持定位的逻辑属性,但最近才在Safari浏览器中出现。

还有一种新的速记方法,用于在一行代码中设置所有四个偏移。这里有一个例子,使用inset ,作为设置topbottomleftright 的速记,一举创建一个全页面的覆盖。

CodePen嵌入回退

我听说inset 被错误地称为一个逻辑属性。但是,在DevTools中快速浏览一下,它实际上是物理_值_的缩写,而不是逻辑_属性_。

它实际上在做的是定义_物理_偏移(即左、右、顶和底)而不是_逻辑_偏移(即内联、块、开始和结束)。显然,如果你想为所有四边设置相同的值,就像上面的例子一样,这并不重要。

inset: 10px 20px 5px 8px; /* shorthand for physical properties not logical properties  */

文本对齐

文本对齐的逻辑值得到了浏览器的大力支持,多年来一直如此。当用英语工作时,text-align: starttext-align: left 相同,而text-align: endtext-align-right 相同。如果你将dir 属性设置为rtl ,它们就会转换,text-align: start 将文本向右对齐。

物理值写作模式相当于
startLTRleft
startRTLright
endLTRright
endRTLleft

边界半径

到目前为止,我们所看到的一切都有很好的浏览器支持。然而,还有一些逻辑属性的支持仍在进行中,边界半径就是其中之一。换句话说,我们可以用逻辑属性为一个元素的不同角落设置不同的border-radius ,但浏览器的支持并不是很好。

物理属性逻辑属性
border-top-left-radiusborder-start-start-radius
border-top-right-radiusborder-start-end-radius
border-bottom-left-radiusborder-end-start-radius
border-bottom-right-radiusborder-end-end-radius

CodePen嵌入回退

值得注意的是,该规范不包括速记属性,如border-start-radiusborder-end-radius 。但是,就像我说的,我们仍然处于早期阶段,所以这可能是一个值得关注的空间。

浮点

在我写这篇文章的时候,逻辑浮点的流量相对值的浏览器支持很糟糕。只有Firefox支持inline-startinline-end 作为float 值。

物理值逻辑值
float: leftfloat: inline-start
float: rightfloat: inline-end
clear: leftclear: inline-start
clear: rightclear: inline-end

CodePen嵌入回退

其他逻辑属性

overflowresize 有拟议的逻辑属性,但目前它们的浏览器支持度很低。

物理值逻辑的
resize: verticalresize: block
resize: horizontalresize: inline
overflow-yoverflow-block
overflow-xoverflow-inline

深入挖掘

我们探讨了一个属性被认为是 "逻辑的 "意味着什么,然后将所有新的逻辑属性和值映射到它们的物理对应物。这很好!但如果你想更深入地了解CSS的逻辑属性和值,有许多资源值得一查。

  • "RTL样式设计101"(Ahmad Shadeed)。如果你正在处理阿拉伯语或其他从右到左的语言,这是一个很好的资源。艾哈迈德涵盖了一切,从逻辑属性到使用特定布局技术(如flexbox和grid)时的注意事项。
  • text-combine-upright(CSS-Tricks)。如果你在处理垂直文本,你知道这个属性可以旋转文本并将多个字符挤压到一个字符的空间里吗?在一些需要将一些字符放在一起,但仍以垂直书写模式流动的特定情况下,这是一个很好的细化手段。

如果你想从整个网络上查看一些不错的垂直排版的真实案例,请看一下水平和垂直写作的网络奖。那里有很多很棒的东西。

收尾工作

你需要急于把你的代码库中的所有物理属性都换掉吗?不,不需要。但在你的工作中开始使用逻辑属性和值也是无妨的。正如我们所看到的,浏览器的支持几乎是存在的。而且,即使你正在做一个只有英文的网站,也没有理由_不_使用它们。


CSS逻辑属性和值》一文首次出现在CSS-Tricks上。你可以通过成为MVP支持者来支持CSS-Tricks。