具有最大宽度、居中内容的 CSS 网格布局

Posted

技术标签:

【中文标题】具有最大宽度、居中内容的 CSS 网格布局【英文标题】:CSS Grid Layout with Max-Width, Centered Content 【发布时间】:2019-07-19 12:09:29 【问题描述】:

我正在学习 CSS Grid(我知道,早该学习了)。我挑战自己将相对标准的基于浮动的布局转换为网格,但无法弄清楚最后一部分。

我的目标是有一个内容(徽标 + 导航和侧边栏 + 内容)居中的布局,并带有 max-width。例如,logo + nav 应该有一个 600px 的max-width。我还需要一个实心填充背景覆盖视口的全宽(与可变高度徽标/导航行的高度匹配)。

第一列(徽标和侧边栏)应缩小以适合其内容 - 因此第一列的宽度仅与徽标/侧边栏之间的宽度一样宽。然后导航/内容应填充max-width 允许的剩余空间。

以下是我最好的尝试。主要内容的宽度没有填满max-width。相反,主要内容的宽度是 Logo 的宽度 + 250px(由网格列定义的宽度)。

我希望实现的是 - 将 Logo + Nav 的 max-width 定义为特定宽度(例如 600 像素),并让 Logo 列缩小以适合其内容。

body 
  margin: 40px;


.fill 
  grid-column-start: 1;
  grid-column-end: 6;
  grid-row-start: 1;
  grid-row-end: 1;
  background-color: gray;


.logo 
  grid-area: logo;
  font-size: calc(1rem + 4vw);


.sidebar 
  grid-area: sidebar;


.content 
  grid-area: content;


.nav 
  grid-area: nav;
  text-align: right;


.footer 
  grid-area: footer;


.wrapper 
  display: grid;
  grid-gap: 10px;
  grid-template-columns: auto min-content 120px 120px auto;
  grid-template-areas: "... logo nav nav ..." "... sidebar content content ..." "... footer  footer  footer ...";
  background-color: #fff;
  color: #444;


.box 
  background-color: #444;
  color: #fff;
  border-radius: 5px;
  padding: 10px;


.header,
.footer 
  background-color: #999;
<div class="wrapper">
  <div class="fill"></div>
  <div class="box logo">Logo</div>
  <div class="box nav">Nav</div>
  <div class="box sidebar">Sidebar</div>
  <div class="box content">Content
    <br /> More content than we had before so this column is now quite tall.</div>
  <div class="box footer">Footer</div>
</div>

CSS Grid 是否可以实现这一点,如果可以,如何实现?

【问题讨论】:

您的问题自最初发布以来发生了根本性的变化。因此,我的答案现在不完整。 可能重复:***.com/q/53110368/3597276 【参考方案1】:

您可以有一个带有grid-template-columns: auto 1fr 的 2 列 grid,以便 第一列 采用其内容的宽度(与它们之间的宽度一样宽) logo/侧边栏),而第二列占据了剩余空间(注意我已将max-width: 600px设置为网格容器)。

我还需要一个实心填充背景覆盖 视口的全宽(匹配变量的高度 高度徽标/导航行)

为此,您可以执行以下操作:

    首先修复logonav在第一行通过设置grid-rowgrid-column属性

    现在为wrapper 使用一个伪元素,与第一行重叠(但堆叠下面使用z-index 属性)。

    李>

    margin-left 属性设置为calc(-50vw + 50%) 并将width 设置为100vw 以将纯色填充背景 拉伸到整个视口。

请看下面的演示:

body 
  margin: 40px;


.wrapper 
  display: grid;
  grid-gap: 10px;
  grid-template-columns: auto 1fr; /* 2-column grid */
  /* background-color: #fff;*/
  color: #444;
  max-width: 600px; /* max-width of the layout */
  margin: 0 auto; /* center in the viewport */

.logo 
  font-size: calc(1rem + 4vw);
  grid-row: 1; /* fix the logo in the first row */
  grid-column: 1; /* fix the logo in the first column */

