0%

Css 新特性与技巧——现代样式开发必备技能

过年期间,Css 的布局就像年夜饭的摆盘,要美观又实用…

介绍

  Css(Cascading Style Sheets)作为前端开发的三大支柱之一,近年来经历了巨大的发展。从 Css Grid 到 Container Queries,从新的伪类选择器到 Houdini API,现代 Css 为我们提供了越来越强大和灵活的样式控制能力。

  本文将带你深入了解 Css 的奇技淫巧,展示如何运用现代 Css 特性创造令人惊艳的视觉效果和用户体验。

Css Grid 高级技巧

Grid 布局的自适应

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
/* 使用 Grid 创建响应式网格 */
.grid-container {
display: grid;
grid-template-columns: repeat(auto-fit, minmax(250px, 1fr));
gap: 1rem;
padding: 1rem;
}

/* 智能网格布局 */
.smart-grid {
display: grid;
grid-template-columns: repeat(auto-fill, minmax(min(300px, 100%), 1fr));
grid-auto-rows: minmax(150px, auto);
gap: 1rem;
}

/* 混合单位网格 */
.hybrid-grid {
display: grid;
grid-template-columns:
[sidebar-start] 250px
[content-start] 1fr
[content-end sidebar-end];
grid-template-areas:
"sidebar header"
"sidebar main"
"sidebar footer";
}

@media (max-width: 768px) {
.hybrid-grid {
grid-template-columns: 1fr;
grid-template-areas:
"header"
"sidebar"
"main"
"footer";
}
}

/* Grid 区域布局示例 */
.dashboard-layout {
display: grid;
grid-template-areas:
"header header header"
"sidebar main aside"
"footer footer footer";
grid-template-columns: 200px 1fr 200px;
grid-template-rows: 80px 1fr 60px;
height: 100vh;
gap: 1rem;
}

.header { grid-area: header; }
.sidebar { grid-area: sidebar; }
.main { grid-area: main; }
.aside { grid-area: aside; }
.footer { grid-area: footer; }

Grid 的动态定位

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
/* 混合定位网格 */
.positioned-grid {
display: grid;
grid-template-columns: repeat(6, 1fr);
grid-template-rows: repeat(4, 100px);
gap: 10px;
}

/* 使用 Css 变量控制位置 */
.positioned-grid > * {
--col-start: 1;
--col-end: 2;
--row-start: 1;
--row-end: 2;

grid-column: var(--col-start) / var(--col-end);
grid-row: var(--row-start) / var(--row-end);
}

/* 动态位置调整 */
.card-1 { --col-start: 1; --col-end: 3; --row-start: 1; --row-end: 2; }
.card-2 { --col-start: 3; --col-end: 5; --row-start: 1; --row-end: 2; }
.card-3 { --col-start: 5; --col-end: 7; --row-start: 1; --row-end: 2; }
.card-4 { --col-start: 1; --col-end: 4; --row-start: 2; --row-end: 4; }
.card-5 { --col-start: 4; --col-end: 7; --row-start: 2; --row-end: 4; }

/* Grid 与动画结合 */
.animated-grid {
display: grid;
grid-template-columns: repeat(3, 1fr);
gap: 20px;
}

.animated-grid > div {
transition: all 0.3s ease;
}

.animated-grid > div:hover {
transform: scale(1.05);
z-index: 1;
box-shadow: 0 10px 25px rgba(0,0,0,0.15);
}

Flexbox 高级技巧

Flexbox 布局优化

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
/* 真正居中的 Flexbox */
.center-flex {
display: flex;
justify-content: center;
align-items: center;
min-height: 100vh;
}

/* Flexbox 等高列 */
.equal-height {
display: flex;
gap: 1rem;
}

.equal-height > div {
flex: 1;
padding: 1rem;
border: 1px solid #ddd;
/* 自动等高 */
}

/* Flexbox 自适应内容 */
.fit-content {
display: flex;
flex-wrap: wrap;
gap: 1rem;
}

.fit-content > * {
flex: 1 1 200px; /* 弹性增长,弹性收缩,基础宽度200px */
min-width: 0; /* 防止内容溢出 */
}

/* Flexbox 卡片布局 */
.cards-container {
display: flex;
flex-wrap: wrap;
gap: 1rem;
justify-content: space-between;
}

