“内部”问题

Avatar of Chris Coyier
Chris Coyier

DigitalOcean 为您的旅程的每个阶段提供云产品。立即开始使用 $200 免费积分!

因此,您正在进行设计。您需要一个全宽容器元素,因为设计有一个从边缘到边缘水平延伸的 background-color。但是内部的内容不必从边缘到边缘。您想要

  1. 限制宽度(针对大屏幕)
  2. 填充边缘
  3. 居中内容

这是网页布局中的“内部问题”。它并不难,只是有很多需要考虑的事项。

经典的解决方案是外层容器和内层容器。

父元素的宽度自然与其自身的父元素相同,让我们假设它是 <body> 元素,或者浏览器窗口的整个宽度。它采用 background-color 并填充左右两侧。内部元素是限制内部宽度和居中的元素。

<footer>
  <div class="inside">
    Content
  </div>
</footer>
footer {
  --contentWidth: 400px;
  background: lightcoral;
  padding: 2rem 1rem;
}

.inside {
  max-width: var(--contentWidth);
  margin: 0 auto;
}

这是我首先想到的。没有使用任何花哨的东西,感觉非常易于理解。这个“内部”元素并不十分理想,仅仅是因为每次使用这种模式时都需要记住将其添加到标记中,这感觉像是繁琐的工作,但它几乎没有其他缺点,可以达到目的。

查看 CodePen 上的
经典的“内部”元素
by Chris Coyier (@chriscoyier)
CodePen 上。

如果您只能使用一个元素会怎么样?

我不喜欢这种限制,因为我觉得一个健康的项目应该允许设计师和开发者对最终的 HTML、CSS 和 JavaScript 输出进行他们需要的任何控制,以便他们能够完成最佳的工作。但是,唉,有时您会处于承包商的奇怪位置,或者遇到遗留 CMS 问题等等。

如果您只有一个元素可以使用,填充可能有点有用。诀窍是使用 calc() 并从 100% 中减去内容最大宽度的一半。

<footer>
  Content
</footer>
footer {
  --contentWidth: 600px;
  
  background: lightcoral;
  padding: 2rem calc((100% - var(--contentWidth)) / 2);
}

查看 CodePen 上的
VOYxOa
by Chris Coyier (@chriscoyier)
CodePen 上。

这里的问题是它不能防止边缘接触,这可能会使它完全不可接受。也许您可以选择内部元素(段落等)并为它们添加填充(使用通用选择器,例如 footer > *)。人们很容易将填充添加到 <body> 或其他元素上以防止边缘接触,但这不起作用,因为我们想要这种边缘到边缘的背景颜色。

如果您已经在一个无法控制的容器内部,并且需要跳出它,该怎么办?

好吧,您始终可以执行老式的 全宽实用程序 操作。这将在任何宽度的居中容器中起作用

.full-width {
  width: 100vw;
  margin-left: 50%;
  transform: translateX(-50%);
}

但这也会使内部内容保持全宽。因此,您将需要再次转向内部元素。

查看 CodePen 上的
全宽元素,带内部元素
by Chris Coyier (@chriscoyier)
CodePen 上。

此外,一旦您有垂直滚动条,该 100vw 值就会触发一个令人讨厌的水平滚动条。一些网站可以执行类似的操作以摆脱该滚动条

body { overflow-x: hidden; }

那很棒。但是,如果您不能这样做,则可能需要在滚动条上设置一个明确的宽度,然后将其从 100vw 中减去。

body {
  scrollbar-width: 20px; /* future standards way */
}

body::-webkit-scrollbar { /* long-standing webkit way */
  width: 20px;
}

.full-width {
  width: calc(100vw - 20px);
}

即使这样也有些糟糕,因为这意味着当没有垂直滚动时,全宽容器不是完全全宽。我希望看到 CSS 在这里有所改进,可能通过改进视口单位的处理。

还有其他各种方法可以处理 全宽容器,例如使用边距将其拉到边缘等等。但是,它们最终都需要视口单位,因此会遭受相同的与滚动条相关的命运。

如果您能够确定隐藏父元素上的 overflow-x,则使用极大的负边距和正填充可以达到目的。

这很酷,因为它没有使用任何现代的东西。都是非常古老的 CSS 属性。

查看 CodePen 上的
使用负边距的全宽条
by Chris Coyier (@chriscoyier)
CodePen 上。

CSS Grid 或 Flexbox 可以在这里提供帮助吗?

呃,不是真的。

我的意思是,当然,您可以设置一个三列网格并将内容放置在中心列,同时使用外部列作为填充。我认为这不是网格的特别引人注目的用途,而且它增加了复杂性,却没有任何好处——除非您已经在该范围内使用和利用网格。

改为模拟边缘。

没有法律规定 background-color 必须来自一个连续的元素。您可以始终通过踢出一个巨大的 box-shadow 或在需要的地方放置一个伪元素来“模拟”左右两侧。

我们将在本文中介绍有关此方面的各种技术。