通过相对流相对简写形式增强逻辑布局

为 Chromium 添加了新的逻辑属性缩写和新的内边距属性。

从 Chromium 69(2018 年 9 月 3 日)开始,逻辑属性和值可帮助开发者通过逻辑(而非实际)方向和尺寸样式来控制其国际布局。Chromium 87 中提供了缩写和偏移量,以便更轻松地编写这些逻辑属性和值。这样一来,Chromium 就与 Firefox 保持了一致,后者从 66 版开始就支持这些缩写。Safari 的技术预览版中已支持这些功能。

显示了拉丁语、希伯来语和日语在设备框架中呈现占位符文本。箭头和颜色会随文本一起显示,以帮助您将这两种排版方向(块级和内嵌)关联起来。

文档流程

如果您已熟悉逻辑属性、内嵌轴和块轴,并且不想回顾这些内容,可以直接跳到下一部分。否则,请参阅下面的简要回顾。

在英语中,字母和字词从左到右排列,而段落则从上到下堆叠。 在繁体中文中,字母和字词是从上到下排列的,而段落是从右到左堆叠的。仅在上述 2 种情况下,如果我们编写 CSS 来为段落设置“margin top”,则只会为 1 种语言样式设置适当的间距。如果网页是从英语翻译成繁体中文的,那么在新的纵向书写模式下,边距可能毫无意义。

因此,在国际上,包装盒的实际信息并不实用。至此,我们开始了解如何支持多种语言;了解盒模型的物理方面与逻辑方面。

您是否曾在 Chrome 开发者工具中检查过 p 元素?如果是,您可能已经注意到,默认的用户代理样式不是实际的,而是逻辑的。

p {
  margin-block-start: 1em;
  margin-block-end: 1em;
  margin-inline-start: 0px;
  margin-inline-end: 0px;
}

Chromium 用户代理样式表中的 CSS

边距并不像英语读者可能认为的那样位于顶部或底部。是 block-startblock-end!这些逻辑属性类似于英语读者的上和下,但类似于日语读者的右和左。只需编写一次,即可在任何设备上使用。

正常流是指网页有意成为这种多方向性内容的一部分。当页面内容根据文档方向更改而更新时,系统会考虑布局及其元素的流程。如需详细了解“在流内”和“不在流内”,请参阅 MDNCSS 显示模块规范。虽然逻辑属性不需要在流内,但在方向发生变化时,它们会为您完成大部分繁重工作。流是指字母、字词和内容需要沿着的方向。这让我们得以使用块级和内嵌逻辑方向。

版块方向是指新内容块遵循的方向,例如问自己“下一段落放在哪里?”。您可以将其视为“内容块”或“文本块”。每种语言都会沿着各自的 block-axis 排列和排序其代码块。block-start 是段落首次放置的一侧,而 block-end 是新段落流向的一侧。

例如,在传统的日语手写中,区块方向为从右到左:

内嵌方向是指字母和字词的方向。想想您在写字时手臂和手的移动方向;它们是沿着 inline-axis 移动的。inline-start 是开始写入的位置,inline-end 是结束或换行写入的位置。在上面的视频中,inline-axis 是从上到下流动的,但在下一个视频中,inline-axis 是从右到左流动的。

flow-relative 表示为一种语言编写的样式将根据上下文适当地应用到其他语言。内容将根据其传送的语言进行流式传输。

新的缩写

以下一些简写形式并非浏览器的新功能,而是利用能够同时在块级边缘或内嵌边缘设置值的优势,编写样式的更简单方式。inset-* 逻辑属性确实带来了新功能,因为之前没有使用逻辑属性指定绝对位置的长写法。不过,边距和缩写非常契合,因此我将一次性介绍 Chromium 87 中推出的所有新逻辑属性功能。

外边距缩写

没有发布任何新功能,但添加了一些非常实用的简写形式:
margin-blockmargin-inline

手写
margin-block-start: 2ch;
margin-block-end: 2ch;
新的简写法
margin-block: 2ch;
/* or */
margin-block: 2ch 2ch;

之前没有“顶部和底部”或“左侧和右侧”的简写形式,但现在有了! 您可能使用 margin: 10px; 的缩写形式引用了所有 4 个边,现在,您可以使用逻辑属性缩写形式轻松引用 2 个互补边。

手写
margin-inline-start: 4ch;
margin-inline-end: 2ch;
新的简写法
margin-inline: 4ch 2ch;

内边距简写法

没有推出任何新功能,但推出了更多超级实用的简写形式:
padding-blockpadding-inline


手写
padding-block-start: 2ch;
padding-block-end: 2ch;
新的简写法
padding-block: 2ch;
/* or */
padding-block: 2ch 2ch;

以及 inline 附赠的一组简写形式:

手写
padding-inline-start: 4ch;
padding-inline-end: 2ch;
新的简写法
padding-inline: 4ch 2ch;

内嵌和缩写

实体属性 toprightbottomleft 都可以写为 inset 属性的值。设置带内边距的边对 position 的任何值都有好处。

.cover {
  position: absolute;
  top: 0;
  right: 0;
  bottom: 0;
  left: 0;
  inset: 0;
}