.nav 
  text-align: right;
  grid-row: 1;  /* fix the nav in the first row */
  grid-column: 2;  /* fix the nav in the second column */


.footer 
  grid-column: span 2; /* footer spans the two columns */


.box 
  background-color: #444;
  color: #fff;
  border-radius: 5px;
  padding: 10px;


.header,
.footer 
  background-color: #999;


.wrapper:after  /* position this in the first row */
  content: '';
  display: block;
  grid-row: 1;
  grid-column: 1/ 3;
  width: 100vw;
  margin-left: calc(-50vw + 50%);
  background: gray;
  z-index: -1; /* push it behind the first row */
<div class="wrapper">
  <div class="box logo">Logo</div>
  <div class="box nav">Nav</div>
  <div class="box sidebar">Sidebar</div>
  <div class="box content">Content
    <br /> More content than we had before so this column is now quite tall.</div>
  <div class="box footer">Footer</div>
</div>

【讨论】:

我仍然希望 logo/nav 后面的实心填充扩展页面的整个宽度,并匹配 logo/nav 行的高度。这可能吗? 标志/导航行的高度是固定的吗? @BrettDeWoody 我不认为你可以匹配 nav 的高度,同时强制 nav + logo 拥有 max-width 除非可能logo+ nav 的高度是固定的... @Michael_B logo/nav 行的高度是可变的,就像在演示中一样(基于 vw)。最后,它将包含一个随屏幕宽度调整大小的图像。 @kukkuz 非常酷,我没有意识到伪元素可以与网格一起使用。【参考方案2】:

居中

将网格容器水平居中相对简单。在父节点上使用 flex 对齐属性:

body 
  display: flex;
  justify-content: center;


最大宽度

您可以使用max-widthflex 属性在网格容器上创建最大宽度。

.wrapper 
  flex: 600px 0 1;

这条规则说:

flex-basis: 600px(起始宽度) flex-grow: 0(项目不能超过600px) flex-shrink: 1(物品可以缩小)

这个命令本质上等同于max-width: 600px


2 列布局

你写的:

第一列(徽标和侧边栏)应缩小以适合其内容 - 因此第一列的宽度仅与徽标/侧边栏之间的宽度一样宽。然后导航/内容应填充最大宽度允许的剩余空间。

试试这个:

.wrapper 
  flex: 600px 0 1;
  display: grid;
  grid-template-columns: min-content 1fr;

body 
  margin: 40px;
  display: flex;
  justify-content: center;


.wrapper 
  flex: 600px 0 1;
  display: grid;
  grid-gap: 10px;
  grid-template-columns: min-content 1fr;
  grid-template-areas: "logo  nav" 
                       "sidebar content" 
                       "footer footer";
  background-color: #fff;
  color: #444;


.logo 
  grid-area: logo;
  font-size: calc(1rem + 4vw);


.sidebar 
  grid-area: sidebar;


.content 
  grid-area: content;


.nav 
  grid-area: nav;
  text-align: right;


.footer 
  grid-area: footer;


.fill 
  background-color: gray;



.box 
  background-color: #444;
  color: #fff;
  border-radius: 5px;
  padding: 10px;


.header,
.footer 
  background-color: #999;
<div class="wrapper">
  <div class="box logo">Logo</div>
  <div class="box nav">Nav</div>
  <div class="box sidebar">Sidebar</div>
  <div class="box content">Content
  <br /> These lines wrap when the text hits 600px maximum width. These lines wrap when the text hits 600px maximum width. These lines wrap when the text hits 600px maximum width. These lines wrap when the text hits 600px maximum width. These lines wrap when the text hits 600px maximum width. These lines wrap when the text hits 600px maximum width.</div>
  <div class="box footer">Footer</div>
</div>

【讨论】:

以上是关于具有最大宽度、居中内容的 CSS 网格布局的主要内容,如果未能解决你的问题,请参考以下文章

如何在 CSS 网格布局中保持内容居中?

【PyQt】网格布局 QGridLayout

网格(grid)

网格布局

动态灵活的网格布局

居中网格内容,同时左对齐每一行的内容,具有任意项/列宽度