New CSS Logical Properties! - The Next Step of CSS Evolution

2019-08-15 admin

原文链接:https://medium.com/@elad/new-… 原文作者:Elad Shechter

简介

在过去,大多数程序猿在思考布局时总是习惯于从“上下左右”的角度出发。这是因为在早期,互联网主要用于上传文档,而不是为了实现我们现在熟知的复杂网站架构。

这也是为什么没有人思考多语言网站的需求。

目前为止,支持类似 RTL/LTR 这种多方向网站的最佳方式,依然是使用 SASSSASS 变量。 (如果你希望了解更多内容,可以阅读我的另一篇文章《The Best Way to RTL Websites with SASS!》)。

这些新的逻辑属性让我们能够在改动最少样式的情况下控制我们的网站,而不用担心网站使用的是何种语言(无论是英语、阿拉伯语、日语还是其他语言)。

现在让我们开始吧!

思考 CSS 逻辑属性的方式

当我们讨论盒模型时,我们已经对下面这张图很熟悉了:

<font color=#999>盒模型物理属性(旧方案)

它在以前和现在一直是正确的,但类似 margin-left, padding-right, border-top 等经典物理特性其实已经时日不多了。

在你开始使用新的逻辑属性之前,你需要停止从 left/right 或者 top/bottom来思考问题,而是使用 inline-start/inline-endblock-start/block-end 来替代它们。

<font color=#999>逻辑属性(新方案)

Inline axis (译者理解为内联轴,即阅读方向)

让我们用英文作为例子,英文的阅读方向是从左到右,这是属性的内联部分。当我们想要把一系列元素排在同一行时,我们通常会使用 display: inline,照这个思路就很容易记住 inline axis 的含义了。

举例来说,padding-inline-start 会在当前语句开始位置的旁边设置一个内边距:

在英语中:       padding-inline-start = padding-left 在阿拉伯语中:padding-inline-start = padding-right 在日语中:       padding-inline-start = padding-top

Block axis (块轴)

让我们忘掉 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)

在理解了 inlineblock 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

逻辑尺寸

WidthHeightinline-sizeblock-size 所取代。

WidthHeight 属性同样需要适应新的尺寸表达方法。一旦我们理解了 inline/block 方法,就非常容易理解它们的尺寸要如何用新属性来表示。在英文网站,宽度属性用 inline-size 表示,高度属性用 block-size 表示。

举个栗子(inline/block size): 在英文与阿拉伯语中(LTR/RTL) width = inline-size height = block-size

在一个阅读顺序是每行里自上而下的语言中,比如日语,我们会看到相反的表达方式: inline-size = heightblock-size = width

对于 min/max 属性,只需要把 min/max 书写在属性前面:min-inline-size: 300px; max-block-size: 100px;

<font color=#999>新旧盒模型属性对比

CSS Positions

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*/
}

CSS Floats

Float 非常简单,它只有2个值 left/right,分别用 inline-start/inline-end 来代替。

在英文网站中(LTR): float: left = float: inline-start float: right = float: inline-end

Text-align

它比 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 这样的属性也会被更新。

CSS Grid & CSS Flexbox

这两个特性本身已经使用了新的逻辑属性方法进行构建,因此如果你之前已经使用了这两个特性,那么没有必要用本文提到的新方法去替代它们。

理解逻辑属性的工作流程

虽然刚开始看起来很复杂,但实际上是非常容易使用的。在写样式时,不再需要考虑跨语言支持的问题。你只需要使用逻辑属性替代旧的物理属性,然后让它们匹配你喜欢的语言即可。

根据语言来应用对齐

当我们学习了所有新逻辑属性的更新后,我们就可以运用2个特性来分别定义块轴对齐(block axis alignment)(网站文档流方向)和内联轴对齐(文字阅读方向)。

Writing-mode 属性(块轴)

在定义网站文档流时,大多数时候是从上到下的。但正如上文提到的,特定语言有可能从右到左(日语),甚至从左到右(蒙语)。在这两种情况中,我们就得使用水平滚动条来替代惯用的垂直滚动条。

注意: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;
}

Direction property (inline axis) - 方向属性(内联轴)

只有在 writing-mode 属性处于默认的水平模式时,方向属性才能够定义文字方向是 left-to-right 还是 right-to-left。如果我们将 writing-mode 改为垂直模式中的一种后,文字方向就会发生改变: left-to-right 会变为 top-to-bottomright-to-left 会变为 bottom-to-top

以阿拉伯语为例:

html {
    direction: rtl;
}

