最近我正在尝试重新设计博客列表。想法是为读者提供来自这些博客的最新文章,采用杂志风格的布局,而不是仅仅在侧边栏中列出我们最喜欢的博客。
轻松的部分是从我们最喜欢的RSS源中获取包含摘要的文章列表。为此,我们使用了WordPress插件Feedzy lite,它可以将多个Feed聚合到一个按时间排序的列表中——非常适合展示它们的最新内容。困难的部分是让它看起来很棒。
该插件的默认列表UI相当平淡无奇,所以我想将其样式设计成类似报纸或杂志网站,混合使用较小和较大的“特色内容”面板。
这似乎是CSS Grid的理想用例!为不同的布局创建网格布局,例如,一个五列布局和一个三列布局,然后使用媒体查询在不同的断点之间切换。对吧?但是,当我们可以使用网格的自动适应选项为我们自动创建一个流畅的响应式网格时,我们真的需要这些媒体查询——以及识别断点的所有麻烦吗?
这种方法听起来很有吸引力,但是当我开始引入跨列元素时,我遇到了网格在窄屏幕上溢出的问题。媒体查询似乎是唯一解决方案。也就是说,直到我找到一个解决方法!
在查看了几个关于CSS Grid的教程后,我发现它们主要分为两类:
- 向您展示如何使用跨越元素创建有趣的布局的教程,但列数是固定的。
- 解释如何制作自动调整大小的响应式网格的教程,但所有网格项的宽度都相同(即没有跨列)。
我想让网格同时做到这两点:创建一个完全响应式的流体布局,其中还包括响应式调整大小的多列元素。
美妙之处在于,一旦您理解了响应式网格的局限性,以及为什么以及何时列跨度会破坏网格响应性,就可以仅用十几行代码加上一个简单的媒体查询(或者如果您愿意限制跨度选项,甚至无需媒体查询)来定义响应式杂志/新闻样式布局。
这是一个视觉效果,显示了开箱即用的RSS插件以及我们对其进行样式设置后的样子。
此杂志风格的网格布局是完全响应式的,彩色特色面板会随着列数的变化而动态调整。页面显示大约50篇文章,但布局代码与显示的项目数量无关。将插件升级以显示100个项目,布局一直保持有趣。
所有这一切都只使用CSS实现,并且只有一个媒体查询来处理最窄屏幕(即小于460像素)上的单列显示。
令人难以置信的是,这个布局只用了21行CSS代码(不包括全局内容样式)。但是,为了用这么少的代码行实现这种灵活性,我不得不深入研究CSS Grid的一些更晦涩的部分,并学习如何解决它的一些固有限制。
产生此布局的代码的基本元素非常短,证明了CSS Grid的强大功能:
<code>.archive { display: grid; grid-template-columns: repeat(auto-fit, minmax(210px, 1fr)); grid-gap: 32px; grid-auto-flow: dense; } /* 特宽网格文章 */ .article:nth-child(31n 1) { grid-column: 1 / -1; } .article:nth-child(16n 2) { grid-column: -3 / -1; } .article:nth-child(16n 10) { grid-column: 1 / -2; } /* 手机单列显示 */ @media (max-width: 459px) { .archive { display: flex; flex-direction: column; } }</code>
本文中的技术同样可以很好地用于设置任何动态生成的内容,例如最新文章小部件、存档页面或搜索结果的输出。
创建响应式网格
我设置了十七个项目,显示各种模拟内容——标题、图像和摘录——它们都包含在一个包装器中
<code><div> </div></code>
将这些项目转换为响应式网格的代码非常紧凑:
<code>.archive { /* 将元素定义为网格容器 */ display: grid; /* 自动适应尽可能多的项目在一行上,而不会低于180像素 */ grid-template-columns: repeat(auto-fit, minmax(180px, 1fr)); /* 文章之间的一点间距 */ grid-gap: 1em; }</code>
请注意,行高会自动调整以适应行中最高的內容。如果您更改Pen的宽度,您将看到项目流畅地增长和缩小,列数分别从一列变为五列。
此处使用的CSS Grid魔法是auto-fit
关键字,它与应用于grid-template-columns
的minmax()
函数配合使用。
工作原理
我们可以仅使用以下方法实现五列布局:
<code>.archive { display: grid; grid-template-columns: repeat(5, 1fr); }</code>
但是,这将创建五个列,这些列会随着不同屏幕宽度的变化而增长和缩小,但始终保持五列,导致它们在小屏幕上变得非常窄。第一个想法可能是创建一堆媒体查询并使用不同数量的列重新定义网格。这可以正常工作,但是使用auto-fit
关键字,所有这些都自动完成。
为了使auto-fit
按我们想要的方式工作,我们需要使用minmax()
函数。这告诉浏览器列可以压缩到多小,然后是它们可以扩展到的最大宽度。更小,它将自动减少列数。更大,列数增加。
<code>.archive { grid-template-columns: repeat (auto-fit, minmax(180px, 1fr)); }</code>
在此示例中,浏览器将尽可能多地容纳180像素宽的列。如果剩余空间,列将通过在它们之间共享剩余空间而平均增长——这就是1fr
值所说的:使列成为可用宽度的相等分数。
拖动窗口,随着可用空间的增加,所有列都会平均增长以使用任何额外的空间。列将继续增长,直到可用空间允许增加一列180像素,此时将出现一整列。减小屏幕宽度,该过程将反转,完美地将网格调整到单列布局。神奇!
而您只需一行代码即可获得所有这些响应能力。这有多酷?
使用“autoflow: dense”创建跨度
到目前为止,我们有一个响应式网格,但所有项目宽度都相同。对于新闻或杂志布局,我们需要一些内容通过跨越两列或更多列甚至可能跨越所有列来突出显示。
为了创建多列跨度,我们可以将column-span
功能添加到我们想要占据更多空间的网格项目中。例如,如果我们希望列表中的第三个项目为两列宽,我们可以添加:
<code>.article:nth-child(3) { grid-column: span 2; }</code>
但是,一旦我们开始添加跨度,就会出现许多问题。首先,网格中可能会出现间隙,因为宽项目可能无法适应行,因此网格自动适应将其推到下一行,留下它本来应该在的位置的间隙:
简单的解决方法是向网格元素添加grid-auto-flow: dense
,这会告诉浏览器用其他项目填充任何间隙,有效地使较窄的内容围绕较宽的项目流动,如下所示:
请注意,项目现在是无序的,第四个项目出现在双倍宽度的第三个项目之前。据我所知,无法避免这种情况,这是您必须接受的CSS Grid的局限性之一。
查看Geoff Graham的“网格密集关键字的自动流动能力”,了解grid-auto-flow: dense
的介绍以及它如何运行的示例。
指定跨度的几种方法
有几种方法可以指示项目应跨越多少列。最简单的方法是将grid-columns: span [n]
应用于其中一个项目,其中n是元素将跨越的列数。我们布局中的第三个项目具有grid-column: span 2
,这解释了为什么它的宽度是仅跨越一列的其他项目的两倍。
其他方法需要您显式定义网格线。网格线的编号系统如下:
可以使用正值(例如1、2、3)或负值(例如-1、-2、-3)从左到右指定网格线,以从右到左进行。这些可用于使用grid-column
属性在网格上放置项目,如下所示:
<code>.grid-item { grid-column: (起始轨道) / (结束轨道); }</code>
因此,这为我们提供了指定跨越项目的其他方法。这尤其灵活,因为起始值或结束值都可以替换为span
关键字。例如,上面示例中的三列蓝色框可以通过向第八个网格项目添加以下任何内容来创建:
grid-column: 3 / 6
grid-column: -4 / -1
grid-column: 3 / span 3
grid-column: -4 / span 3
grid-column: span 3 / -1
- 等等
在非响应式(即固定列)网格上,所有这些都会产生相同的效果(如上图中的蓝色框),但是,如果网格是响应式的并且列数发生变化,它们的差异就会开始显现。某些列跨度会破坏具有自动流动网格的布局,使这两种技术看起来不相容。幸运的是,有一些解决方案可以让我们成功地将两者结合起来。
但是,首先,我们需要了解问题。
溢出侧滚动问题
以下是使用上述符号创建的一些特色区域:
在全宽(五列)时,一切看起来都很好,但当调整大小到应该是两列时,布局会像这样中断:
如您所见,我们的网格失去了响应能力,尽管容器已缩小,但网格试图保持所有五列。为此,它放弃了尝试保持等宽列,并且网格从其容器的右侧溢出,导致水平滚动。
这是为什么?问题是浏览器试图遵守我们命名的显式网格线。在这个宽度下,自动适应网格应该隐式地显示两列,但是我们的网格线编号系统通过显式引用第五条网格线与之相矛盾。这种矛盾导致混乱。为了正确显示我们隐式的两列网格,唯一允许的行号是1、2和3以及-3、-2、-1,如下所示:
但是,如果我们的任何网格项目包含位于此范围之外的grid-column
引用,例如网格线编号4、5或6(或-4、-5或-6),则浏览器会收到混合消息。一方面,我们要求它自动创建灵活的列(这应该隐式地为我们提供此屏幕宽度下的两列),但我们还显式地引用了在两列网格中未出现的网格线。当隐式(自动)列和显式列数之间存在冲突时,网格始终偏向于显式网格;因此会出现不需要的列和水平溢出(这也恰当地被称为CSS数据丢失)。就像使用网格线编号一样,跨度也可以创建显式列。因此,grid-column: span 3
(演示中的第八个网格项目)强制网格显式采用至少三列,而我们希望它隐式显示两列。
在这一点上,似乎唯一前进的道路是使用媒体查询在我们的布局中断的宽度处更改grid-column
值——但不要太快!这正是我一开始的假设。但是,在更仔细地考虑并尝试各种选项之后,我发现有一些有限的解决方法可以一直向下工作到两列,只留下一个媒体查询来处理最窄屏幕上的单列布局。
解决方案
我意识到,诀窍是只使用您打算显示的最窄网格中出现的网格线来指定跨度。在这种情况下,是两列网格。(我们将使用媒体查询来处理最窄屏幕上的单列场景。)这意味着我们可以安全地使用网格线1、2和3(或-3、-2和-1)而不会破坏网格。
我最初认为这意味着将自己限制在最多两列的跨度,使用以下组合:
grid column: span 2
grid-column: 1 /3
grid-column: -3 / -1
这在一直到两列的范围内都保持完美的响应能力:
虽然这有效,但从设计的角度来看,它相当有限,而且不是特别令人兴奋。我希望能够创建在大型屏幕上为三列、四列甚至五列宽的跨度。但是怎样呢?我的第一个想法是我必须求助于媒体查询(天哪,旧习惯很难改!),但我试图摆脱这种方法并以不同的方式思考响应式设计。
再次查看我们仅使用1到3和-3到-1可以做什么,我逐渐意识到我可以混合使用网格列的起始值和结束值的正数和负数,例如1/-3和2/-2。乍一看,这似乎不是很令人感兴趣。当您意识到这些线条在调整网格大小时的位置时,情况就会发生变化:这些跨越的元素会随着屏幕大小的变化而改变宽度。这为响应式列跨度开辟了一整套新的可能性:随着屏幕变宽,将跨越不同列数的项目,而无需媒体查询。
我发现的第一个例子是grid-column: 1/-1
。这使得项目像一个全宽横幅一样,在所有列数下都从第一列跨越到最后一列。它甚至适用于一列宽!
通过使用grid-column: 1/-2
,可以创建一个左对齐的几乎全宽跨度,它始终会在其右侧留下一列项目。当缩小到两列时,它会响应式地缩小到一列。令人惊讶的是,当缩小到单列布局时,它甚至也能工作。(原因似乎是网格不会将项目压缩到零宽度,因此它保持一列宽,grid-column: 1/1
也是如此。)我假设grid-column: 2/-1
的工作方式类似,但与右侧边缘对齐,并且在大多数情况下确实如此,除了单列显示时会导致溢出。
接下来我尝试了1/-3
,它在较宽的屏幕上工作得很好,显示至少三列,在较小的屏幕上显示一列。我认为它在两列网格上会做一些奇怪的事情,因为第一条网格线与-3的网格线相同。令我惊讶的是,它仍然作为单列项目正常显示。
经过大量的尝试,我找到了十一个可能的网格列值,使用了来自两列网格的网格线编号。令人惊讶的是,其中三个一直到单列布局都能正常工作。另外七个可以一直向下工作到两列,只需要一个媒体查询来处理单列显示。
这是完整的列表:
如您所见,虽然这是所有可能的响应式跨度的有限子集,但实际上有很多可能性。
-
2/-2
很有趣,因为它创建了一个居中的跨度,一直到一列都能正常工作! -
3/-1
最没用,因为它即使在两列情况下也会导致溢出。 -
3/-3
是一个惊喜。
通过使用此列表中的各种grid-column
值,可以创建有趣且完全响应的布局。对于最窄的单列显示,使用单个媒体查询,我们可以使用十种不同的网格列跨度模式。
单列媒体查询通常也很简单。此最终演示上的一个在较小的屏幕上恢复使用flexbox:
<code>@media (max-width: 680px) { .archive { display: flex; flex-direction: column; } .article { margin-bottom: 2em; } }</code>
这是最终网格,如您所见,它从一列到五列都是完全响应式的:
使用 :nth-child() 重复可变长度显示
我用来将代码减少到二十几行的最后一个技巧是:nth-child(n)
选择器,我用它来设置网格中的多个项目样式。我希望我的跨度样式应用于我的Feed中的多个项目,以便特色帖子框定期出现在页面中。首先,我使用了逗号分隔的选择器列表,如下所示:
<code>.article:nth-child(2), .article:nth-child(18), .article:nth-child(34), .article:nth-child(50) { background-color: rgba(128,0,64,0.8); grid-column: -3 / -1; }</code>
但我很快发现这很麻烦,尤其是我必须为我想在每篇文章中设置样式的每个子元素重复此列表——例如标题、链接等等。在原型设计期间,如果我想玩弄跨越元素的位置,我必须手动更改这些列表中的数字,这既费力又容易出错。
那时我意识到我可以使用强大的功能:nth-child
伪选择器,而不是像我在上面的列表中使用的那样简单的整数。:nth-child(n)
也可以采用等式,例如:nth-child(2n 2)
,它将定位每个第二个子元素。
以下是如何使用:nth-child([公式])
在我的网格中创建蓝色全宽面板,这些面板出现在页面的顶部,并在页面下方重复出现:
<code>.article:nth-child(31n 1) { grid-column: 1 / -1; background: rgba(11, 111, 222, 0.5); }</code>
括号中的位 (31n 1) 确保选择第1个、第32个、第63个等子项。浏览器运行一个循环,从n=0开始(在这种情况下,31 0 1 = 1),然后是n=1(31 1 1 = 32),然后是n=2(31 * 2 1 = 63)。在最后一种情况下,浏览器意识到没有第63个子项,因此它忽略该项,停止循环,并将CSS应用于第1个和第32个子项。
我对从右到左交替出现的紫色框做了类似的操作:
<code>.article:nth-child(16n 2) { grid-column: -3 / -1; background: rgba(128, 0, 64, 0.8); } .article:nth-child(16n 10) { grid-column: 1 / -2; background: rgba(128, 0, 64, 0.8); }</code>
第一个选择器用于右侧的紫色框。16n 2 确保样式应用于每第16个网格项目,从第二个项目开始。
第二个选择器定位右侧的框。它使用相同的间距 (16n),但偏移量不同 ( 10)。结果,这些框会定期出现在第10、26、42等网格项目的右侧。
当涉及到这些网格项目及其内容的视觉样式时,我使用了另一个技巧来减少重复。对于两个框共享的样式(例如,background-color
),可以使用单个选择器来定位两者:
<code>.article:nth-child(8n 2) { background: rgba(128, 0, 64, 0.8); /* 其他共享样式 */ }</code>
这将定位项目 2、10、18、26、34、42、50等等。换句话说,它选择左右两个特色框。
它之所以有效是因为 8n 正好是 16n 的一半,并且因为两个单独选择器中使用的偏移量相差 8(即 10 和 2 之间的差是 8)
最后的想法
目前,CSS Grid 可用于使用最少的代码创建灵活的响应式网格,但这确实对在不使用媒体查询的倒退步骤的情况下定位元素有一些重要的限制。
能够指定不会在较小屏幕上强制溢出的跨度会很棒。目前,我们实际上是告诉浏览器,“请创建一个响应式网格”,它做得非常漂亮。但是当我们继续说,“哦,并且使这个网格项目跨越四列”时,它会在窄屏幕上发脾气,优先考虑四列跨度请求而不是响应式网格。能够告诉网格优先考虑响应能力而不是我们的跨度请求会很棒。类似这样:
<code>.article { grid-column: span 3, autofit; }</code>
响应式网格的另一个问题是最后一行。随着屏幕宽度的变化,最后一行经常不会被填充。我花了很长时间寻找一种方法来使最后一个网格项目跨越(并因此填充)剩余的列,但目前看来您无法在Grid中做到这一点。如果我们可以使用像auto
这样的关键字来指定项目的起始位置,那就太好了,这意味着“请将左边缘放在它落下的任何位置”。类似这样:
<code>.article { grid-column: auto, -1; }</code>
……这将使左边缘跨越到行的末尾。
以上是仅20行CSS中的响应式网格杂志布局的详细内容。更多信息请关注PHP中文网其他相关文章!