.card {
flex: 1 1 calc(33.333% - 1rem);
min-width: 250px;
padding: 1.5rem;
border-radius: 8px;
box-shadow: 0 2px 10px rgba(0,0,0,0.1);
transition: transform 0.2s ease;
}

.card:hover {
transform: translateY(-5px);
}

/* Flexbox 自适应文本 */
.text-adaptive {
display: flex;
align-items: center;
gap: 1rem;
padding: 1rem;
border: 1px solid #eee;
border-radius: 4px;
}

.text-adaptive > img {
flex-shrink: 0;
width: 50px;
height: 50px;
object-fit: cover;
border-radius: 50%;
}

.text-adaptive > div {
flex: 1;
overflow: hidden;
min-width: 0; /* 关键:防止文本溢出 */
}

.text-adaptive > div > h3 {
margin: 0;
white-space: nowrap;
overflow: hidden;
text-overflow: ellipsis;
}

.text-adaptive > div > p {
margin: 0.5rem 0 0 0;
color: #666;
font-size: 0.9em;
white-space: nowrap;
overflow: hidden;
text-overflow: ellipsis;
}

Flexbox 动画技巧

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
/* Flexbox 动画列表 */
.animated-list {
display: flex;
flex-direction: column;
gap: 0.5rem;
max-height: 300px;
overflow-y: auto;
}

.animated-list > li {
flex: 0 0 auto;
opacity: 0;
transform: translateX(-20px);
transition: all 0.3s ease;
}

.animated-list > li.appear {
opacity: 1;
transform: translateX(0);
}

/* Flexbox 进度条 */
.progress-container {
display: flex;
height: 20px;
background: #f0f0f0;
border-radius: 10px;
overflow: hidden;
}

.progress-bar {
display: flex;
align-items: center;
justify-content: center;
min-width: 0;
height: 100%;
background: linear-gradient(90deg, #4CAF50, #45a049);
color: white;
font-size: 0.75rem;
font-weight: bold;
transition: width 0.3s ease;
position: relative;
}

.progress-text {
position: absolute;
left: 50%;
transform: translateX(-50%);
color: white;
font-size: 0.75rem;
z-index: 1;
}

Css Container Queries

Container Queries 实战

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
/* Container Queries 示例 */
.card-container {
container-type: inline-size;
container-name: card;
padding: 1rem;
}

/* 基于容器尺寸的样式 */
@container card (min-width: 300px) {
.card {
display: flex;
gap: 1rem;
}

.card-image {
flex-shrink: 0;
width: 80px;
height: 80px;
}

.card-content {
flex: 1;
}
}

@container card (min-width: 500px) {
.card {
gap: 2rem;
}

.card-image {
width: 120px;
height: 120px;
}
}

/* 多个 Container Queries */
.gallery-container {
container-type: inline-size;
display: grid;
grid-template-columns: repeat(auto-fill, minmax(200px, 1fr));
gap: 1rem;
}

.gallery-item {
aspect-ratio: 1 / 1;
background: #f0f0f0;
border-radius: 8px;
display: flex;
align-items: center;
justify-content: center;
overflow: hidden;
}

@container (min-width: 400px) {
.gallery-item {
aspect-ratio: 4 / 3;
}
}

@container (min-width: 600px) {
.gallery-item {
aspect-ratio: 16 / 9;
}
}

/* 组件级别的响应式 */
.component-wrapper {
container-type: inline-size;
width: 100%;
}

.component {
padding: 1rem;
background: white;
border-radius: 8px;
box-shadow: 0 2px 8px rgba(0,0,0,0.1);
}

@container (width > 300px) {
.component {
padding: 1.5rem;
}
}

@container (width > 500px) {
.component {
display: grid;
grid-template-columns: 1fr 2fr;
gap: 1.5rem;
padding: 2rem;
}
}

Container Queries 高级应用

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
/* 嵌套 Container Queries */
.outer-container {
container-type: inline-size;
max-width: 1200px;
margin: 0 auto;
padding: 1rem;
}

.inner-container {
container-type: inline-size;
display: grid;
grid-template-columns: 1fr;
gap: 1rem;
}

@container outer (min-width: 600px) {
.inner-container {
grid-template-columns: repeat(2, 1fr);
}
}

@container inner (min-width: 400px) {
.inner-item {
padding: 2rem;
}
}

/* 基于内容的样式 */
.content-aware {
container-type: inline-size;
container-name: content;
}

@container content (width > 300px) and (width < 600px) {
.responsive-element {
font-size: clamp(1rem, 2.5vw, 1.2rem);
}
}

@container content (width >= 600px) {
.responsive-element {
font-size: clamp(1.2rem, 3vw, 1.5rem);
}
}

/* 容器查询的媒体查询后备 */
.fallback-container {
display: grid;
grid-template-columns: 1fr; /* 默认单列 */
}

/* 媒体查询后备 */
@media (min-width: 600px) {
.fallback-container {
grid-template-columns: repeat(2, 1fr);
}
}

/* 容器查询(优先级更高) */
@supports (container-type: inline-size) {
.fallback-container {
container-type: inline-size;
}

@container (min-width: 500px) {
grid-template-columns: repeat(2, 1fr);
}
}

Css 自定义属性(Variables)

动态主题系统

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
/* 主题变量系统 */
:root {
/* 颜色系统 */
--primary-color: #3498db;
--secondary-color: #2ecc71;
--accent-color: #e74c3c;
--neutral-color: #95a5a6;
--dark-color: #2c3e50;
--light-color: #ecf0f1;

/* 间距系统 */
--spacing-xs: 0.25rem;
--spacing-sm: 0.5rem;
--spacing-md: 1rem;
--spacing-lg: 1.5rem;
--spacing-xl: 2rem;
--spacing-2xl: 3rem;

/* 字体系统 */
--font-size-xs: 0.75rem;
--font-size-sm: 0.875rem;
--font-size-base: 1rem;
--font-size-lg: 1.125rem;
--font-size-xl: 1.25rem;
--font-size-2xl: 1.5rem;
--font-size-3xl: 1.875rem;

/* 圆角系统 */
--radius-xs: 0.125rem;
--radius-sm: 0.25rem;
--radius-md: 0.375rem;
--radius-lg: 0.5rem;
--radius-xl: 0.75rem;
--radius-full: 9999px;

/* 阴影系统 */
--shadow-sm: 0 1px 2px 0 rgba(0, 0, 0, 0.05);
--shadow-md: 0 4px 6px -1px rgba(0, 0, 0, 0.1);
--shadow-lg: 0 10px 15px -3px rgba(0, 0, 0, 0.1);
--shadow-xl: 0 20px 25px -5px rgba(0, 0, 0, 0.1);
}

/* 深色主题 */
[data-theme="dark"] {
--primary-color: #5dade2;
--secondary-color: #58d68d;
--accent-color: #ec7063;
--dark-color: #ecf0f1;
--light-color: #2c3e50;
--shadow-sm: 0 1px 2px 0 rgba(0, 0, 0, 0.2);
--shadow-md: 0 4px 6px -1px rgba(0, 0, 0, 0.3);
--shadow-lg: 0 10px 15px -3px rgba(0, 0, 0, 0.3);
--shadow-xl: 0 20px 25px -5px rgba(0, 0, 0, 0.3);
}

/* 使用变量的组件 */
.button {
padding: var(--spacing-sm) var(--spacing-md);
border-radius: var(--radius-md);
font-size: var(--font-size-base);
background: var(--primary-color);
color: white;
border: none;
cursor: pointer;
transition: all 0.2s ease;
}

.button:hover {
background: color-mix(in srgb, var(--primary-color) 80%, black 20%);
transform: translateY(-1px);
box-shadow: var(--shadow-md);
}

/* 动态颜色计算 */
.gradient-card {
background: linear-gradient(
135deg,
var(--primary-color),
color-mix(in srgb, var(--primary-color) 70%, var(--secondary-color) 30%)
);
padding: var(--spacing-lg);
border-radius: var(--radius-lg);
color: white;
}

/* Css 变量与 calc 结合 */
.responsive-text {
font-size: calc(var(--font-size-base) + 0.2vw);
line-height: 1.6;
margin-bottom: var(--spacing-md);
}

/* 变量的动态设置 */
.highlight {
--highlight-color: var(--accent-color);
background: color-mix(in srgb, var(--highlight-color) 10%, transparent 90%);
padding: var(--spacing-xs) var(--spacing-sm);
border-radius: var(--radius-sm);
font-weight: bold;
}

Css 变量的动画

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
/* 基于变量的动画 */
.animated-progress {
--progress: 0;
width: 100%;
height: 20px;
background: #f0f0f0;
border-radius: 10px;
overflow: hidden;
position: relative;
}

.animated-progress::before {
content: '';
position: absolute;
top: 0;
left: 0;
height: 100%;
width: calc(var(--progress) * 1%);
background: linear-gradient(90deg, #4CAF50, #45a049);
border-radius: 10px;
transition: width 0.3s ease;
}

/* 使用 JS 动态设置进度 */
/* document.documentElement.style.setProperty('--progress', '75'); */

/* 变量驱动的动画组件 */
.animated-counter {
--count: 0;
font-size: var(--font-size-3xl);
font-weight: bold;
color: var(--primary-color);
counter-reset: count var(--count);
}

.animated-counter::after {
content: counter(count);
transition: all 0.3s ease;
}

/* 色彩渐变动画 */
.color-wheel {
--hue: 0;
width: 100px;
height: 100px;
border-radius: 50%;
background: hsl(var(--hue), 70%, 50%);
animation: rotateHue 5s linear infinite;
}

@keyframes rotateHue {
from { --hue: 0; }
to { --hue: 360; }
}

现代 Css 伪类和伪元素

高级伪类选择器

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
/* :is() 和 :where() 伪类 */
/* :is() - 匹配括号内的任意选择器 */
.featured-content :is(h1, h2, h3) {
color: var(--primary-color);
margin-bottom: var(--spacing-md);
}

/* :where() - 不影响特异性 */
.where-example :where(button, .btn, input[type="submit"]) {
padding: var(--spacing-sm) var(--spacing-md);
border: 1px solid #ccc;
border-radius: var(--radius-md);
cursor: pointer;
}

/* :not() 的高级用法 */
.form-field:not(:last-child) {
margin-bottom: var(--spacing-md);
}

/* 多重否定 */
.item:not(.featured):not(.hidden):not(.disabled) {
opacity: 0.7;
transition: opacity 0.2s ease;
}

.item:not(.featured):not(.hidden):not(.disabled):hover {
opacity: 1;
}

/* :has() 伪类(现代浏览器支持) */
/* 兄弟元素检查 */
.parent:has(.child.active) {
background: color-mix(in srgb, var(--primary-color) 10%, transparent 90%);
border-left: 3px solid var(--primary-color);
}

/* 子元素存在检查 */
.article:has(h1) .article-meta {
margin-top: var(--spacing-lg);
}

/* :nth-child() 高级用法 */
/* 选择奇数行 */
.table-row:nth-child(odd) {
background: color-mix(in srgb, var(--light-color) 80%, transparent 20%);
}

/* 从第4个开始的每第3个 */
.item:nth-child(3n + 4) {
border-left: 3px solid var(--accent-color);
}

/* 最后3个 */
.item:nth-last-child(-n + 3) {
opacity: 0.8;
}

/* 介于特定位置之间 */
.item:nth-child(n + 3):nth-child(-n + 8) {
border-right: 1px solid #eee;
}

伪元素创意应用

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
/* 文本装饰效果 */
.decorative-text {
position: relative;
display: inline-block;
}

.decorative-text::before {
content: '';
position: absolute;
bottom: -2px;
left: 0;
width: 100%;
height: 2px;
background: linear-gradient(90deg, transparent, var(--primary-color), transparent);
transform: scaleX(0);
transform-origin: center;
transition: transform 0.3s ease;
}

.decorative-text:hover::before {
transform: scaleX(1);
}

/* 渐变边框 */
.gradient-border {
position: relative;
padding: var(--spacing-lg);
border-radius: var(--radius-lg);
}

.gradient-border::before {
content: '';
position: absolute;
inset: 0;
padding: 2px;
background: linear-gradient(45deg, var(--primary-color), var(--secondary-color));
border-radius: inherit;
mask: linear-gradient(#fff 0 0) content-box, linear-gradient(#fff 0 0);
mask-composite: exclude;
-webkit-mask-composite: xor;
}

/* 焦点环效果 */
.focus-ring {
position: relative;
outline: none;
}

.focus-ring:focus::after {
content: '';
position: absolute;
inset: -3px;
border: 2px solid var(--primary-color);
border-radius: inherit;
animation: pulse 1.5s infinite;
}

@keyframes pulse {
0% { box-shadow: 0 0 0 0 color-mix(in srgb, var(--primary-color) 70%, transparent 30%); }
70% { box-shadow: 0 0 0 10px transparent; }
100% { box-shadow: 0 0 0 0 transparent; }
}

/* 悬浮提示 */
.tooltip-trigger {
position: relative;
}

.tooltip-trigger::after {
content: attr(data-tooltip);
position: absolute;
bottom: 100%;
left: 50%;
transform: translateX(-50%) translateY(-5px);
background: var(--dark-color);
color: white;
padding: var(--spacing-xs) var(--spacing-sm);
border-radius: var(--radius-sm);
font-size: var(--font-size-sm);
white-space: nowrap;
opacity: 0;
visibility: hidden;
transition: all 0.2s ease;
z-index: 1000;
}

.tooltip-trigger:hover::after {
opacity: 1;
visibility: visible;
transform: translateX(-50%) translateY(0);
}

/* 图片遮罩效果 */
.image-overlay {
position: relative;
overflow: hidden;
}

.image-overlay img {
width: 100%;
height: auto;
transition: transform 0.3s ease;
}

.image-overlay::before {
content: '';
position: absolute;
top: 0;
left: 0;
right: 0;
bottom: 0;
background: linear-gradient(to bottom, transparent 60%, rgba(0,0,0,0.7));
opacity: 0;
transition: opacity 0.3s ease;
}

.image-overlay:hover::before {
opacity: 1;
}

.image-overlay:hover img {
transform: scale(1.05);
}

Css 新特性详解

逻辑属性

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
/* 逻辑属性示例 */
.layout-container {
/* 逻辑边距 */
margin-block-start: var(--spacing-lg);
margin-block-end: var(--spacing-lg);
margin-inline-start: var(--spacing-md);
margin-inline-end: var(--spacing-md);

/* 逻辑内边距 */
padding-block: var(--spacing-md);
padding-inline: var(--spacing-lg);

/* 逻辑边框 */
border-block-start: 2px solid var(--primary-color);
border-inline-end: 1px dashed var(--neutral-color);

/* 逻辑尺寸 */
min-block-size: 300px; /* 等同于 min-height */
max-inline-size: 800px; /* 等同于 max-width */

/* 逻辑位置 */
inset-block-start: 10px; /* 等同于 top */
inset-inline-end: 10px; /* 等同于 right */
}

/* 方向性适配 */
.text-component {
text-align: start; /* 自动适配书写方向 */
margin-inline-start: var(--spacing-md); /* LTR 时为 margin-left,RTL 时为 margin-right */
padding-inline-end: var(--spacing-sm);
}

/* 多语言适配 */
[dir="rtl"] .text-component {
/* 无需额外规则,逻辑属性自动适配 */
}

颜色函数

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
/* 现代颜色函数 */
.color-examples {
--base-color: rgb(52, 152, 219);
--lighter-color: color-mix(in srgb, var(--base-color) 70%, white 30%);
--darker-color: color-mix(in srgb, var(--base-color) 80%, black 20%);
--transparent-color: color-mix(in srgb, var(--base-color) 50%, transparent 50%);

/* HSL 颜色 */
--hsl-color: hsl(200, 70%, 50%);

/* 相对颜色 */
--adjusted-color: lab(from var(--base-color) l c h);
}

.relative-colors {
background-color: oklch(from var(--base-color) calc(l + 0.2) c calc(h + 30deg));
color: oklch(from var(--base-color) calc(l - 0.3) c h);
}

/* 颜色对比度 */
.accessible-text {
background: var(--base-color);
/* 确保足够的对比度 */
color: color-contrast(
var(--base-color) vs white, black
);
}

滚动行为

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
/* 滚动捕捉 */
.scroll-container {
display: grid;
grid-auto-flow: column;
grid-auto-columns: 100%;
scroll-snap-type: x mandatory;
overflow-x: auto;
scroll-behavior: smooth;
}

.scroll-item {
scroll-snap-align: start;
}

/* 侧边滚动容器 */
.sidebar-nav {
height: 400px;
overflow-y: auto;
scroll-snap-type: y proximity;
padding: var(--spacing-md);
}

.sidebar-nav > * {
scroll-snap-align: start;
margin-bottom: var(--spacing-md);
}

/* 滚动驱动动画 */
.scrolling-animation {
animation: slideIn 1s ease-out;
animation-timeline: scroll();
animation-range: entry 0% entry 100%;
}

@keyframes slideIn {
from {
transform: translateX(-100%);
opacity: 0;
}
to {
transform: translateX(0);
opacity: 1;
}
}

实用技巧合集

形状和裁剪

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
/* 复杂形状 */
.hexagon {
width: 100px;
height: 100px;
background: var(--primary-color);
clip-path: polygon(50% 0%, 100% 25%, 100% 75%, 50% 100%, 0% 75%, 0% 25%);
}

/* 心形 */
.heart-shape {
width: 100px;
height: 90px;
position: relative;
}

.heart-shape::before,
.heart-shape::after {
content: '';
width: 52px;
height: 80px;
position: absolute;
background: var(--accent-color);
border-radius: 50px 50px 0 0;
transform: rotate(-45deg);
transform-origin: 0 100%;
}

.heart-shape::after {
left: 50px;
transform: rotate(45deg);
transform-origin: 100% 100%;
}

/* 波浪形分割线 */
.wave-divider {
height: 100px;
background: var(--secondary-color);
clip-path: path("M0,0 V80 Q40,100 80,80 T160,80 V0 Z");
}

/* 扇形裁剪 */
.sector {
width: 200px;
height: 200px;
background: radial-gradient(circle, var(--primary-color) 50%, transparent 51%);
clip-path: path("M100,100 L200,100 A100,100 0 0,1 100,200 Z");
}

/* 多边形 */
.octagon {
width: 100px;
height: 100px;
background: var(--accent-color);
clip-path: polygon(
30% 0%, 70% 0%,
100% 30%, 100% 70%,
70% 100%, 30% 100%,
0% 70%, 0% 30%
);
}

特殊效果

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
/* 粘性头部 */
.sticky-header {
position: sticky;
top: 0;
background: white;
z-index: 100;
box-shadow: 0 2px 4px rgba(0,0,0,0.1);
}

/* 视差滚动 */
.parallax-container {
height: 100vh;
overflow-x: hidden;
overflow-y: auto;
perspective: 1px;
}

.parallax-layer {
position: absolute;
top: 0;
left: 0;
right: 0;
bottom: 0;
transform: translateZ(0);
}

.parallax-background {
transform: translateZ(-1px) scale(2);
z-index: -1;
}

/* 深度效果 */
.depth-effect {
position: relative;
}

.depth-effect::after {
content: '';
position: absolute;
inset: 0;
border-radius: inherit;
box-shadow: 0 8px 16px rgba(0,0,0,0.15);
z-index: -1;
filter: blur(8px);
opacity: 0.6;
}

/* 玻璃态效果 */
.glass-effect {
background: rgba(255, 255, 255, 0.1);
backdrop-filter: blur(10px);
border: 1px solid rgba(255, 255, 255, 0.2);
border-radius: var(--radius-lg);
padding: var(--spacing-lg);
}

/* 文本渐变 */
.gradient-text {
background: linear-gradient(45deg, var(--primary-color), var(--secondary-color));
-webkit-background-clip: text;
-webkit-text-fill-color: transparent;
background-clip: text;
font-weight: bold;
}

/* 毛玻璃按钮 */
.frosted-button {
background: rgba(255, 255, 255, 0.2);
backdrop-filter: blur(10px);
border: 1px solid rgba(255, 255, 255, 0.3);
border-radius: var(--radius-md);
padding: var(--spacing-sm) var(--spacing-md);
color: white;
cursor: pointer;
transition: all 0.2s ease;
}

.frosted-button:hover {
background: rgba(255, 255, 255, 0.3);
transform: translateY(-2px);
}

响应式设计技巧

响应式单位

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
/* Clamp 函数响应式字体 */
.responsive-heading {
/* 最小1rem,理想值为4vw + 1rem,最大2.5rem */
font-size: clamp(1rem, 4vw + 1rem, 2.5rem);
line-height: 1.2;
}

/* 响应式间距 */
.responsive-section {
padding: clamp(1rem, 5vw, 4rem);
margin: clamp(0.5rem, 3vw, 2rem) 0;
}

/* 响应式组件 */
.responsive-card {
width: clamp(250px, 90vw, 600px);
margin: 0 auto;
padding: clamp(1rem, 3vw, 2rem);
}

/* 响应式网格 */
.responsive-grid {
display: grid;
grid-template-columns: repeat(auto-fit, minmax(clamp(200px, 30vw, 300px), 1fr));
gap: clamp(1rem, 2vw, 2rem);
}

/* 响应式图像 */
.responsive-image {
width: clamp(150px, 50vw, 400px);
height: auto;
aspect-ratio: 16 / 9;
object-fit: cover;
}

/* 响应式边距 */
.adaptive-margin {
margin: clamp(1rem, 5vw, 3rem) clamp(1rem, 3vw, 2rem);
}

媒体查询优化

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
/* 容器查询与媒体查询结合 */
.modern-layout {
container-type: inline-size;
}

.modern-layout > .item {
/* 默认样式 */
padding: 1rem;
grid-column: 1 / -1;
}

/* 容器查询(现代浏览器) */
@container (min-width: 400px) {
.modern-layout > .item {
grid-column: span 2;
}
}

@container (min-width: 600px) {
.modern-layout > .item {
grid-column: span 3;
}
}

/* 媒体查询后备(传统浏览器) */
@media (min-width: 600px) {
.modern-layout:has(.item) {
display: grid;
grid-template-columns: repeat(auto-fit, minmax(200px, 1fr));
}
}

/* 混合查询 */
.multi-query {
display: grid;
gap: 1rem;
}

@media (min-width: 768px) and (prefers-reduced-motion: no-preference) {
.multi-query {
animation: fadeInUp 0.5s ease-out;
}
}

@supports (container-type: inline-size) and (display: grid) {
.multi-query {
container-type: inline-size;
}
}

@container (min-width: 500px) {
.multi-query {
grid-template-columns: repeat(2, 1fr);
}
}

性能优化技巧

Css 优化

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
/* 高效的动画属性 */
.optimized-animation {
/* 使用 transform 和 opacity 进行动画,避免 layout thrashing */
will-change: transform, opacity;
}

.optimized-animation:hover {
transform: translateY(-2px);
opacity: 0.9;
}

/* 避免昂贵的属性 */
/* bad: background-position, width, height, top, left */
/* good: transform, opacity, visibility */

/* 分离动画元素 */
.animation-isolation {
isolation: isolate; /* 创建堆叠上下文 */
contain: layout style paint; /* 限制样式、布局和绘制的影响 */
}

/* 使用 containment 优化 */
.card-container {
contain: layout;
}

.card-content {
contain: paint; /* 隔离绘制 */
}

/* 使用 content-visibility */
.performance-list {
container-type: inline-size;
}

.performance-list > li {
content-visibility: auto;
contain-intrinsic-size: 100px; /* 告诉浏览器元素的大致尺寸 */
}

/* 高效的滚动优化 */
.smooth-scrolling {
scroll-behavior: smooth;
-webkit-overflow-scrolling: touch; /* iOS 平滑滚动 */
}

.scroll-container {
contain: strict; /* 最大化优化 */
}

/* 避免重排重绘 */
.no-reflow {
transform: translateZ(0); /* 创建合成层 */
will-change: transform; /* 提示浏览器优化 */
}

/* 使用 Css 变量减少重排 */
.variable-optimization {
/* 而不是修改 width/height,使用 scale */
--scale: 1;
transform: scale(var(--scale));
}

.variable-optimization:hover {
--scale: 1.05;
}

总结

  • Css Grid 和 Flexbox 的高级技巧可以创建复杂的响应式布局
  • Container Queries 提供了组件级别的响应式能力
  • Css 自定义属性系统可以构建动态的主题系统
  • 现代 Css 伪类和伪元素提供了强大的选择和装饰能力
  • 逻辑属性支持国际化和多语言适配
  • 新的颜色函数提供了更灵活的颜色操作
  • 性能优化技巧确保流畅的用户体验
  • 响应式设计应该结合多种技术手段

过年期间,就像 Css 的布局一样,年夜饭的摆盘也要美观又实用。Css 的新特性和奇技淫巧让我们能够创造出既美观又实用的界面效果,就像精心摆盘的年夜饭一样,给人带来视觉和体验上的双重享受。

实用技巧清单

技巧用途代码示例
clamp()响应式单位font-size: clamp(1rem, 4vw, 2rem)
:is()简化选择器:is(h1, h2, h3) { color: red; }
aspect-ratio固定比例aspect-ratio: 16 / 9;
container-type容器查询container-type: inline-size;
color-mix()颜色混合color-mix(in srgb, red 70%, blue 30%)

扩展阅读

  1. MDN Css 参考
  2. Css Tricks
  3. 现代 Css 特性
  4. Css Container Queries

练习建议

  1. 使用 Css Grid 创建一个响应式仪表板
  2. 实现基于 Container Queries 的组件系统
  3. 创建动态主题切换功能
  4. 尝试使用新颜色函数和逻辑属性
  5. 优化现有项目的 Css 性能
bulb