我在嵌套布局中混合了 CSS Grid 和 Flexbox。外部布局是 2x2 CSS 网格。每个网格容器将包含另一个网格布局或一些 Flexbox 组件。
外部网格的左下角容器是一个可折叠侧边栏,包含 2x2 网格,右下角容器有一个 3x2 网格。
当我将整个左下容器向左折叠时,我希望右下容器向左拉伸并占据空出的空间。在此过程中,它应该自动调整其包含的元素的大小。不幸的是我无法实现它。
* {
box-sizing: border-box;
/* this is also essential to avoid a world of width-based pain */
}
.body {
height: 100vh;
width: 100vw;
margin: 0;
/* negates the default 8px margins */
display: grid;
grid-template-columns: 20% 1fr;
grid-template-rows: 10% 1fr;
grid-template-areas: "logo head" "side main";
}
.logo {
background-color: #fff;
grid-area: logo;
display: flex;
flex-flow: row nowrap;
justify-content: flex-start;
align-content: center;
}
.img {
height: 100%;
object-fit: cover;
}
.header {
background-color: #fff;
padding: 0.3rem;
grid-area: head;
display: flex;
flex-flow: row nowrap;
justify-content: center;
align-content: center;
display: grid;
/* nested grid inside the header */
grid-template-columns: 2fr 1fr;
/* define 3 equal columns each taking same fraction of the space */
grid-template-rows: 1fr;
/* there's only one row; so take all the available space */
grid-template-areas: "msg regoraccess";
gap: 0.5em;
}
.head-card {
border-radius: .25rem;
display: flex;
flex-flow: row wrap;
justify-content: center;
align-content: center;
}
/* place each of the six cards in their respective areas */
.head-card:nth-child(1) {
grid-area: msg;
}
.notification {
text-align: center;
margin: 0;
}
.head-card:nth-child(2) {
grid-area: regoraccess;
display: flex;
flex-flow: row wrap;
justify-content: flex-end;
align-content: center;
}
.side-bar {
background-color: #1c1f23;
padding: 0.1rem 0 0.1rem 0.1rem;
grid-area: side;
display: flex;
flex-flow: row nowrap;
align-content: flex-start;
display: grid;
grid-template-columns: 0.05fr 0.95fr;
grid-template-rows: 0.9fr 0.1fr;
grid-template-areas: "collapse menu" "rc rc";
}
.side-card {
display: flex;
}
/*
nth-child(1): Collapse button
nth-child(2): Menu
nth-child(3): Copyright
*/
.side-card:nth-child(1) {
grid-area: collapse;
display: flex;
flex-flow: row wrap;
justify-content: flex-end;
align-content: center;
}
.fa-solid {
color: #3DED97;
/* Seafoam Color */
}
.accord-button>input {
display: none;
}
.accord-button>input:checked+label .not-active {
display: none;
}
.accord-button>input:not(:checked)+label .active {
display: none;
}
/* the menu */
.side-card:nth-child(2) {
grid-area: menu;
display: flex;
flex-flow: column wrap;
justify-content: flex-start;
align-content: flex-start;
transition: width 300ms;
}
.nav {
display: flex;
flex-flow: column wrap;
padding: 1rem;
gap: 1rem;
}
.nav li {
display: flex;
}
.menu-button {
background: transparent;
border: 0;
color: white;
}
body:has(.accord-button > input:checked) {
#aside {
width: 1em;
}
.side-card:nth-child(2) {
display: none;
}
.side-card:nth-child(3) {
width: 1em;
}
.long-copyright {
display: none;
}
}
body:has(.accord-button > input:not(:checked)) {
.short-copyright {
display: none
}
}
/* copyright */
.side-card:nth-child(3) {
grid-area: rc;
display: inline-flex;
flex-flow: row wrap;
justify-content: flex-start;
align-content: flex-end;
}
.long-copyright {
color: #D3D3D3;
/* light-gray */
font-size: 1rem;
}
.short-copyright {
color: #D3D3D3;
/* light-gray */
font-size: 0.5rem;
}
/* the main engagement area */
.main {
background-color: #c3c5ca;
padding: 0.5rem;
/* padding all around the main container */
grid-area: main;
display: grid;
/* nested grid inside the main */
grid-template-columns: 1fr 1fr 1fr;
/* define 3 equal columns each taking same fraction of the space */
grid-template-rows: 1fr 1fr 1fr;
/* define 3 equal rows each taking same fraction of available space */
grid-template-areas: "col-1 col-2 col-3" "col-4 col-4 col-5" "col-4 col-4 col-6";
gap: 1em;
/* gap between the rows and the columns */
flex-grow: 1;
/* <== will not work here because of the Display: Grid on Parent */
}
.card {
background-color: #f6f7f9;
border-radius: 1rem;
}
/* place each of the six cards in their respective areas */
.card:nth-child(1) {
grid-area: col-1;
}
.card:nth-child(2) {
grid-area: col-2;
}
.card:nth-child(3) {
grid-area: col-3;
}
.card:nth-child(4) {
grid-area: col-4;
}
.card:nth-child(5) {
grid-area: col-5;
}
.card:nth-child(6) {
grid-area: col-6;
}
/* media queries */
@media (max-width: 900px) {
.main {
grid-template-columns: 1fr;
grid-template-rows: repeat(6, 1fr);
grid-template-areas: initial;
}
.card {
grid-area: initial !important;
}
}
<html>
<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" />
<link href="https://cdn.jsdelivr.net/npm/[email protected]/dist/css/bootstrap.min.css" rel="stylesheet" />
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.4.2/css/all.min.css" crossorigin="anonymous">
<link rel="stylesheet" type="text/css" href="styles.css" />
</head>
<body class="body">
<section class="logo">
<img class="img" src="../static/images/logo.png">
</section>
<header class="header">
<div class="head-card"><span class="notification">[ some msg ]</span></div>
<div class="head-card">
</div>
</header>
<!-- Collapsible Side Nav bar for menus -->
<section id="aside" class="side-bar">
<div class="side-card">
<div class='accord-button'>
<input type='checkbox' id='accordianinput'>
<label for='accordianinput'>
<i class="fa-solid fa-arrow-circle-left not-active"></i>
<i class="fa-solid fa-arrow-circle-right active"></i>
</label>
</div>
</div>
<div class="side-card">
<ul class="nav">
<li><button type="button" class="menu-button" onclick="#">Home</button></li>
<li><button type="button" class="menu-button" onclick="#">About</button></li>
</ul>
</div>
<div class="side-card">
<span class="long-copyright">© Runaway Company, Inc.</span>
<span class="short-copyright">©RC</span>
</div>
</section>
<main class="main">
<div class="card">
</div>
<div class="card">
</div>
<div class="card">
</div>
<div class="card">
</div>
<div class="card">
</div>
<div class="card">
</div>
</main>
</body>
</html>
我知道“flex-grow:1”不适用于“主”容器,但不知道如何处理。谁能告诉我正确的方法吗?
如果你想让侧边栏折叠起来,我不会在主体上使用 2x2 网格。将主体设置为单列两行 (1x2)。第一行将包含您的标题,第二行将包含侧边栏和主面板。
使用 Flexbox 设置每一行的格式。对于标题行,请使用
justify-content: space-between
。第二排几乎会照顾自己。
* {
box-sizing: border-box;
}
body, html {
height: 100vh;
}
body {
margin: 0;
display: grid;
grid-template-rows: auto 1fr;
}
header {
background-color: #fff;
padding: 0.3rem;
display: flex;
justify-content: space-between;
align-items: center;
gap: 0.5em;
}
main {
display: flex;
}
.side-bar {
background-color: #1c1f23;
padding: 0.1rem 0 0.1rem 0.1rem;
grid-area: side;
display: flex;
flex-flow: row nowrap;
align-content: flex-start;
display: grid;
grid-template-columns: 0.05fr 0.95fr;
grid-template-rows: 0.9fr 0.1fr;
grid-template-areas: "collapse menu" "rc rc";
}
.side-card {
display: flex;
}
/*
nth-child(1): Collapse button
nth-child(2): Menu
nth-child(3): Copyright
*/
.side-card:nth-child(1) {
grid-area: collapse;
display: flex;
flex-flow: row wrap;
justify-content: flex-end;
align-content: center;
}
.fa-solid {
color: #3DED97;
/* Seafoam Color */
}
.accord-button>input {
display: none;
}
.accord-button>input:checked+label .not-active {
display: none;
}
.accord-button>input:not(:checked)+label .active {
display: none;
}
/* the menu */
.side-card:nth-child(2) {
grid-area: menu;
display: flex;
flex-flow: column wrap;
justify-content: flex-start;
align-content: flex-start;
transition: width 300ms;
}
.nav {
display: flex;
flex-flow: column wrap;
padding: 1rem;
gap: 1rem;
}
.nav li {
display: flex;
}
.menu-button {
background: transparent;
border: 0;
color: white;
}
body:has(.accord-button > input:checked) {
#aside {
width: 1em;
}
.side-card:nth-child(2) {
display: none;
}
.side-card:nth-child(3) {
width: 1em;
}
.long-copyright {
display: none;
}
}
body:has(.accord-button > input:not(:checked)) {
.short-copyright {
display: none
}
}
/* copyright */
.side-card:nth-child(3) {
grid-area: rc;
display: inline-flex;
flex-flow: row wrap;
justify-content: flex-start;
align-content: flex-end;
}
.long-copyright {
color: #D3D3D3;
/* light-gray */
font-size: 1rem;
}
.short-copyright {
color: #D3D3D3;
/* light-gray */
font-size: 0.5rem;
}
/* the main engagement area */
.mainpanel {
background-color: #c3c5ca;
padding: 0.5rem;
/* padding all around the main container */
grid-area: main;
display: grid;
/* nested grid inside the main */
grid-template-columns: 1fr 1fr 1fr;
/* define 3 equal columns each taking same fraction of the space */
grid-template-rows: 1fr 1fr 1fr;
/* define 3 equal rows each taking same fraction of available space */
grid-template-areas: "col-1 col-2 col-3" "col-4 col-4 col-5" "col-4 col-4 col-6";
gap: 1em;
/* gap between the rows and the columns */
flex-grow: 1;
/* <== will not work here because of the Display: Grid on Parent */
}
.card {
background-color: #f6f7f9;
border-radius: 1rem;
}
/* place each of the six cards in their respective areas */
.card:nth-child(1) {
grid-area: col-1;
}
.card:nth-child(2) {
grid-area: col-2;
}
.card:nth-child(3) {
grid-area: col-3;
}
.card:nth-child(4) {
grid-area: col-4;
}
.card:nth-child(5) {
grid-area: col-5;
}
.card:nth-child(6) {
grid-area: col-6;
}
/* media queries */
@media (max-width: 900px) {
.mainpanel {
grid-template-columns: 1fr;
grid-template-rows: repeat(6, 1fr);
grid-template-areas: initial;
}
.card {
grid-area: initial !important;
}
}
<link href="https://cdn.jsdelivr.net/npm/[email protected]/dist/css/bootstrap.min.css" rel="stylesheet" />
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.4.2/css/all.min.css" crossorigin="anonymous">
<header>
<img class="logo" src="https://picsum.photos/80/40">
<div>header centre</div>
<div>header right</div>
</header>
<main>
<nav id="aside" class="side-bar">
<div class="side-card">
<div class='accord-button'>
<input type='checkbox' id='accordianinput'>
<label for='accordianinput'>
<i class="fa-solid fa-arrow-circle-left not-active"></i>
<i class="fa-solid fa-arrow-circle-right active"></i>
</label>
</div>
</div>
<div class="side-card">
<ul class="nav">
<li><button type="button" class="menu-button" onclick="#">Home</button></li>
<li><button type="button" class="menu-button" onclick="#">About</button></li>
</ul>
</div>
<div class="side-card">
<span class="long-copyright">© Runaway Company, Inc.</span>
<span class="short-copyright">©RC</span>
</div>
</nav>
<div class="mainpanel">
<div class="card">
</div>
<div class="card">
</div>
<div class="card">
</div>
<div class="card">
</div>
<div class="card">
</div>
<div class="card">
</div>
</div>
</main>