令人惊奇的是,将一个自上而下的网站变为一个带有横向滚动条的自右向左的网站是多么的容易。

这里是我写的一个demo,在 Firefox 中浏览最佳(目前为止 Firefox 支持更多的新属性)

Live Example (试试选择其他语言选项):

浏览器支持情况

  • 除 Edge 外,大部分主流浏览器支持所有的盒模型属性(margin / padding / border)以及新的 width / height (inline-size, block-size) 属性。
  • 除 Edge 外,大部分主流浏览器支持 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 属性来工作。

但如何能让简写自动根据directionwriting-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

[转载]原文链接:https://segmentfault.com/a/1190000020076565

本站文章除注明转载外,均为本站原创或编译。欢迎任何形式的转载,但请务必注明出处。

转载请注明:文章转载自 JavaScript中文网 [https://www.javascriptcn.com]

本文地址:https://www.javascriptcn.com/read-72524.html

文章标题:New CSS Logical Properties! - The Next Step of CSS Evolution

相关文章
在 Microsoft Azure 中使用 MEAN 堆栈基于开放数据协议
网络开发人员通常构建伟大的应用程序在客户端使用JavaScript和ASP(c#或Visual Basic . NET)在服务器端。 但是如果你能使用一个共同的语言来构建应用程序的所有层堆栈,从浏览器和服务器端业务处理服务层,甚至在数据库查...
2015-11-12
面试官:谈谈你对 CSS 盒模型的认识?(你确定会?)
题目:谈谈你对 CSS 盒模型的认识 涉及知识点(层层递进): 基本概念:标准模型+ IE模型(区别) CSS如何设置这两种模型 JS如何设置获取盒子模型对应的宽和高 实例题(根据盒模型解释边距重叠) BFC(边距重叠解决方案) 1...
2018-06-09
纯css实现窗户玻璃雨滴逼真效果
这里仅是用CSS技术来演示这样的一个场景,可能并不太实用。然而这是一个探索CSS新功能的最佳机会。可以让你尝试使用一些新特性和新工具。并且逐渐将在工作中实践。在制作窗口雨滴效果,将使用到HAML和Sass。 案例效果 看到上面的效果是不是...
2017-03-29
7个你可能不认识的CSS单位
浼楁墍鍛ㄧ煡CSS鎶€鏈�鎴戜滑铏界劧寰堢啛鎮夛紝鍦ㄤ娇鐢ㄧ殑杩囩▼鍗村緢瀹规槗琚�鍥颁綇锛岃繖璁╂垜浠�鍦ㄦ柊闂�棰樺嚭鐜扮殑鏃跺€欏彉寰楀緢涓嶅埄銆� 闅忕潃web缁х画涓嶆柇鍦板彂灞曪紝瀵逛簬鏂版妧鏈�鏂拌В鍐虫柟妗堢殑瑕佹眰涔熶細涓...
2015-11-11
css3.0参考手册
下载地址:css3.0参考手册 友情提示:如果打开空白,在手册上右键属性解除锁定即可。 ...
2015-11-12
使用HTML+CSS+JS制作简单的网页菜单界面
写ABROAD项目用到了标签这个东东,其实标签在WEB上到处可见,图中就依次显示了DCC文章发布器、ABROAD后台添加数据、百度图片搜索、sf发布博客文章时贴标签的样式——标签就像浏览器里原生的checkbox一样,不过checkbox实...
2017-03-27
webpack4 css打包压缩问题
这两天一直在练习这个webpack4, 发现有好多问题和坑,做开发嘛,一定要有喜欢出问题并喜欢解决问题,坚决踩个坑填个坑的不怕死小强精神! webpack4 在配置上其实是可以是想production和development的, &#x2F...
2018-05-18
javascript实现动态导入js与css等静态资源文件的方法
本文实例讲述了javascript实现动态导入js与css等静态资源文件的方法。分享给大家供大家参考。具体实现方法如下: &#x2F;** * 动态导入静态资源文件js&#x2F;css *&#x2F; var $import = fu...
2017-03-27
javascript中使用new与不使用实例化对象的区别
我们先来看个实例 function Me(name,age,job){ this.name = name; this.age = age; this.job = job; } 请问这以下两种实例化对象方式有什么区别呢? var...
2017-03-24
JavaScript使用indexOf获得子字符串在字符串中位置的方法
本文实例讲述了JavaScript使用indexOf获得子字符串在字符串中位置的方法。分享给大家供大家参考。具体如下: &lt;!DOCTYPE html&gt; &lt;html&gt; &lt;body&gt; &lt;p id=&qu...
2017-03-22
回到顶部