具有CSS的自定义光标很棒,但是我们可以将JavaScript提升到一个新的水平。使用JavaScript,我们可以在光标状态之间过渡,将动态文本放置在光标中,应用复杂的动画并应用过滤器。

互动CSS动画和元素相互启动的元素在2025年似乎更合理。虽然不需要在CSS中实施乒乓球,但CSS的灵活性和力量的增加,可以怀疑Lee&Aver Lee&Aver Lee有一天将是一场

有关利用CSS背景滤波器属性来样式用户界面的提示和技巧。您将学习如何在多个元素之间进行背景过滤器,并将它们与其他CSS图形效果集成在一起以创建精心设计的设计。

好吧,事实证明,SVG的内置动画功能从未按计划进行弃用。当然,CSS和JavaScript具有承载负载的能力,但是很高兴知道Smil并没有像以前那样死在水中

是的,让#039;跳上文字包装:Safari Technology Preview In Pretty Landing!但是请注意,它与在铬浏览器中的工作方式不同。

此CSS-tricks更新了,重点介绍了年鉴,最近的播客出现,新的CSS计数器指南以及增加了几位新作者,这些新作者贡献了有价值的内容。

在大多数情况下,人们展示了@Apply的@Apply功能,其中包括Tailwind的单个property实用程序之一(会改变单个CSS声明)。当以这种方式展示时,@Apply听起来似乎很有希望。如此明显


