模块底部的间距

Avatar of Chris Coyier
Chris Coyier 发布

DigitalOcean 为您旅程的每个阶段提供云产品。 立即开始使用 200 美元的免费额度!

编辑注: 正在寻找一种更现代的方法来在元素之间获得一致的底部间距? Heydon Pickering 的 “被切除脑叶的猫头鹰”选择器 是一种不错的方法,在我们等待 margin-trim 属性获得支持的同时可以使用。

啊,谦逊的模块!如今,许多设计都在内容型和应用型网站中使用模块。 一块信息、一则广告、一组功能……可以是任何东西。 它们可能具有视觉相似性,但可以包含任何内容,这带来了一个有趣的 CSS 挑战:如何一致地填充内部?

这是一个简单的示例,其中模块通过颜色差异与背景区分开来

html {
  background: #333;
}
.module {
  width: 20rem;
  padding: 1.5rem;
  margin: 1.5rem auto;
  background: white;
}
简单易懂。没什么大不了的。均匀填充。

但是,一旦该模块包含其他元素,填充就会“偏离”。

模块

Pellentesque habitant morbi tristique senectus…

段落很可能应用了一些全局排版规则,这些规则很可能具有一些底部边距。 即使您使用 选择性排版,您也可能在这里选择使用它,因为这里有文本。

 

模块中的段落。

看到较大的底部填充了吗?也许您觉得没问题,但我怀疑并非如此。 这种沉重感来自您在模块本身设置的一致填充加上段落的底部边距。

 

红色 = 段落底部边距

那么我们该怎么做呢?一个权宜之计是删除这些段落的边距。

.module p {
  margin: 0;
}

但我相信我们都同意这很糟糕。 如果一个模块包含两个段落会怎样?现在它们会笨拙地彼此紧贴。

也许只有最后一个?

.module p:last-child {
  margin: 0;
}

这可能行得通。但是这个修复仍然感觉有点笨拙。如果问题元素将来根本不是段落会怎样?它可能是一个

    • 或者

 

      1. 。或者

 

。或者任何其他 HTML 元素……我们要列出每个 HTML 元素吗?

 

.module p:last-child,
.module ul:last-child,
.module ol:last-child,
.module dl:last-child {
  /* losing battle */
  margin: 0;
}

这绝对是一场必败的战斗。

但我们可以匹配任何元素……

.module *:last-child {
  margin: 0;
}

您甚至可以省略那里的“*”,因为它被隐含且没有特异性,但我认为它使它更清晰。 我认为这更接近一个好的修复,但它有点笨重。 列表始终具有此操作会影响的子元素。 任何具有后代的元素都会成为问题。 为了解决这个问题,我们只需确保模块下只有顶级元素使用 子元素选择器 接受这种处理。

.module > *:last-child {
  margin: 0;
}

这不错。我仍然不会称其为完美,因为后代实际上可能是最终额外底部填充的原因。 比如如果列表项中包含段落。 您可能需要将它们链接几次以匹配合理的 DOM 深度。

.module > *:last-child,
.module > *:last-child > *:last-child,
.module > *:last-child > *:last-child > *:last-child {
  margin: 0;
}

这可能就可以了。

这是一个可视化演示

查看 Chris Coyier 在 CodePen 上的 Pen JFynD (@chriscoyier)


一种完全不同的方法可能是从模块中去除底部填充,并让子元素提供它,但我觉得这有点危险,因为无法保证子元素会自带自己的(例如一些通用的

).

 

您遇到过这种情况吗?您是否有自己喜欢的解决方案?