因此,您正在进行设计。您需要一个全宽容器元素,因为设计有一个从边缘到边缘水平延伸的 background-color
。但是内部的内容不必从边缘到边缘。您想要
- 限制宽度(针对大屏幕)
- 填充边缘
- 居中内容
这是网页布局中的“内部问题”。它并不难,只是有很多需要考虑的事项。
“内部”问题。全宽颜色带内的居中、最大宽度/填充容器。
您最喜欢的模式是什么?
(只是一个有趣的日常事物,有很多可能的解决方案需要考虑!) pic.twitter.com/pNYf5YsQMp
— Chris Coyier (@chriscoyier) 2019 年 3 月 14 日
经典的解决方案是外层容器和内层容器。
父元素的宽度自然与其自身的父元素相同,让我们假设它是 <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
或在需要的地方放置一个伪元素来“模拟”左右两侧。
我之前使用伪
::before
和::after
元素实现过这一点。这有点笨拙,并且存在一些水平溢出的问题,但在一些限制性很强的场景中,我无法控制结构,但它完成了任务。通常情况下,我会使用一个<section>
元素来实现这一点,该元素有一个用于内容的子容器,类似于您的“经典”解决方案,并且父节元素始终是全宽的。我认为网格非常适合此用途。查看更新后的笔以了解示例:https://codepen.io/tmassman/pen/JqryVZ
为什么您要进行计算,如果浏览器可以为您完成呢?您展示的技术对于不支持网格的浏览器来说是完全可以的。
该演示的一个问题
啊,我完全错过了。感谢您的提示!我已经更新了笔,以考虑左右填充。
很棒的方法,正是我要评论的,网格绝对可以很容易地解决这个问题。
对于
.full-width
实用程序,我认为您可以完全跳过 transform(尽管它不会解决您随后提到的有关滚动条的问题)。我认为是 Ana Tudor 在 Twitter 上提到了这一点这篇文章很棒,Chris。感谢您将这些不同的方法汇总在一起。我将来一定会在我的工作中使用这些提示:)
可以在该单个元素上添加一个不可见的边框来防止边缘接触。这远非理想,但如果您无法控制您的 html,有时您不得不做出妥协。
对于我的最后一个玩耍项目,我想避免使用 margin 或 padding,同时实现以下目标
父元素包含不同的内容:标题、段落、图像、引用等。它可以是一个 article 元素。
大多数子元素将具有 max-width 以防止过长的文本行。
这些文本元素需要在移动屏幕上与左侧和右侧屏幕边框保持边距。
某些子元素将占据全宽或更宽的宽度,例如应该“弹出”的图像或大型花哨的文字引用等。
我最终得到了以下对我有用的解决方案
您如何看待我的方法?
不是真的,您指的是什么边缘接触
对于单个元素选项,您可以在计算中包含 padding 值以确保在较小的屏幕上没有边缘接触。对于您要从现有容器中跳出的版本,您可以将背景颜色应用于伪元素并为其提供 100vw 宽度和负转换,使常规元素保持原样(除了根据需要应用 position: relative)。
这就是我们目前的操作方式
唯一令人讨厌的是为 contain 创建 max-width 断点,这需要根据您想要的 max-width 以及以前断点的左右填充来计算,这样您就可以获得干净的过渡且没有边缘接触。
我能够通过绝对定位
::before
元素(不指定其top
)来轻松地实现这一点:https://codepen.io/mpetrovich/pen/zQpjrYAndy Bell 在他的博客上提供了一个很好的介绍,Creating a full bleed CSS utility: https://andy-bell.design/wrote/creating-a-full-bleed-css-utility/
过去 4 到 5 年我一直这样做……不需要额外的标记。
在任何支持视窗单位的地方都能正常工作,并且失败得很好。
有时需要在 body 上进行 z-index 和 overflow 调整以确保万无一失,但除此之外非常健壮。
使用 padding 来计算断点怎么样?
https://codepen.io/jricarte/pen/BerqxM
我需要一个布局来允许一个包含 2 列的行,该行具有全宽 2 列/颜色背景。我基本上在列上使用了响应式
::before
全宽实用程序。