- 发布于
现代CSS布局技巧集锦:Grid、Flexbox与Container Queries
- 作者

- 姓名
- 全能波
- GitHub
- @weicracker
现代CSS布局技巧集锦:Grid、Flexbox与Container Queries
现代CSS为我们提供了强大的布局工具,本文将分享CSS Grid、Flexbox和Container Queries等现代布局技术的实战技巧和最佳实践。
CSS Grid高级应用
复杂网格布局
/* 响应式网格布局系统 */
.grid-container {
display: grid;
grid-template-columns: repeat(auto-fit, minmax(300px, 1fr));
grid-template-rows: masonry; /* 实验性功能 */
gap: 2rem;
padding: 2rem;
}
/* 不规则网格布局 */
.magazine-layout {
display: grid;
grid-template-columns: repeat(6, 1fr);
grid-template-rows: repeat(4, 200px);
gap: 1rem;
}
.magazine-layout .featured {
grid-column: 1 / 4;
grid-row: 1 / 3;
}
.magazine-layout .sidebar {
grid-column: 4 / 7;
grid-row: 1 / 2;
}
.magazine-layout .article-1 {
grid-column: 4 / 6;
grid-row: 2 / 4;
}
.magazine-layout .article-2 {
grid-column: 6 / 7;
grid-row: 2 / 3;
}
.magazine-layout .ads {
grid-column: 6 / 7;
grid-row: 3 / 4;
}
.magazine-layout .footer {
grid-column: 1 / 7;
grid-row: 4 / 5;
}
/* 动态网格布局 */
.dynamic-grid {
display: grid;
grid-template-columns: repeat(auto-fill, minmax(250px, 1fr));
grid-auto-rows: minmax(200px, auto);
gap: 1rem;
}
.dynamic-grid .item {
background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
border-radius: 8px;
padding: 1rem;
color: white;
}
/* 特殊尺寸项目 */
.dynamic-grid .item.large {
grid-column: span 2;
grid-row: span 2;
}
.dynamic-grid .item.wide {
grid-column: span 2;
}
.dynamic-grid .item.tall {
grid-row: span 2;
}
/* 网格区域命名 */
.app-layout {
display: grid;
grid-template-areas:
"header header header"
"nav main aside"
"nav footer aside";
grid-template-columns: 200px 1fr 200px;
grid-template-rows: 60px 1fr 60px;
min-height: 100vh;
gap: 1rem;
}
.app-layout .header { grid-area: header; }
.app-layout .nav { grid-area: nav; }
.app-layout .main { grid-area: main; }
.app-layout .aside { grid-area: aside; }
.app-layout .footer { grid-area: footer; }
/* 响应式网格区域 */
@media (max-width: 768px) {
.app-layout {
grid-template-areas:
"header"
"nav"
"main"
"aside"
"footer";
grid-template-columns: 1fr;
grid-template-rows: 60px auto 1fr auto 60px;
}
}
Grid子网格(Subgrid)
/* 子网格布局 */
.parent-grid {
display: grid;
grid-template-columns: repeat(4, 1fr);
grid-template-rows: repeat(3, 200px);
gap: 1rem;
}
.child-grid {
grid-column: 2 / 4;
grid-row: 1 / 3;
/* 使用子网格 */
display: grid;
grid-template-columns: subgrid;
grid-template-rows: subgrid;
gap: inherit;
}
/* 卡片网格对齐 */
.card-grid {
display: grid;
grid-template-columns: repeat(auto-fit, minmax(300px, 1fr));
gap: 2rem;
}
.card {
display: grid;
grid-template-rows: auto 1fr auto;
border: 1px solid #ddd;
border-radius: 8px;
overflow: hidden;
}
.card-header {
padding: 1rem;
background: #f5f5f5;
}
.card-content {
padding: 1rem;
/* 自动填充剩余空间 */
}
.card-footer {
padding: 1rem;
background: #f5f5f5;
border-top: 1px solid #ddd;
}
/* 网格线命名 */
.named-lines {
display: grid;
grid-template-columns:
[sidebar-start] 200px
[sidebar-end main-start] 1fr
[main-end aside-start] 200px
[aside-end];
grid-template-rows:
[header-start] 60px
[header-end content-start] 1fr
[content-end footer-start] 60px
[footer-end];
}
.named-lines .header {
grid-column: sidebar-start / aside-end;
grid-row: header-start / header-end;
}
.named-lines .sidebar {
grid-column: sidebar-start / sidebar-end;
grid-row: content-start / content-end;
}
.named-lines .main {
grid-column: main-start / main-end;
grid-row: content-start / content-end;
}
Flexbox高级技巧
复杂Flex布局
/* 自适应导航栏 */
.navbar {
display: flex;
align-items: center;
padding: 0 2rem;
background: white;
box-shadow: 0 2px 10px rgba(0,0,0,0.1);
}
.navbar .logo {
flex-shrink: 0;
margin-right: 2rem;
}
.navbar .nav-links {
display: flex;
list-style: none;
margin: 0;
padding: 0;
gap: 2rem;
}
.navbar .nav-actions {
margin-left: auto;
display: flex;
gap: 1rem;
align-items: center;
}
/* 响应式导航 */
@media (max-width: 768px) {
.navbar {
flex-wrap: wrap;
}
.navbar .nav-links {
order: 3;
flex-basis: 100%;
flex-direction: column;
background: white;
padding: 1rem 0;
border-top: 1px solid #eee;
}
}
/* 等高卡片布局 */
.card-container {
display: flex;
flex-wrap: wrap;
gap: 2rem;
align-items: stretch; /* 等高 */
}
.card-item {
flex: 1 1 300px; /* 最小宽度300px */
display: flex;
flex-direction: column;
border: 1px solid #ddd;
border-radius: 8px;
overflow: hidden;
}
.card-item .content {
flex: 1; /* 占据剩余空间 */
padding: 1rem;
}
.card-item .actions {
padding: 1rem;
background: #f5f5f5;
border-top: 1px solid #ddd;
}
/* 圣杯布局 */
.holy-grail {
display: flex;
flex-direction: column;
min-height: 100vh;
}
.holy-grail .header,
.holy-grail .footer {
flex-shrink: 0;
background: #333;
color: white;
padding: 1rem;
}
.holy-grail .content {
flex: 1;
display: flex;
}
.holy-grail .sidebar {
flex: 0 0 200px;
background: #f5f5f5;
padding: 1rem;
}
.holy-grail .main {
flex: 1;
padding: 1rem;
}
.holy-grail .aside {
flex: 0 0 200px;
background: #f5f5f5;
padding: 1rem;
}
/* 移动端调整 */
@media (max-width: 768px) {
.holy-grail .content {
flex-direction: column;
}
.holy-grail .sidebar,
.holy-grail .aside {
flex: none;
}
}
/* 垂直居中技巧 */
.center-container {
display: flex;
align-items: center;
justify-content: center;
min-height: 100vh;
}
.center-content {
text-align: center;
max-width: 500px;
padding: 2rem;
}
/* 弹性间距 */
.flexible-spacing {
display: flex;
justify-content: space-between;
align-items: center;
padding: 1rem;
}
.flexible-spacing .item:not(:last-child) {
margin-right: auto;
}
/* 自动换行网格 */
.flex-grid {
display: flex;
flex-wrap: wrap;
gap: 1rem;
margin: -0.5rem; /* 抵消gap */
}
.flex-grid .item {
flex: 1 1 calc(33.333% - 1rem);
min-width: 250px;
margin: 0.5rem;
}
@media (max-width: 768px) {
.flex-grid .item {
flex: 1 1 calc(50% - 1rem);
}
}
@media (max-width: 480px) {
.flex-grid .item {
flex: 1 1 100%;
}
}
Flex高级属性应用
/* flex-grow, flex-shrink, flex-basis 详解 */
.flex-demo {
display: flex;
width: 600px;
height: 200px;
border: 2px solid #333;
}
.flex-demo .item-1 {
flex: 1 1 200px; /* grow: 1, shrink: 1, basis: 200px */
background: #ff6b6b;
}
.flex-demo .item-2 {
flex: 2 1 100px; /* grow: 2, shrink: 1, basis: 100px */
background: #4ecdc4;
}
.flex-demo .item-3 {
flex: 1 2 150px; /* grow: 1, shrink: 2, basis: 150px */
background: #45b7d1;
}
/* 自适应表单布局 */
.form-row {
display: flex;
gap: 1rem;
margin-bottom: 1rem;
align-items: flex-start;
}
.form-row .form-group {
display: flex;
flex-direction: column;
flex: 1;
}
.form-row .form-group.narrow {
flex: 0 0 120px; /* 固定宽度 */
}
.form-row .form-group.wide {
flex: 2; /* 占据更多空间 */
}
.form-row label {
margin-bottom: 0.5rem;
font-weight: bold;
}
.form-row input,
.form-row select,
.form-row textarea {
padding: 0.5rem;
border: 1px solid #ddd;
border-radius: 4px;
}
/* 响应式表单 */
@media (max-width: 768px) {
.form-row {
flex-direction: column;
}
.form-row .form-group.narrow,
.form-row .form-group.wide {
flex: none;
}
}
/* 媒体对象布局 */
.media-object {
display: flex;
gap: 1rem;
padding: 1rem;
border-bottom: 1px solid #eee;
}
.media-object .media-figure {
flex-shrink: 0;
}
.media-object .media-figure img {
width: 60px;
height: 60px;
border-radius: 50%;
object-fit: cover;
}
.media-object .media-body {
flex: 1;
min-width: 0; /* 防止内容溢出 */
}
.media-object .media-body h4 {
margin: 0 0 0.5rem 0;
font-size: 1rem;
}
.media-object .media-body p {
margin: 0;
color: #666;
overflow: hidden;
text-overflow: ellipsis;
white-space: nowrap;
}
Container Queries
容器查询基础
/* 容器查询设置 */
.card-container {
container-type: inline-size;
container-name: card;
}
.card {
padding: 1rem;
border: 1px solid #ddd;
border-radius: 8px;
}
/* 基于容器宽度的样式 */
@container card (min-width: 300px) {
.card {
display: flex;
gap: 1rem;
}
.card .image {
flex: 0 0 120px;
}
.card .content {
flex: 1;
}
}
@container card (min-width: 500px) {
.card {
padding: 2rem;
}
.card .image {
flex: 0 0 200px;
}
.card h3 {
font-size: 1.5rem;
}
}
/* 复杂容器查询 */
.sidebar {
container-type: inline-size;
container-name: sidebar;
}
.widget {
margin-bottom: 1rem;
padding: 1rem;
background: white;
border-radius: 8px;
box-shadow: 0 2px 4px rgba(0,0,0,0.1);
}
@container sidebar (max-width: 250px) {
.widget {
padding: 0.5rem;
}
.widget h4 {
font-size: 0.9rem;
}
.widget .description {
display: none;
}
}
@container sidebar (min-width: 300px) {
.widget {
display: flex;
align-items: center;
gap: 1rem;
}
.widget .icon {
flex-shrink: 0;
width: 40px;
height: 40px;
}
.widget .content {
flex: 1;
}
}
/* 网格容器查询 */
.grid-container {
container-type: inline-size;
container-name: grid;
}
.grid {
display: grid;
gap: 1rem;
}
@container grid (min-width: 400px) {
.grid {
grid-template-columns: repeat(2, 1fr);
}
}
@container grid (min-width: 600px) {
.grid {
grid-template-columns: repeat(3, 1fr);
}
}
@container grid (min-width: 800px) {
.grid {
grid-template-columns: repeat(4, 1fr);
}
}
容器查询实战应用
/* 响应式卡片组件 */
.product-card {
container-type: inline-size;
container-name: product-card;
border: 1px solid #ddd;
border-radius: 8px;
overflow: hidden;
background: white;
}
.product-card .image {
width: 100%;
height: 200px;
object-fit: cover;
}
.product-card .content {
padding: 1rem;
}
.product-card .title {
font-size: 1.1rem;
font-weight: bold;
margin-bottom: 0.5rem;
}
.product-card .price {
font-size: 1.2rem;
color: #e74c3c;
font-weight: bold;
}
.product-card .description {
color: #666;
margin: 0.5rem 0;
line-height: 1.4;
}
.product-card .actions {
margin-top: 1rem;
}
/* 小尺寸容器样式 */
@container product-card (max-width: 200px) {
.product-card .image {
height: 120px;
}
.product-card .content {
padding: 0.5rem;
}
.product-card .title {
font-size: 0.9rem;
}
.product-card .description {
display: none;
}
.product-card .actions button {
width: 100%;
font-size: 0.8rem;
}
}
/* 中等尺寸容器样式 */
@container product-card (min-width: 300px) and (max-width: 400px) {
.product-card {
display: flex;
}
.product-card .image {
width: 120px;
height: 120px;
flex-shrink: 0;
}
.product-card .content {
flex: 1;
display: flex;
flex-direction: column;
}
.product-card .actions {
margin-top: auto;
}
}
/* 大尺寸容器样式 */
@container product-card (min-width: 400px) {
.product-card .image {
height: 250px;
}
.product-card .content {
padding: 1.5rem;
}
.product-card .title {
font-size: 1.3rem;
}
.product-card .description {
font-size: 1rem;
line-height: 1.6;
}
.product-card .actions {
display: flex;
gap: 1rem;
}
.product-card .actions button {
flex: 1;
}
}
/* 导航组件容器查询 */
.navigation {
container-type: inline-size;
container-name: navigation;
background: #333;
color: white;
}
.nav-list {
display: flex;
list-style: none;
margin: 0;
padding: 0;
}
.nav-item {
position: relative;
}
.nav-link {
display: block;
padding: 1rem;
color: white;
text-decoration: none;
transition: background-color 0.3s;
}
.nav-link:hover {
background-color: rgba(255,255,255,0.1);
}
/* 窄容器:垂直导航 */
@container navigation (max-width: 600px) {
.nav-list {
flex-direction: column;
}
.nav-item {
border-bottom: 1px solid rgba(255,255,255,0.1);
}
.nav-item:last-child {
border-bottom: none;
}
}
/* 宽容器:水平导航 */
@container navigation (min-width: 600px) {
.nav-list {
justify-content: center;
}
.nav-item:not(:last-child) {
border-right: 1px solid rgba(255,255,255,0.1);
}
}
现代CSS布局组合技巧
Grid + Flexbox 组合
/* Grid作为页面布局,Flexbox作为组件布局 */
.page-layout {
display: grid;
grid-template-areas:
"header header"
"sidebar main"
"footer footer";
grid-template-columns: 250px 1fr;
grid-template-rows: auto 1fr auto;
min-height: 100vh;
gap: 1rem;
}
.page-header {
grid-area: header;
display: flex;
justify-content: space-between;
align-items: center;
padding: 1rem 2rem;
background: white;
box-shadow: 0 2px 4px rgba(0,0,0,0.1);
}
.page-sidebar {
grid-area: sidebar;
display: flex;
flex-direction: column;
gap: 1rem;
padding: 1rem;
background: #f5f5f5;
}
.page-main {
grid-area: main;
display: flex;
flex-direction: column;
gap: 2rem;
padding: 2rem;
}
.page-footer {
grid-area: footer;
display: flex;
justify-content: center;
align-items: center;
padding: 1rem;
background: #333;
color: white;
}
/* 内容区域使用Flexbox */
.content-section {
display: flex;
flex-direction: column;
gap: 1rem;
}
.content-header {
display: flex;
justify-content: space-between;
align-items: center;
padding-bottom: 1rem;
border-bottom: 2px solid #eee;
}
.content-grid {
display: grid;
grid-template-columns: repeat(auto-fit, minmax(300px, 1fr));
gap: 2rem;
}
.content-card {
display: flex;
flex-direction: column;
border: 1px solid #ddd;
border-radius: 8px;
overflow: hidden;
}
.content-card .header {
display: flex;
justify-content: space-between;
align-items: center;
padding: 1rem;
background: #f8f9fa;
border-bottom: 1px solid #ddd;
}
.content-card .body {
flex: 1;
padding: 1rem;
}
.content-card .footer {
display: flex;
justify-content: flex-end;
gap: 1rem;
padding: 1rem;
background: #f8f9fa;
border-top: 1px solid #ddd;
}
响应式布局最佳实践
/* 移动优先的响应式设计 */
.responsive-layout {
--sidebar-width: 250px;
--header-height: 60px;
--gap: 1rem;
display: grid;
grid-template-areas:
"header"
"main"
"sidebar"
"footer";
grid-template-rows: var(--header-height) 1fr auto auto;
min-height: 100vh;
gap: var(--gap);
}
/* 平板尺寸 */
@media (min-width: 768px) {
.responsive-layout {
grid-template-areas:
"header header"
"sidebar main"
"footer footer";
grid-template-columns: var(--sidebar-width) 1fr;
grid-template-rows: var(--header-height) 1fr auto;
}
}
/* 桌面尺寸 */
@media (min-width: 1024px) {
.responsive-layout {
--sidebar-width: 300px;
--gap: 2rem;
grid-template-areas:
"header header header"
"sidebar main aside"
"footer footer footer";
grid-template-columns: var(--sidebar-width) 1fr 250px;
}
}
/* 大屏幕优化 */
@media (min-width: 1400px) {
.responsive-layout {
max-width: 1400px;
margin: 0 auto;
}
}
/* 容器查询增强响应式 */
.adaptive-component {
container-type: inline-size;
container-name: adaptive;
}
@container adaptive (min-width: 400px) {
.adaptive-component .content {
display: grid;
grid-template-columns: 1fr 1fr;
gap: 1rem;
}
}
@container adaptive (min-width: 600px) {
.adaptive-component .content {
grid-template-columns: 1fr 2fr 1fr;
}
}
/* 打印样式优化 */
@media print {
.responsive-layout {
grid-template-areas:
"header"
"main"
"footer";
grid-template-columns: 1fr;
}
.page-sidebar,
.page-aside {
display: none;
}
.page-header,
.page-footer {
background: none !important;
box-shadow: none !important;
}
}
总结
现代CSS布局的核心要点:
- CSS Grid:适合二维布局,页面级别的整体结构
- Flexbox:适合一维布局,组件级别的内容排列
- Container Queries:基于容器尺寸的响应式设计
- 组合使用:Grid + Flexbox 实现复杂布局需求
- 响应式策略:移动优先,渐进增强
现代CSS布局技术为我们提供了前所未有的灵活性和控制力,合理运用这些技术可以创建出既美观又实用的用户界面。