热AI工具

Undresser.AI Undress
人工智能驱动的应用程序,用于创建逼真的裸体照片

AI Clothes Remover
用于从照片中去除衣服的在线人工智能工具。

Undress AI Tool
免费脱衣服图片

Clothoff.io
AI脱衣机

Video Face Swap
使用我们完全免费的人工智能换脸工具轻松在任何视频中换脸!

热门文章

热工具

适用于 Eclipse 的 SAP NetWeaver 服务器适配器
将Eclipse与SAP NetWeaver应用服务器集成。

mPDF
mPDF是一个PHP库,可以从UTF-8编码的HTML生成PDF文件。原作者Ian Back编写mPDF以从他的网站上“即时”输出PDF文件,并处理不同的语言。与原始脚本如HTML2FPDF相比,它的速度较慢,并且在使用Unicode字体时生成的文件较大,但支持CSS样式等,并进行了大量增强。支持几乎所有语言,包括RTL(阿拉伯语和希伯来语)和CJK(中日韩)。支持嵌套的块级元素(如P、DIV),

DVWA
Damn Vulnerable Web App (DVWA) 是一个PHP/MySQL的Web应用程序,非常容易受到攻击。它的主要目标是成为安全专业人员在合法环境中测试自己的技能和工具的辅助工具,帮助Web开发人员更好地理解保护Web应用程序的过程,并帮助教师/学生在课堂环境中教授/学习Web应用程序安全。DVWA的目标是通过简单直接的界面练习一些最常见的Web漏洞,难度各不相同。请注意,该软件中

Atom编辑器mac版下载
最流行的的开源编辑器

禅工作室 13.0.1
功能强大的PHP集成开发环境