【问题标题】:CSS Grid Layout with Max-Width, Centered Content具有最大宽度、居中内容的 CSS 网格布局
【发布时间】: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 是否可以实现这一点,如果可以,如何实现?

【问题讨论】:

标签: html css flexbox css-grid grid-layout


【解决方案1】:

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

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

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

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

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

    李>
  3. 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>

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2018-08-05
    • 2018-01-09
    • 1970-01-01
    • 1970-01-01
    • 2012-12-06
    • 2019-06-22
    • 2011-06-10
    相关资源
    最近更新 更多