在早期的 Web 开发中,页面的布局和定位通常要用表格和各种 hack 技术来实现。与那时相比,CSS 已经得到了长足的发展。如今,开发人员可以很轻松地编写出适用于所有主流浏览器的 CSS 代码,在实现复杂布局时也不会像以前那样绞尽脑汁。这不仅使响应式布局变得更容易,还可以通过删除冗余的代码来发布体积更小的样式。在本文中,我们将使用现代技术来降低代码的复杂程度,通过一些较新的技术来编写出更好的 CSS 代码。
如果你的应用只支持单一的语言(比如 en-US),而且没有做国际化相关工作,那么在编写 CSS 时,你可能并不需要关注文字 LTR(left-to-right,左对齐)和 RTL(right-to-left,右对齐)的差异。我们可以很放心地去使用 margin-left
、padding-right
、以及绝对定位等属性。
但如果你的应用是国际化的,要支持多个地区的语言,那情况就完全不同了。在阿拉伯语、希伯来语等这些 RTL 的语言环境中,文本是从右向左读的,而不是从左向右读的。根据已有经验,页面上的大多数视觉元素要进行左右颠倒,并沿着与文本相同的方向进行布局(尽管很少有例外)。
实现 RTL 的传统方法:首先要从 LTR 的角度去编写 CSS,然后使用 dir
属性确定 RTL 样式的范围。这里通常使用物理维度的属性和值,这些属性和值的基本方向是固定的(top、right、 bottom 和 left)。下面是一个示例:
.element {
/* LTR CSS */
margin-left: 8px;
}
html[dir="rtl"] .element {
/* RTL CSS */
margin-left: unset;
margin-right: 8px;
}
在 LTR 模式下,我们的元素会有一个左外边距。在 RTL 模式下,元素需要的是一个右外边距。所以,我们取消左外边距,与此同时将右边距设置了相同的值。在页面中根据语言情况来决定哪种样式生效(RTL 版本具有更高的优先级)。但你会发现,当你处理越来越多的样式时,这个过程也变得越来越枯燥。为了实现国际化,我们额外开发了大量的重复代码。
下面列举了一些我们经常使用的物理属性:
让我们感到欣慰的是,CSS 已经开始支持逻辑属性了。与物理属性相比,逻辑属性更易于适应不同的书写模式。在逻辑属性中没有物理维度的概念,只用 start 和 end 等来描述文本方向。因此,可以使用更少的代码来实现上面的功能:
.element {
margin-inline-start: 8px;
}
逻辑属性,通常由三部分组成,属性名称(margin
)、流动方向 (block
或 inline
)、起止方向 (start
或 end
),以及相关的子属性(例如 color
、width
等)。所以与 border-left-color
对应的 逻辑属性是 border-inline-start-color
。在 LTR 模式下,start
等价于 left
,在 RTL 模式下,等价于 right
。在这两种模式下,UI 样式与期望的效果是一致的,但只需要编写一个样式规则即可适应这两个模式。
在最近所有的 CSS 新特性中,逻辑属性可以算做是我最喜欢的一个。即使你的应用程序暂不支持 RTL,你仍然可以使用逻辑属性,因为它们可以无缝地用于 LTR。带来额外的好处是,如果未来有需要的话,可以快速实现应用程序的国际化。使用逻辑属性没有任何坏处,所需要的只是转变开发视角。可以阅读「[是时候了解 CSS 逻辑属性了] 」,进一步了解逻辑属性。
当你需要重构的代码越多,逻辑属性带来的收益越大。就在去年,我使用逻辑属性对一个已有项目重构(因为我们的应用程序支持 RTL),结果我删除了近 700 行不必要的 CSS。
我们可以使用很多的逻辑属性和相关的属性值。在下面的章节中,列出了一些最常见并广泛使用的 CSS 逻辑属性,以及它们与物理属性的对应关系。值得注意的是,并不是所有的物理属性都有与之对应的逻辑属性。两个示例包括变换平移和长方体阴影偏移。
边距
我们可以把 margins、 padding、borders 替换成对应的逻辑属性,这样就会自动完成对 RTL 和 垂直书写模式的支持。下面的表格中列出了对应的关系:
物理属性 | 逻辑属性 |
---|---|
[margin | padding |
[margin | padding |
[margin | padding |
[margin | padding |
border-bottom-width | border-block-end-width |
border-left-color | border-inline-start-color |
如果从单个边框属性来看,逻辑属性的命名确实比较冗长。但与维护两套样式(一套用于 LTR,另一套用于 RTL)相比,它肯定就不那么冗长。
定位
包含 absolute、relative 和 fixed 在内的定位也可以通过逻辑属性来完成:
物理属性 | 逻辑属性 |
---|---|
top | inset-block-start |
bottom | inset-block-end |
left | inset-inline-start |
right | inset-inline-end |
宽高
如果需要支持垂直书写模式,则有以下逻辑属性:
物理属性 | 逻辑属性 |
---|---|
width | inline-size |
height | block-size |
因为宽度是对称(没有方向性),对 RTL 样式没有任何影响。在使用它们时,我们不需要做额外的工作。
逻辑属性值
除了一些属性之外,还有一些属性值也是具有逻辑性的:
物理规则 | 逻辑规则 |
---|---|
text-align: right; | text-align: end; |
justify-content: left; | justify-content: start; |
float: left; | float: inline-start; |
float: right; | float: inline-end; |
本文主要介绍使用 CSS 逻辑属性的支持不同语言的书写模式,这样可以使 CSS 的代码更加整洁。本文是整个系列的第三篇文章,点击下面的链接可以阅读前两篇文章:
[编写更好的 CSS 代码 (Part I)]
[编写更好的 CSS 代码 (Part Ⅱ)]
Copyright© 2013-2020
All Rights Reserved 京ICP备2023019179号-8