使用 margin-trim,布局更简便

如果你经常编写 CSS,那么你一定会经历这样的时刻:你不太确定如何完成你想要完成的工作。通常,你会求助于教程或文档,学习更多有关 CSS 的知识来完成工作。但每隔一段时间,你就会发现没有 “正确 “的方法来完成你想做的事情。于是,你会想出(或借用)一个让人感觉很笨拙的解决方案。也许它需要很多复杂的选择器。又或者,它对目前的内容有效,但你担心有一天,有人会在网站上添加不同的 HTML,而你写的解决方案就会崩溃。

在过去的十年中,CSS 已经成熟了很多。许多强大的解决方案填补了以前需要脆弱黑客才能实现的空白。现在,又多了一个–margin-trim

Margin trim

margin-trim 属性可以让你告诉容器修剪其子容器的边距,也就是任何顶到容器的边距。这样一来,子元素与容器之间的所有边距空间都被消除了。

 

图0:使用 margin-trim,布局更简便元素周期表当边距位于孙子辈或曾孙子辈或曾曾曾孙子辈时,这也同样有效。如果在容器内的任何内容上使用 margin 创建了空间,并且该空间与容器相抵,那么在对容器应用 margin-trim 时,该空间就会被修剪掉。

图1:使用 margin-trim,布局更简便让我们举一个实际的例子。假设我们在article 元素中包含多个段落,而这些段落都有边距。同时,容器上还有填充。

article {
  padding: 2lh;
  background: white;
  p {
    margin-block: 1lh;
  }
}

这是非常典型的代码。容器上的 padding 本应在整个方框内创建均匀的空间,但内容的上方和下方却出现了额外的空白。就像这样

图2:使用 margin-trim,布局更简便段落之间的页边距为 1lh,文章框的填充为 2lh,我们试图创建一个漂亮的排版布局。让我们打开一些指南,以便更好地查看额外空间的来源。article 框的填充和段落的边距分别用不同的颜色标记。

图3:使用 margin-trim,布局更简便第一段和最后一段的页边距(1lh)被添加到填充(2lh)中,从而在块方向上形成一个 3lh 的空间。

如果去掉第一段上方的边距和最后一段下方的边距,设计效果会更好。在有 margin-trim 之前,我们会尝试去掉第一段和最后一段的页边距,或减少块方向的填充……但我们采取的任何方法都将取决于内部的内容。也许article 的另一个例子会以一个标题开始,而这个标题的顶部边距是不同的。或者开始时使用一张没有边距的图片。

如果不能百分之百确定框内的内容,就很难保证间距能达到预期效果。直到现在。

新的 margin-trim 属性为我们提供了一种简单的方法,让我们可以直接提出自己的要求。我们可以告诉框消除任何与框相邻的边距。

例如

article {
  margin-trim: block;
  padding: 2lh;
  background: white;
  p {
    margin-block: 1lh;
  }
}

现在,浏览器会自动切掉块方向上任何与article 框边缘相接触的边距,在本例中就是框的顶部和底部。

图4:使用 margin-trim,布局更简便请注意,虽然边距是在 <p> 元素上定义的,但您在 <article> 元素上声明了 margin-trim。你总是将 margin-trim 应用于容器,而不是首先有 margin 的元素。

这就是最终结果。

 

图5:使用 margin-trim,布局更简便

请亲自尝试

您可以在 Safari 16.4 或更高版本的 Safari 中,在此实时演示中试用 margin-trim

 

图6:使用 margin-trim,布局更简便

浏览器支持

两年多前,Safari 浏览器开始支持margin-trim 。但到目前为止,Safari 是唯一支持该功能的浏览器。那么,对于不支持的浏览器该怎么办呢?在我们的演示中,您可以在功能查询中编写回退代码,如下所示:

article { 
  margin-trim: block;
  font-size: 1.2rem;
  line-height: 1.3;
  padding: 2lh;
  p {
    margin-block: 1lh;
  }
}
@support not (margin-trim: block) {
  article { 
    :first-child {
      margin-block-start: 0;
    }
    :last-child {
      margin-block-end: 0;
    }
  }
}

这有助于澄清 margin-trim 与我们一直使用的旧技术之间的区别。

使用 :first-child :last-child 时,任何作为容器的第一个或最后一个直接子元素的边距都会被修剪。但任何未被元素包装或在 DOM 结构中嵌套较深的内容都不会被修剪。

 

图7:使用 margin-trim,布局更简便例如,如果第一个元素是有顶边距的图形,而图形中包含的图片也有顶边距,那么这两个边距都会被 margin-trim 修剪,而只有图形的边距会被 :first-child 修剪。

<article>
  <figure style="margin-top: 1em">
    <img  style="margin-top: 1em" src="photo.jxl" alt="[alt]">
    <figcaption></figcaption>
  </figure>
</article>  

margin-trim 属性使修剪这种边距比以前的技术更简单、更强大。

尽管 Safari 是目前唯一支持该属性的浏览器,但现在使用它还是很有意义的。在不支持该属性的浏览器中,将较复杂的布局代码放在功能查询中(如@support not (margin-trim: block) { }),而在支持该属性的浏览器中使用 margin-trim。希望不那么强大的代码也能正常工作。无论如何,这都是你必须编写的代码。但与此同时,支持该功能的浏览器将获得更强大的解决方案。随着越来越多的浏览器加入支持,越来越多的用户将保证拥有一个无论如何都不会出错的布局。

Margin Trim 的选项

margin-trim 的值都是逻辑值,指的是 blockinline directions

  • margin-trim: none
  • margin-trim: block
  • margin-trim: inline
  • margin-trim: block-start
  • margin-trim: block-end
  • margin-trim: inline-start
  • margin-trim: inline-end

如果想同时向两个方向修剪,可以通过组合长手数值来实现。例如

margin-trim: block-start block-end inline-start inline-end;

2024 年 12 月,CSSWG 决定也允许将较短的blockinline结合使用,从而允许使用这样的语法:

margin-trim: block inline;

WebKit 已经完成了支持最后一个选项的工作。敬请期待 Safari 技术预览版。关注本期,了解更多更新

让我们了解

CSS从未如此出色。我希望你能了解像这样的微小改进,并以此编写出更强大的代码。请在 Bluesky 或 Mastodon 上告诉我你的想法。我很乐意听到你的故事、功能请求和问题。

 

本文文字及图片出自 Easier layout with margin-trim

你也许感兴趣的:

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注