实体手写
position: absolute;
top: 1px;
right: 2px;
bottom: 3px;
left: 4px;
新的物理简写
position: absolute;
inset: 1px 2px 3px 4px;

这样看起来应该很方便!内边距是实体边的简写形式,其运作方式与外边距和内边距一样。

新功能

物理侧快捷字词虽然很有趣,但额外的 inset 快捷字词带来的逻辑功能更为丰富。这些缩写不仅为开发者带来了编写便利(输入更短),还因为它们与流程相关,从而扩大了布局的潜在覆盖面。

实体手写
position: absolute;
top: 10px;
bottom: 10px;
逻辑简写
position: absolute;
inset-block: 10px;


实体手写
position: absolute;
left: 10px;
right: 20px;
逻辑简写
position: absolute;
inset-inline: 10px 20px;

如需进一步了解并查看内嵌缩写法和长写法完整列表,请访问 MDN。

边框缩写

Border 及其嵌套的 colorstylewidth 属性也都新增了逻辑缩写。


实体手写
border-top-color: hotpink;
border-bottom-color: hotpink;
逻辑简写
border-block-color: hotpink;
/* or */
border-block-color: hotpink hotpink;


实体手写
border-left-style: dashed;
border-right-style: dashed;
逻辑简写
border-inline-style: dashed;
/* or */
border-inline-style: dashed dashed;


实体手写
border-left-width: 1px;
border-right-width: 1px;
逻辑简写
border-inline-width: 1px;
/* or */
border-inline-width: 1px 1px;

如需进一步了解,请参阅 MDN 上的边框缩写和长写形式的完整列表

逻辑属性 <figure> 示例

我们通过一个小例子来综合运用这些知识。逻辑属性可以为图片添加说明,以处理不同的书写方向和文档方向。

或者试试!

只需使用 <figure> 和一些逻辑属性,您就可以轻松让卡片在全球范围内适应各种屏幕尺寸。如果您好奇这些在国际范围内考虑到不同文化的 CSS 是如何协同发挥作用的,希望这篇简短的介绍对您有所帮助。

多填充和跨浏览器支持

若要让新旧浏览器都能正确显示,并使用经过更新的逻辑属性,Cascade 或构建工具是可行的选择。对于级联回退,请在实体属性后面跟上逻辑属性,浏览器将使用其在样式解析期间找到的“最后一个”属性。

p {
  /* for unsupporting browsers */
  margin-top: 1ch;
  margin-bottom: 2ch;

  /* for supporting browsers to use */
  /* and unsupporting browsers to ignore and go 🤷‍♂️ */
  margin-block: 1ch 2ch;
}

不过,这并非适合所有人的完整解决方案。下面是一个手写的回退方案,它利用 :lang() 伪类选择器定位到特定语言,适当地调整其实际间距,然后在最后为支持的浏览器提供逻辑间距:

/* physical side styles */
p {
  margin-top: 1ch;
  margin-bottom: 2ch;
}

/* adjusted physical side styles per language */
:lang(ja) {
  p {
    /* zero out styles not useful for traditional Japanese */
    margin-top: 0;
    margin-bottom: 0;

    /* add appropriate styles for traditional Japanese */
    margin-right: 1ch;
    margin-left: 2ch;
  }
}

/* add selectors and adjust for languages all supported */
:lang(he) {}
:lang(mn) {}

/* Logical Sides */
/* Then, for supporting browsers to use */
/* and unsupporting browsers to ignore #TheCascade */
p {
  /* remove any potential physical cruft.. */
  margin: 0;
  /* explicitly set logical value */
  margin-block: 1ch 2ch;
}

您还可以使用 @supports 确定是否提供实体属性回退:

p {
  margin-top: 1ch;
  margin-bottom: 2ch;
}

@supports (margin-block: 0) {
  p {
    margin-block: 1ch 2ch;
  }
}

SassPostCSSEmotion 等工具提供了自动化捆绑器和/或构建时产品,这些产品提供了各种回退或解决方案。请查看每种方法,看看哪种方法最适合您的工具链和整体网站策略。

后续步骤

更多 CSS 将提供逻辑属性,我们还在努力!不过,我们缺少一组重要的简写形式,并且此 GitHub 问题仍在等待解决。草稿中提供了临时解决方案。如果您想使用缩写为框的所有逻辑边设置样式,该怎么办?

物理速记法
margin: 1px 2px 3px 4px;
margin: 1px 2px;
margin: 2px;
逻辑简写
margin: logical 1px 2px 3px 4px;
margin: logical 1px 2px;
margin: logical 2px;

当前的草稿提案意味着,您必须在每个缩写中都写入 logical,才能应用逻辑等效项,这在某些人看来似乎不太符合DRY (DRY) 原则。

还有其他提案建议在块级或页面级更改它,但这可能会导致逻辑用法泄露到仍假定物理边的样式中。

html {
  flow-mode: physical;
  /* or */
  flow-mode: logical;
  /* now all margin/padding/etc references are logical */
}

/* hopefully no 3rd/1st party code is hard coded to top/left/etc ..? */

这是一个难题!欢迎投票并发表您的意见,我们期待收到您的反馈。

想要详细了解或研究逻辑属性?如需详细参考文档以及指南和示例,请访问 MDN 网站

反馈