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

为 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

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

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 网站 🤓

反馈