个人主页:Guiat
归属专栏:HTML CSS JavaScript
正文
CSS布局是网页设计的核心,它决定了网页元素如何排列和显示。掌握布局技术可以帮助开发者创建从简单到复杂的各种网页结构。
盒模型是CSS布局的基础,它定义了元素在页面中占据的空间。
.box {
width: 300px;
height: 200px;
padding: 20px;
border: 1px solid #333;
margin: 15px;
box-sizing: border-box; /* 使width和height包含padding和border */
}
默认情况下,HTML元素按照文档流进行布局:
<div>这是块级元素,独占一行div>
<span>这是内联元素span><span>可以在同一行span>
浮动最初用于图文混排,后来被用于创建多列布局。
.column {
float: left;
width: 33.33%;
padding: 15px;
}
/* 清除浮动 */
.clearfix::after {
content: "";
display: table;
clear: both;
}
浮动会使元素脱离文档流,可能导致父容器高度塌陷。
/* 方法1:使用clearfix */
.clearfix::after {
content: "";
display: table;
clear: both;
}
/* 方法2:父元素设置overflow */
.container {
overflow: auto;
}
定位允许精确控制元素在页面中的位置。
.relative {
position: relative;
top: 20px;
left: 30px;
}
.container {
position: relative; /* 为绝对定位子元素创建参考点 */
}
.absolute {
position: absolute;
top: 50px;
right: 10px;
}
.header {
position: fixed;
top: 0;
left: 0;
width: 100%;
background-color: white;
z-index: 100;
}
.nav {
position: sticky;
top: 0;
background-color: #f8f8f8;
}
虽然不再推荐使用表格进行布局,但CSS提供了表格显示模式。
.table-layout {
display: table;
width: 100%;
}
.table-row {
display: table-row;
}
.table-cell {
display: table-cell;
padding: 10px;
vertical-align: middle;
}
Flexbox是一维布局模型,适用于一行或一列的元素排列。
.container {
display: flex;
/* 主轴方向 */
flex-direction: row; /* row | row-reverse | column | column-reverse */
/* 是否换行 */
flex-wrap: wrap; /* nowrap | wrap | wrap-reverse */
/* flex-direction和flex-wrap的简写 */
flex-flow: row wrap;
/* 主轴对齐方式 */
justify-content: space-between; /* flex-start | flex-end | center | space-between | space-around | space-evenly */
/* 交叉轴对齐方式 */
align-items: center; /* flex-start | flex-end | center | stretch | baseline */
/* 多行对齐方式 */
align-content: space-between; /* flex-start | flex-end | center | stretch | space-between | space-around */
}
.item {
/* 排序 */
order: 2;
/* 放大比例 */
flex-grow: 1;
/* 缩小比例 */
flex-shrink: 1;
/* 基础尺寸 */
flex-basis: auto; /* auto | */
/* flex-grow、flex-shrink和flex-basis的简写 */
flex: 1 1 auto; /* 常用值: 1 (1 1 0%), auto (1 1 auto), none (0 0 auto) */
/* 单个项目的对齐方式,覆盖align-items */
align-self: flex-end; /* auto | flex-start | flex-end | center | baseline | stretch */
}
/* 导航栏 */
.navbar {
display: flex;
justify-content: space-between;
align-items: center;
padding: 10px 20px;
}
.nav-links {
display: flex;
gap: 20px;
}
/* 卡片布局 */
.card-container {
display: flex;
flex-wrap: wrap;
gap: 20px;
}
.card {
flex: 1 1 300px; /* 增长、收缩、基础宽度 */
display: flex;
flex-direction: column;
}
.card-body {
flex: 1; /* 占用所有可用空间 */
}
Grid是二维布局模型,适用于行列结构的复杂布局。
.container {
display: grid;
/* 定义列 */
grid-template-columns: 1fr 2fr 1fr; /* 三列网格,中间列宽度是两边的两倍 */
/* 定义行 */
grid-template-rows: 100px auto 100px; /* 三行网格,中间行高度自适应 */
/* 行列间距 */
gap: 20px; /* row-gap column-gap的简写 */
row-gap: 10px;
column-gap: 20px;
/* 区域模板 */
grid-template-areas:
"header header header"
"sidebar content content"
"footer footer footer";
/* 对齐网格项(水平) */
justify-items: center; /* start | end | center | stretch */
/* 对齐网格项(垂直) */
align-items: center; /* start | end | center | stretch */
/* 对齐整个网格(水平) */
justify-content: space-between; /* start | end | center | stretch | space-around | space-between | space-evenly */
/* 对齐整个网格(垂直) */
align-content: space-between; /* start | end | center | stretch | space-around | space-between | space-evenly */
}
.item {
/* 指定项目位置 */
grid-column: 1 / 3; /* 从第1列线到第3列线 */
grid-row: 2 / 3; /* 从第2行线到第3行线 */
/* 简写形式 */
grid-area: 2 / 1 / 3 / 3; /* row-start / column-start / row-end / column-end */
/* 使用命名区域 */
grid-area: header;
/* 单个项目对齐(水平) */
justify-self: end; /* start | end | center | stretch */
/* 单个项目对齐(垂直) */
align-self: center; /* start | end | center | stretch */
}
/* 经典网页布局 */
.grid-layout {
display: grid;
grid-template-areas:
"header header header"
"nav content sidebar"
"footer footer footer";
grid-template-columns: 200px 1fr 200px;
grid-template-rows: auto 1fr auto;
min-height: 100vh;
gap: 10px;
}
.header { grid-area: header; }
.nav { grid-area: nav; }
.content { grid-area: content; }
.sidebar { grid-area: sidebar; }
.footer { grid-area: footer; }
/* 响应式图片画廊 */
.gallery {
display: grid;
grid-template-columns: repeat(auto-fill, minmax(250px, 1fr));
gap: 15px;
}
.gallery-item {
overflow: hidden;
border-radius: 8px;
}
.gallery-item img {
width: 100%;
height: 100%;
object-fit: cover;
}
特性 | Flexbox | Grid |
---|---|---|
维度 | 一维(行或列) | 二维(行和列) |
适用场景 | 小组件、导航栏、单行/列布局 | 整页布局、复杂的二维布局 |
内容驱动 | 是(尺寸由内容决定) | 否(尺寸由网格决定) |
控制方向 | 主轴和交叉轴 | 行和列 |
空白分配 | 在元素之间 | 在网格线之间 |
媒体查询是响应式设计的基础,允许根据设备特性应用不同的样式。
/* 基本样式 - 适用于所有设备 */
.container {
width: 100%;
padding: 15px;
}
/* 小屏幕设备 (手机) */
@media (max-width: 576px) {
.container {
padding: 10px;
}
}
/* 中等屏幕设备 (平板) */
@media (min-width: 577px) and (max-width: 992px) {
.container {
max-width: 720px;
margin: 0 auto;
}
}
/* 大屏幕设备 (桌面) */
@media (min-width: 993px) {
.container {
max-width: 1140px;
margin: 0 auto;
}
}
流体布局使用百分比单位,使内容能够适应不同的屏幕尺寸。
.container {
width: 90%;
max-width: 1200px;
margin: 0 auto;
}
.column {
float: left;
width: 33.33%;
padding: 0 15px;
}
@media (max-width: 768px) {
.column {
width: 50%;
}
}
@media (max-width: 480px) {
.column {
width: 100%;
}
}
弹性布局使用相对单位(如em、rem),使内容能够根据用户的字体大小偏好进行缩放。
html {
font-size: 16px; /* 基准字体大小 */
}
body {
font-size: 1rem; /* 相对于html的字体大小 */
line-height: 1.5;
}
h1 {
font-size: 2.5rem; /* 40px */
}
.container {
max-width: 75rem; /* 1200px */
padding: 1.25rem; /* 20px */
}
@media (max-width: 768px) {
html {
font-size: 14px; /* 在小屏幕上减小基准字体大小 */
}
}
视口单位(vw、vh、vmin、vmax)相对于视口尺寸,非常适合创建全屏布局。
.hero {
height: 100vh; /* 视口高度的100% */
width: 100vw; /* 视口宽度的100% */
}
.title {
font-size: 5vw; /* 视口宽度的5% */
}
.responsive-padding {
padding: 2vmin; /* 视口宽度或高度中较小值的2% */
}
/* 基本响应式图片 */
img {
max-width: 100%;
height: auto;
}
/* 使用picture元素提供不同分辨率的图片 */
"large.jpg" media="(min-width: 1200px)">
"medium.jpg" media="(min-width: 768px)">
"small.jpg" alt="响应式图片">
CSS多列布局允许内容自动分成多列,类似于报纸布局。
.multi-column {
column-count: 3; /* 列数 */
column-gap: 2em; /* 列间距 */
column-rule: 1px solid #ddd; /* 列分隔线 */
}
.multi-column h2 {
column-span: all; /* 标题跨越所有列 */
}
CSS形状允许文本围绕不规则形状流动。
.circle-text {
width: 300px;
height: 300px;
shape-outside: circle(50%);
float: left;
border-radius: 50%;
}
.custom-shape {
float: left;
shape-outside: polygon(0 0, 100% 0, 100% 100%, 30% 100%);
clip-path: polygon(0 0, 100% 0, 100% 100%, 30% 100%);
width: 300px;
height: 300px;
}
CSS Grid子网格允许子元素继承父网格的轨道定义。
.parent-grid {
display: grid;
grid-template-columns: repeat(9, 1fr);
gap: 10px;
}
.child-grid {
grid-column: 2 / 8;
display: grid;
grid-template-columns: subgrid; /* 继承父网格的列定义 */
}
容器查询允许基于父容器的尺寸而不是视口尺寸应用样式。
/* 定义一个查询容器 */
.card-container {
container-type: inline-size;
}
/* 基于容器宽度应用样式 */
@container (min-width: 400px) {
.card {
display: flex;
}
.card-image {
width: 40%;
}
.card-content {
width: 60%;
}
}
圣杯布局是一种经典的三列布局,中间列包含主要内容,两侧是固定宽度的侧边栏。
.holy-grail {
display: flex;
min-height: 100vh;
flex-direction: column;
}
.holy-grail-header,
.holy-grail-footer {
flex: 0 0 auto;
}
.holy-grail-body {
display: flex;
flex: 1 0 auto;
}
.holy-grail-content {
flex: 1 0 auto;
}
.holy-grail-nav,
.holy-grail-ads {
flex: 0 0 200px;
}
.holy-grail-nav {
order: -1;
}
@media (max-width: 768px) {
.holy-grail-body {
flex-direction: column;
}
.holy-grail-nav,
.holy-grail-ads {
flex: 0 0 auto;
}
}
.holy-grail {
display: grid;
min-height: 100vh;
grid-template-areas:
"header header header"
"nav content ads"
"footer footer footer";
grid-template-columns: 200px 1fr 200px;
grid-template-rows: auto 1fr auto;
}
.holy-grail-header { grid-area: header; }
.holy-grail-nav { grid-area: nav; }
.holy-grail-content { grid-area: content; }
.holy-grail-ads { grid-area: ads; }
.holy-grail-footer { grid-area: footer; }
@media (max-width: 768px) {
.holy-grail {
grid-template-areas:
"header"
"nav"
"content"
"ads"
"footer";
grid-template-columns: 1fr;
grid-template-rows: auto auto 1fr auto auto;
}
}
卡片网格是现代网站常用的布局方式,适合展示产品、文章等内容。
.card-grid {
display: grid;
grid-template-columns: repeat(auto-fill, minmax(300px, 1fr));
gap: 20px;
padding: 20px;
}
.card {
display: flex;
flex-direction: column;
border-radius: 8px;
overflow: hidden;
box-shadow: 0 2px 10px rgba(0, 0, 0, 0.1);
transition: transform 0.3s ease;
}
.card:hover {
transform: translateY(-5px);
}
.card-image {
height: 200px;
overflow: hidden;
}
.card-image img {
width: 100%;
height: 100%;
object-fit: cover;
transition: transform 0.3s ease;
}
.card:hover .card-image img {
transform: scale(1.05);
}
.card-content {
padding: 20px;
flex: 1;
display: flex;
flex-direction: column;
}
.card-title {
margin-top: 0;
margin-bottom: 10px;
}
.card-text {
margin-bottom: 20px;
flex: 1;
}
.card-button {
align-self: flex-start;
padding: 8px 16px;
background-color: #0066cc;
color: white;
border: none;
border-radius: 4px;
cursor: pointer;
}
全屏分屏布局将屏幕分成几个全屏部分,常用于展示页面或产品介绍。
.fullscreen-sections {
height: 100vh;
overflow-y: scroll;
scroll-snap-type: y mandatory;
}
.section {
height: 100vh;
scroll-snap-align: start;
display: flex;
flex-direction: column;
justify-content: center;
align-items: center;
padding: 20px;
}
.section:nth-child(odd) {
background-color: #f8f8f8;
}
.section-content {
max-width: 800px;
text-align: center;
}
.section-title {
font-size: 3rem;
margin-bottom: 20px;
}
.section-text {
font-size: 1.2rem;
line-height: 1.6;
margin-bottom: 30px;
}
.section-button {
padding: 12px 24px;
background-color: #0066cc;
color: white;
border: none;
border-radius: 4px;
font-size: 1rem;
cursor: pointer;
transition: background-color 0.3s;
}
.section-button:hover {
background-color: #0052a3;
}
/* 优化前 */
.box {
width: 300px;
height: 200px;
background-color: red;
}
.box:hover {
width: 310px; /* 触发重排 */
height: 210px; /* 触发重排 */
background-color: blue; /* 触发重绘 */
}
/* 优化后 */
.box {
width: 300px;
height: 200px;
background-color: red;
transform: scale(1); /* 使用transform代替宽高变化 */
transition: transform 0.3s, background-color 0.3s;
}
.box:hover {
transform: scale(1.03); /* 不触发重排 */
background-color: blue; /* 只触发重绘 */
}
使用CSS属性触发GPU加速,提高动画性能。
.accelerated {
transform: translateZ(0); /* 启用硬件加速 */
will-change: transform; /* 提示浏览器元素将发生变化 */
}
避免在JavaScript中频繁读取和修改DOM几何属性。
// 不好的做法 - 导致布局抖动
for (let i = 0; i < elements.length; i++) {
const height = elements[i].offsetHeight; // 读取
elements[i].style.height = (height * 2) + 'px'; // 写入
}
// 好的做法 - 批量读取和写入
const heights = [];
// 先读取
for (let i = 0; i < elements.length; i++) {
heights.push(elements[i].offsetHeight);
}
// 再写入
for (let i = 0; i < elements.length; i++) {
elements[i].style.height = (heights[i] * 2) + 'px';
}
CSS Houdini是一组低级API,允许开发者直接访问CSS引擎。
// 注册自定义属性
CSS.registerProperty({
name: '--my-color',
syntax: '' ,
inherits: false,
initialValue: '#c0ffee'
});
// 创建自定义布局
registerLayout('masonry', class {
static get inputProperties() { return ['--gap']; }
async layout(children, edges, constraints, styleMap) {
// 实现瀑布流布局逻辑
}
});
CSS Scroll Snap提供了更精确的滚动位置控制。
.container {
scroll-snap-type: y mandatory;
overflow-y: scroll;
height: 100vh;
}
.section {
scroll-snap-align: start;
height: 100vh;
}
CSS Aspect Ratio允许元素保持特定的宽高比。
.video-container {
aspect-ratio: 16 / 9;
width: 100%;
}
.square {
aspect-ratio: 1 / 1;
width: 50%;
}
CSS逻辑属性使布局适应不同的书写模式和阅读方向。
.box {
/* 物理属性 */
margin-left: 10px;
padding-right: 20px;
border-top: 1px solid black;
/* 逻辑属性 */
margin-inline-start: 10px; /* 根据文本方向自动调整 */
padding-inline-end: 20px;
border-block-start: 1px solid black;
}
使用浏览器开发工具可视化和调试Grid布局。
/* Firefox和Chrome开发工具都支持Grid布局可视化 */
.grid-container {
display: grid;
grid-template-columns: repeat(3, 1fr);
grid-template-rows: auto 1fr auto;
gap: 10px;
}
/* 在开发工具中可以查看Flex容器和项目的属性 */
.flex-container {
display: flex;
justify-content: space-between;
align-items: center;
}
/* 使用轮廓线可视化元素边界,不影响布局 */
* {
outline: 1px solid rgba(255, 0, 0, 0.2);
}
/* 使用背景色区分不同的布局区域 */
header { background-color: rgba(255, 0, 0, 0.1); }
nav { background-color: rgba(0, 255, 0, 0.1); }
main { background-color: rgba(0, 0, 255, 0.1); }
/* 基础样式 - 适用于小屏幕 */
.container {
padding: 10px;
}
/* 中等屏幕及以上 */
@media (min-width: 768px) {
.container {
padding: 20px;
max-width: 720px;
margin: 0 auto;
}
}
/* 大屏幕及以上 */
@media (min-width: 1200px) {
.container {
max-width: 1140px;
}
}
/* 确保内容在禁用CSS的情况下仍然可读 */
/* 使用相对单位以支持文本缩放 */
body {
font-size: 1rem;
line-height: 1.5;
}
/* 支持减少动画 */
@media (prefers-reduced-motion: reduce) {
* {
animation-duration: 0.01ms !important;
animation-iteration-count: 1 !important;
transition-duration: 0.01ms !important;
scroll-behavior: auto !important;
}
}
结语
感谢您的阅读!期待您的一键三连!欢迎指正!