原文连接:https://medium.com/@elad/new-...
原文做者:Elad Shechtercss
在过去,大多数程序猿在思考布局时老是习惯于从“上下左右”的角度出发。这是由于在早期,互联网主要用于上传文档,而不是为了实现咱们如今熟知的复杂网站架构。html
这也是为何没有人思考多语言网站的需求。git
目前为止,支持相似 RTL/LTR
这种多方向网站的最佳方式,依然是使用 SASS
和 SASS
变量。
(若是你但愿了解更多内容,能够阅读个人另外一篇文章《The Best Way to RTL Websites with SASS!》)。github
这些新的逻辑属性让咱们可以在改动最少样式的状况下控制咱们的网站,而不用担忧网站使用的是何种语言(不管是英语、阿拉伯语、日语仍是其余语言)。web
如今让咱们开始吧!浏览器
当咱们讨论盒模型时,咱们已经对下面这张图很熟悉了:sass
<font color=#999>盒模型物理属性(旧方案)架构
它在之前和如今一直是正确的,但相似 margin-left
, padding-right
, border-top
等经典物理特性其实已经时日很少了。布局
在你开始使用新的逻辑属性以前,你须要中止从 left/right
或者 top/bottom
来思考问题,而是使用 inline-start/inline-end
和 block-start/block-end
来替代它们。学习
<font color=#999>逻辑属性(新方案)
让咱们用英文做为例子,英文的阅读方向是从左到右,这是属性的内联部分。当咱们想要把一系列元素排在同一行时,咱们一般会使用 display: inline
,照这个思路就很容易记住 inline axis
的含义了。
举例来讲,padding-inline-start 会在当前语句开始位置的旁边设置一个内边距:
在英语中: padding-inline-start
= padding-left
在阿拉伯语中:padding-inline-start
= padding-right
在日语中: padding-inline-start
= padding-top
让咱们忘掉 top 和 bottom 相关属性的含义(再也不表示“上下”),而是把 top 当作网站的开始,把 bottom 当作网站的结束。只要想像几个 display:block
的元素首尾相连,就很容易记住这点了。
到这时你仍然会问本身,难道这不是一向的作法吗?
这个问题解释起来有点复杂。由于目前并无其余解决方案,因此目前全部的网站,不论是使用的是什么语言,都是这么处理的。
要知道使用日文或者其余东方语言的网站(按布局方向)多是从右到左,而非从上到下的!为了理解这种网站的表现,咱们能够想象一下将浏览器向右旋转90度,咱们会发现网站的滚动条再也不是垂直方向了,它变成了水平方向!
举个例子(block cases):
在英语和阿拉伯语中: padding-block-start
= padding-top
在日语中: padding-block-start
= padding-right
<font color=#999>(日文网站)
(margin, padding and border)
在理解了 inline 和 block axis 以后,你就能够根据须要来使用它们了。
用英文网站举例来讲:
margin margin-block-start
= margin-top
margin-block-end
= margin-bottom
margin-inline-start
= margin-left
margin-inline-end
= margin-left
padding padding-block-start
= padding-top
padding-block-end
= padding-bottom
padding-inline-start
= padding-left
padding-liline-end
= padding-right
border border-block-start
= border-top
border-block-end
= border-bottom
border-inline-start
= border-left
border-inline-end
= border-right
Width
和 Height
被 inline-size
和 block-size
所取代。
Width
和 Height
属性一样须要适应新的尺寸表达方法。一旦咱们理解了 inline/block 方法,就很是容易理解它们的尺寸要如何用新属性来表示。在英文网站,宽度属性用 inline-size
表示,高度属性用 block-size
表示。
举个栗子(inline/block size):
在英文与阿拉伯语中(LTR/RTL) width
= inline-size
height
= block-size
在一个阅读顺序是每行里自上而下的语言中,好比日语,咱们会看到相反的表达方式:inline-size
= height
,block-size
= width
。
对于 min/max 属性,只须要把 min/max 书写在属性前面:min-inline-size: 300px;
max-block-size: 100px;
。
<font color=#999>新旧盒模型属性对比
top/right/bottom/left
这些旧的位置属性已经发展出了一组新的属性名,它们都带有 inset
前缀,分别是: inset-block-start / inset-inline-end / inset-block-end / inset-inline-start
在英文网站中(LTR): top
= inset-block-start
bottom
= inset-block-end
left
= inset-inline-start
right
= inset-inline-end
/* OLD TECHIQUE */ .popup { position: fixed; top: 0; bottom: 0; left: 0; right: 0; } /* NEW TECHIQUE */ .popup { position: fixed; inset-block-start: 0; /*top - in English*/ inset-block-end: 0; /*bottom - in English*/ inset-inline-start: 0; /*left - in English*/ inset-inline-end: 0; /*right - in English*/ }
第一眼看到这些代码,你可能会质疑为何咱们须要如此复杂的命名?!其实这是有充分理由的。在新的属性名中,这些属性依然可使用相似 padding/margin/border
的书写方式混合起来,而这种新的位置简写特性在之前是不存在的(以下所示)。
.popup{ position:fixed; inset:0 0 0 0; /*top, right, bottom, left - in English*/ }
Float 很是简单,它只有2个值 left/right
,分别用 inline-start/inline-end
来代替。
在英文网站中(LTR): float: left
= float: inline-start
float: right
= float: inline-end
它比 floats 更简单,只须要用 start/end
代替 left/right
便可。
在英文网站中(LTR): text-align: left
= text-align: start
text-align: right
= text-align: end
Resize:经常使用于 <textarea>
,它的值 horizontal/vertical
升级为 inline/block
代替。
在英文网站中(LTR): resize: horizontal
= resize: inline
resize: vertical
= resize: block
background-position:目前为止尚未任何浏览器中针对该属性进行过修改,但若是你研究的足够深刻,你就会在 Mozilla 的 MDN 中找到有关 background-position-inline & background-position-block
的资料。虽然这些文档还不够完善,但工做人员已经在进行相关的工做了。
其余:正如其余与方向有关的属性同样,咱们还能够预测相似 transform-origin
这样的属性也会被更新。
这两个特性自己已经使用了新的逻辑属性方法进行构建,所以若是你以前已经使用了这两个特性,那么没有必要用本文提到的新方法去替代它们。
虽然刚开始看起来很复杂,但其实是很是容易使用的。在写样式时,再也不须要考虑跨语言支持的问题。你只须要使用逻辑属性替代旧的物理属性,而后让它们匹配你喜欢的语言便可。
当咱们学习了全部新逻辑属性的更新后,咱们就能够运用2个特性来分别定义块轴对齐(block axis alignment)(网站文档流方向)和内联轴对齐(文字阅读方向)。
在定义网站文档流时,大多数时候是从上到下的。但正如上文提到的,特定语言有可能从右到左(日语),甚至从左到右(蒙语)。在这两种状况中,咱们就得使用水平滚动条来替代惯用的垂直滚动条。
注意:writing-mode
有3个主要的值:horizontal-tb / vertical-rl / vertical-lr
。
这3个值的名称有一点使人困惑。这是由于他们既能够表示块轴方向,还能够表示内联轴的文字对齐(inline-axis)。这显然让人很不爽,由于文字对齐实际上是多余的,这只能让人感到困惑。
为了消除这个困惑,建议忽略属性值内表示内联轴的部分,只关注块轴部分。
举例来讲:
writing-mode: horizontal-tb;
= Top to Bottom Flow,英文(默认)writing-mode: vertical-rl;
= Right to Left Flow,日语writing-mode: vertical-lr;
= Left to Right Flow,蒙语就我而言,我更倾向于让属性值只包括:tb/rl/lr (block-axis part),以此消除潜在的困惑。
日语中 writing-mode
是这么定义的:
html { writing-mode: vertical-rl; }
只有在 writing-mode
属性处于默认的水平模式时,方向属性才可以定义文字方向是 left-to-right 仍是 right-to-left。若是咱们将 writing-mode
改成垂直模式中的一种后,文字方向就会发生改变:
left-to-right 会变为 top-to-bottom,right-to-left 会变为 bottom-to-top。
以阿拉伯语为例:
html { direction: rtl; }
使人惊奇的是,将一个自上而下的网站变为一个带有横向滚动条的自右向左的网站是多么的容易。
这里是我写的一个demo,在 Firefox 中浏览最佳(目前为止 Firefox 支持更多的新属性)
Live Example (试试选择其余语言选项):
margin / padding / border
)以及新的 width / height (inline-size, block-size)
属性。text-align
的新属性值。Floats / Positions / Resize
的值或属性只被 Firefox 所支持。随着这些新属性的诞生,咱们也必须面对随之而来的新问题。好比,当咱们想用简写的方式把全部 margin 属性写出来时,像这样:
margin: 1px 2px 3px 4px;
你是没法预测它会如何被浏览器解析的。
由于若是网站使用的是物理属性,这些属性值就会被解析为:margin-top / margin-right / margin-bottom / margin-left
,但若是网站使用的是逻辑属性,这些值就应该是:margin-block-start / margin-inline-end / margin-block-end / margin-inline-start
。
在英文网站中,物理属性与逻辑属性的表现是一致的。在使用其余语言的网站中,当咱们使用相似 margin
的简写时,咱们但愿它可以根据 direction
属性或 writing-mode
属性来工做。
但如何能让简写自动根据direction
或 writing-mode
去解析呢?这一直是个悬而未决的问题。针对该问题,我曾给出一些建议:++suggestion that can solve the issue at github csswg-drafts++。若是你有更好的解决方案,欢迎你在连接中评论!
若是你如今要使用逻辑属性,那你就必须把它们的属性名完整地写出来,而不能使用简写。
在这里我给出一个可选的解决方案:
html{ flow-mode:physical; /*or*/ flow-mode:logical; } .box{ /*will be interpreted according to the HTML flow-mode value*/ margin:10px 5px 6px 3px; padding:5px 10px 2px 7px; }
为了制做一个完善的 demo,我尝试在媒体查询里使用 max-width
的新属性 max-inline-size
,在 left-to-right 的条件下,max-inline-size
的效果会与 max-width
同样,而在 right-to-left 的条件下,好比日语这样的语言,新属性的效果就会与 max-height
同样。有点遗憾的是目前浏览器并不支持在媒体查询(media query)中解析新属性。
/*Not Working*/ @media (max-inline-size:1000px){ .main-content{ background:red; grid-template-columns:auto; } }
在深刻学习并理解了逻辑属性的概念后,我一边写文章一边想,还有一些被忽略的改动也应该被归入将来的更新范围中:
line-height
能够改成 line-size
border-width
能够改成 border-size
不过真实状况彷佛不太同样,至少 border-width
和我想的不同。它更新为逻辑属性后,属性名中依然带有 width
。
举个例子:border-block-start-width
。