现在我们做的响应式布局的一般都会用到媒体查询工具,那么能不能不用呢?那我告诉您,可以的,不妨来一试吧。
带有网格的响应式布局
首先可能是我最喜欢的所有解决方案,因为它的多功能性和易用性。使用 Grid,我们可以创建一组响应式列,这些列可以根据需要自行创建。我们将提供一个单一的约束——列的最小宽度——它在列项目进入新行之前作为一种“断点”发挥双重作用。
这是完成此响应式网格布局所需的全部,其中我们的最小列大小是30ch
通过辅助自定义属性设置的。此规则指示浏览器创建尽可能多的列,这些列至少要30ch
宽:
.grid { --min: 30ch; display: grid; grid-template-columns: repeat(auto-fit, minmax(min(100%, var(--min)), 1fr)); }
由于1fr
是 的“最大”值minmax()
,因此还允许列拉伸以公平地填充行内的任何剩余空间。因此,如果可用空间为80ch
并且有两个网格子项,它们将各自占用40ch
. 如果有三个孩子,第三个将在第二行,因为80
没有平均分配到允许的最小大小30
。
以下提供了响应式网格布局的实时示例:
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <meta http-equiv="X-UA-Compatible" content="IE=edge"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <title>带有网格的响应式布局 | Web前端之家www.jiangweishan.com</title> <style> html { height: 100%; } body { font-family: system-ui; min-height: 100%; background-color: var(--bg, mediumvioletred); padding: var(--padding, 0); max-width: var(--max-width, 120ch); margin-inline: auto; --padding: 5vw; --max-width: 180ch; } ul,li { display: list-item; text-align: -webkit-match-parent; } * { box-sizing: border-box; margin: 0; } .grid { --min: 30ch; display: grid; grid-template-columns: repeat(auto-fit, minmax(min(100%, var(--min)), 1fr)); gap: 1rem; } :where([role="list"]) { margin: 0; padding: 0; list-style: none; } .card { padding: clamp(0.75rem, 5%, 3rem); background-color: #fff; border-radius: 1rem; } </style> </head> <body> <ul role="list" class="grid"> <li class="card"> <h3>Lorem, ipsum.</h3> <p>Lorem ipsum dolor sit amet, consectetur adipisicing elit.</p> </li> <li class="card"> <h3>Minus, pariatur?</h3> <p>Veritatis optio illum possimus eveniet exercitationem perferendis ad?</p> </li> <li class="card"> <h3>Iste, assumenda!</h3> <p>Esse minima in maiores similique unde eaque nostrum!</p> </li> <li class="card"> <h3>Voluptatem, veritatis!</h3> <p>Provident deserunt veniam, debitis alias atque deleniti laboriosam!</p> </li> <li class="card"> <h3>Accusamus, magnam.</h3> <p>Ipsum accusantium laboriosam, architecto cum dolor odit animi?</p> </li> <li class="card"> <h3>Recusandae, placeat.</h3> <p>Incidunt, aliquid odit! Eaque nihil mollitia repellat beatae.</p> </li> </ul> </body> </html>
使用 Flexbox 的响应式布局
我们可以用 Flexbox 完成类似的体验。Flexbox 和 Grid 解决方案之间的区别在于,流向新行的网格项不能扩展到多个网格列。使用 Flexbox,我们可以引导 flex 项目增长以填充所有剩余的额外空间,从而防止在 Grid 解决方案中出现“孤儿”。
在此代码中,与在 Grid 代码中一样,浏览器将创建尽可能多的列,以适应行内空间,大小至少--min
为30ch
. 如果我们有三个项目,第三个需要移动到一个新行,由于简写,它会占用剩余的空间flex
,重要的是设置flex-grow
为1
. 因此,它在大多数情况下具有类似的行为1fr
:
.flexbox-grid { --min: 30ch; display: flex; flex-wrap: wrap; } .flexbox-grid > * { flex: 1 1 var(--min); }
由于该属性,下图显示了跨越两列的最终奇数列表项flex-grow
。
注意:在 Grid 和 Flexbox 解决方案中,如果我们添加一个gap
,那么在添加新行之前可以创建多少列的计算中会减去该空间。
敏锐的读者可能已经注意到这些解决方案之间的另一个关键区别:使用 Grid 时,父级定义子级行为。对于 Flexbox,我们在子项上设置子布局行为。简写flex
顺序依次为flex-grow
、flex-shrink
和flex-basis
。
作为实验,我们可以将flex-grow
值更改为0
,看看项目如何只扩展到该flex-basis
值。flex-shrink
(用下面的 CodePen 演示进行实验。)保持很重要1
,这样,最终——当可用内联空间比 窄时flex-basis
——仍然允许项目“收缩”,因为这有助于防止溢出。
下面的展示了我们的 Flexbox 布局。
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <meta http-equiv="X-UA-Compatible" content="IE=edge"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <title>带有网格的响应式布局 | Web前端之家www.jiangweishan.com</title> <style> * { box-sizing: border-box; margin: 0; } html { height: 100%; } body { font-family: system-ui; min-height: 100%; background-color: var(--bg, mediumvioletred); padding: var(--padding, 0); max-width: var(--max-width, 120ch); margin-inline: auto; } :where([role="list"]) { margin: 0; padding: 0; list-style: none; } .card { padding: clamp(0.75rem, 5%, 3rem); background-color: #fff; border-radius: 1rem; } .flexbox-grid { --min: 30ch; display: flex; flex-wrap: wrap; gap: 1rem; } .flexbox-grid > * { flex: 1 1 var(--min); } body { --padding: 5vw; --max-width: 180ch; } </style> </head> <body> <ul role="list" class="flexbox-grid"> <li class="card"> <h3>Lorem, ipsum.</h3> <p>Lorem ipsum dolor sit amet, consectetur adipisicing elit.</p> </li> <li class="card"> <h3>Minus, pariatur?</h3> <p>Veritatis optio illum possimus eveniet exercitationem perferendis ad?</p> </li> <li class="card"> <h3>Iste, assumenda!</h3> <p>Esse minima in maiores similique unde eaque nostrum!</p> </li> </ul> </body> </html>
flex-basis
可以针对此解决方案进一步调整该属性,以便为不同的项目分配唯一的“断点”。由于我们通过--min
自定义属性设置该值,并且 Flexbox 子元素控制自己的大小,因此我们可以使用内联样式对其进行调整:
<li style="--min: 40ch">...</li>
此示例中的其他列表子项仍将围绕它流动并使用30ch
来自基本规则,但更宽的列有效地改变了行为。
这是此代码的演示:
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <meta http-equiv="X-UA-Compatible" content="IE=edge"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <title>带有网格的响应式布局 | Web前端之家www.jiangweishan.com</title> <style> * { box-sizing: border-box; margin: 0; } html { height: 100%; } body { font-family: system-ui; min-height: 100%; background-color: var(--bg, mediumvioletred); padding: var(--padding, 0); max-width: var(--max-width, 120ch); margin-inline: auto; } :where([role="list"]) { margin: 0; padding: 0; list-style: none; } .card { padding: clamp(0.75rem, 5%, 3rem); background-color: #fff; border-radius: 1rem; } .flexbox-grid { --min: 25ch; display: flex; flex-wrap: wrap; gap: 1rem; } .flexbox-grid > * { flex: 1 1 var(--min); } body { --padding: 3vw; --max-width: 180ch; } </style> </head> <body> <ul role="list" class="flexbox-grid"> <li class="card"> <h3>Lorem, ipsum.</h3> <p>Lorem ipsum dolor sit amet, consectetur adipisicing elit.</p> </li> <li class="card" style="--min: 40ch"> <h3>Custom "Breakpoint" --min</h3> <p>Veritatis optio illum possimus eveniet exercitationem perferendis ad?</p> </li> <li class="card"> <h3>Iste, assumenda!</h3> <p>Esse minima in maiores similique unde eaque nostrum!</p> </li> <li class="card"> <h3>Molestiae, quo.</h3> <p>Quos ullam, iure inventore delectus sequi aliquam omnis!</p> </li> <li class="card"> <h3>Illo, facere!</h3> <p>Vel pariatur quod alias, quaerat porro sint quas.</p> </li> </ul> </body> </html>
以下是另外两种以有趣的方式使用flex-grow
和 的Flexbox 技术flex-basis
:
Heydon Pickering 的Flexbox Holy Albatross,它根据父容器的总宽度从列分解为一行。
Heydon Pickering 和 Andy Bell 的侧边栏布局,它展示了如何强制使用不同的基于 Flexbox 的断点以更好地控制项目何时换行。
网友评论文明上网理性发言 已有0人参与
发表评论: