我正在学习CSS Grid(早就应该了,我知道)。我挑战自己将一个相对标准的基于浮动的布局转换为网格,但无法弄清楚这最后一部分。
我的目标是使用max-width
进行内容(徽标+导航和侧边栏+内容)居中的布局。例如,logo + nav应该有一个600px的max-width
。我还要求具有覆盖视口全宽的实心填充背景(匹配可变高度徽标/导航行的高度)。
第一列(徽标和侧边栏)应缩小以适合其内容 - 因此第一列仅与徽标/侧边栏之间的宽度一样宽。导航/内容应填充max-width
允许的剩余空间。
以下是我最好的尝试。主要内容的宽度不填充max-width
。相反,主要内容的宽度是Logo + 250px的宽度(由网格列定义的宽度)。
我希望实现的是 - 将Logo + Nav的max-width
定义为特定宽度(比如600px),并将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是否可以实现,如果是这样,怎么做?
您可以使用带有grid-template-columns: auto 1fr
的2列网格,以便第一列获取其内容的宽度(与徽标/侧边栏之间的宽度一样宽),第二列占用剩余空间(请注意,我已将max-width: 600px
设置为网格容器)。
我还需要一个覆盖视口全宽的实心填充背景(匹配可变高度徽标/导航行的高度)
为此,您可以执行以下操作:
logo
和nav
属性来修复第一行中的grid-row
和grid-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>
水平对中网格容器相对简单。在父级上使用flex alignment属性:
body {
display: flex;
justify-content: center;
}
您可以使用max-width
或flex
属性在网格容器上创建最大宽度。
.wrapper {
flex: 600px 0 1;
}
这条规则说:
flex-basis: 600px
(起始宽度)flex-grow: 0
(该项目不能超过600px)flex-shrink: 1
(该项目可以收缩)该命令基本上等同于max-width: 600px
。
你写了:
第一列(徽标和侧边栏)应缩小以适合其内容 - 因此第一列仅与徽标/侧边栏之间的宽度一样宽。然后导航/内容应填充max-width允许的剩余空间。
试试这个:
.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>