<!DOCTYPE html>
<!-- ============================================================
【前端学习全景图】- 涵盖HTML5 + CSS3 全部核心知识点
包含:语义化标签、表单、多媒体、选择器、盒模型、
定位、Flex/Grid、动画、过渡、变量、容器查询、级联层、
嵌套CSS、:has()、逻辑属性、滤镜、混合模式、锚点定位、
滚动驱动动画、响应式设计 等 全部最新特性。
============================================================ -->
<html lang="zh-CN" dir="ltr">
<head>
<!-- ========== 字符编码与视口 ========== -->
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0, viewport-fit=cover">
<meta name="description" content="前端学习全景图 - 涵盖全部HTML5与CSS3知识点">
<meta name="theme-color" content="#0f172a">
<title>前端学习全景图 · HTML5 + CSS3 全部知识点</title>
<!-- ========== @import 引入外部字体 ========== -->
<style>
@import url('https://fonts.googleapis.com/css2?family=Inter:wght@300;400;600;700;900&family=JetBrains+Mono:wght@400;700&display=swap');
</style>
<!-- ========== 核心样式 ========== -->
<style>
/* ==========================================
@layer - 级联层:控制样式优先级顺序
========================================== */
@layer reset, base, components, utilities, animations;
/* ========== @layer reset - 重置样式 ========== */
@layer reset {
*, *::before, *::after {
margin: 0;
padding: 0;
box-sizing: border-box;
/* 逻辑属性简写 - 等同于 margin/padding 的物理属性 */
}
html {
-webkit-text-size-adjust: 100%;
text-size-adjust: 100%;
/* 平滑滚动 */
scroll-behavior: smooth;
/* 滚动吸附 */
scroll-padding-top: 80px;
}
img, video, canvas, svg {
display: block;
max-inline-size: 100%;
block-size: auto;
}
button, input, select, textarea {
font: inherit;
color: inherit;
}
}
/* ========== @layer base - 基础样式 & CSS自定义属性 ========== */
@layer base {
:root {
/* --- 颜色系统 (使用 oklch 现代颜色空间) --- */
--clr-bg: oklch(0.13 0.02 260);
--clr-surface: oklch(0.18 0.025 260);
--clr-surface-2: oklch(0.22 0.03 260);
--clr-text: oklch(0.93 0.01 260);
--clr-text-muted: oklch(0.72 0.02 260);
--clr-primary: oklch(0.75 0.15 200);
--clr-secondary: oklch(0.78 0.12 170);
--clr-accent: oklch(0.7 0.18 40);
--clr-warning: oklch(0.8 0.16 80);
--clr-success: oklch(0.72 0.14 150);
--clr-danger: oklch(0.65 0.2 25);
--clr-border: oklch(0.35 0.03 260);
--clr-code-bg: oklch(0.16 0.03 260);
--clr-gradient-1: oklch(0.75 0.15 200);
--clr-gradient-2: oklch(0.78 0.12 170);
--clr-gradient-3: oklch(0.7 0.18 40);
/* --- 字体 --- */
--font-sans: 'Inter', 'Segoe UI', system-ui, -apple-system, sans-serif;
--font-mono: 'JetBrains Mono', 'Fira Code', monospace;
/* --- 间距 (基于逻辑属性) --- */
--space-xs: 0.25rem;
--space-sm: 0.5rem;
--space-md: 1rem;
--space-lg: 1.5rem;
--space-xl: 2rem;
--space-2xl: 3rem;
--space-3xl: 4rem;
/* --- 圆角 --- */
--radius-sm: 4px;
--radius-md: 8px;
--radius-lg: 16px;
--radius-xl: 24px;
--radius-full: 9999px;
/* --- 阴影 --- */
--shadow-sm: 0 1px 3px oklch(0 0 0 / 0.12);
--shadow-md: 0 4px 12px oklch(0 0 0 / 0.2);
--shadow-lg: 0 12px 40px oklch(0 0 0 / 0.35);
--shadow-glow: 0 0 30px oklch(0.75 0.15 200 / 0.3);
/* --- 过渡 --- */
--transition-fast: 150ms cubic-bezier(0.4, 0, 0.2, 1);
--transition-base: 300ms cubic-bezier(0.4, 0, 0.2, 1);
--transition-slow: 600ms cubic-bezier(0.22, 1, 0.36, 1);
/* --- 容器宽度 --- */
--container-max: 1200px;
/* --- 层级 --- */
--z-header: 100;
--z-modal: 200;
--z-tooltip: 300;
/* --- 滚动驱动动画时间线 --- */
--scroll-timeline: scroll-timeline-name;
/* 使用 color-mix() 混合颜色 */
--clr-primary-soft: color-mix(in oklch, var(--clr-primary) 20%, transparent);
--clr-surface-hover: color-mix(in oklch, var(--clr-surface) 90%, var(--clr-primary) 10%);
/* 使用 clamp() 流式排版 */
--text-xs: clamp(0.7rem, 0.6rem + 0.3vw, 0.85rem);
--text-sm: clamp(0.8rem, 0.7rem + 0.4vw, 0.95rem);
--text-base: clamp(0.9rem, 0.8rem + 0.5vw, 1.05rem);
--text-md: clamp(1rem, 0.9rem + 0.6vw, 1.2rem);
--text-lg: clamp(1.2rem, 1rem + 0.8vw, 1.5rem);
--text-xl: clamp(1.5rem, 1.2rem + 1.2vw, 2rem);
--text-2xl: clamp(1.8rem, 1.4rem + 1.8vw, 2.8rem);
--text-3xl: clamp(2.2rem, 1.6rem + 2.5vw, 3.5rem);
}
/* 暗色主题为默认,也提供亮色方案 */
@media (prefers-color-scheme: light) {
:root {
--clr-bg: oklch(0.97 0.01 260);
--clr-surface: oklch(0.93 0.015 260);
--clr-surface-2: oklch(0.88 0.02 260);
--clr-text: oklch(0.15 0.02 260);
--clr-text-muted: oklch(0.4 0.02 260);
--clr-border: oklch(0.7 0.03 260);
--clr-code-bg: oklch(0.9 0.02 260);
--shadow-sm: 0 1px 3px oklch(0 0 0 / 0.06);
--shadow-md: 0 4px 12px oklch(0 0 0 / 0.1);
--shadow-lg: 0 12px 40px oklch(0 0 0 / 0.15);
}
}
body {
font-family: var(--font-sans);
font-size: var(--text-base);
line-height: 1.7;
color: var(--clr-text);
background: var(--clr-bg);
min-block-size: 100vh;
/* 使用 100dvh 动态视口高度 */
min-block-size: 100dvh;
/* 抗锯齿 */
-webkit-font-smoothing: antialiased;
-moz-osx-font-smoothing: grayscale;
/* 文本渲染 */
text-rendering: optimizeLegibility;
/* 溢出处理 */
overflow-x: hidden;
}
/* 使用 ::selection 伪元素自定义选中样式 */
::selection {
background: var(--clr-primary);
color: oklch(0.1 0.02 260);
}
/* Firefox 的选中样式 */
::-moz-selection {
background: var(--clr-primary);
color: oklch(0.1 0.02 260);
}
/* 滚动条样式 */
::-webkit-scrollbar {
inline-size: 8px;
}
::-webkit-scrollbar-track {
background: var(--clr-bg);
}
::-webkit-scrollbar-thumb {
background: var(--clr-border);
border-radius: var(--radius-full);
}
::-webkit-scrollbar-thumb:hover {
background: var(--clr-primary);
}
/* 链接 */
a {
color: var(--clr-primary);
text-decoration: none;
transition: color var(--transition-fast), text-decoration-color var(--transition-fast);
text-decoration-color: transparent;
text-underline-offset: 4px;
}
a:hover {
color: var(--clr-secondary);
text-decoration: underline;
text-decoration-color: var(--clr-secondary);
text-decoration-thickness: 2px;
}
a:visited {
color: color-mix(in oklch, var(--clr-primary) 70%, var(--clr-accent));
}
a:focus-visible {
outline: 3px solid var(--clr-primary);
outline-offset: 2px;
border-radius: var(--radius-sm);
}
h1, h2, h3, h4, h5, h6 {
font-weight: 700;
line-height: 1.25;
margin-block-end: var(--space-md);
text-wrap: balance; /* 平衡文本换行 */
}
h1 { font-size: var(--text-3xl); }
h2 { font-size: var(--text-2xl); }
h3 { font-size: var(--text-xl); }
h4 { font-size: var(--text-lg); }
h5 { font-size: var(--text-md); }
h6 { font-size: var(--text-base); }
p {
margin-block-end: var(--space-md);
text-wrap: pretty; /* 避免孤行 */
}
code, pre, kbd, samp {
font-family: var(--font-mono);
font-size: 0.9em;
}
code {
background: var(--clr-code-bg);
padding: 0.1em 0.4em;
border-radius: var(--radius-sm);
border: 1px solid var(--clr-border);
}
pre {
background: var(--clr-code-bg);
padding: var(--space-lg);
border-radius: var(--radius-md);
overflow-x: auto;
border: 1px solid var(--clr-border);
margin-block-end: var(--space-lg);
}
pre code {
background: none;
padding: 0;
border: none;
}
}
/* ========== @layer components - 组件样式 ========== */
@layer components {
/* --- 顶部导航栏 (使用 sticky 定位) --- */
.site-header {
position: sticky;
top: 0;
z-index: var(--z-header);
background: color-mix(in oklch, var(--clr-bg) 80%, transparent);
backdrop-filter: blur(20px);
-webkit-backdrop-filter: blur(20px);
border-block-end: 1px solid var(--clr-border);
padding-block: var(--space-sm);
padding-inline: var(--space-lg);
display: flex;
align-items: center;
justify-content: space-between;
gap: var(--space-md);
flex-wrap: wrap;
}
.site-header .logo {
font-size: var(--text-lg);
font-weight: 900;
letter-spacing: -0.02em;
background: linear-gradient(135deg, var(--clr-gradient-1), var(--clr-gradient-2), var(--clr-gradient-3));
-webkit-background-clip: text;
background-clip: text;
-webkit-text-fill-color: transparent;
color: transparent;
}
.nav-links {
display: flex;
gap: var(--space-md);
list-style: none;
flex-wrap: wrap;
}
.nav-links a {
padding: var(--space-xs) var(--space-sm);
border-radius: var(--radius-full);
font-size: var(--text-sm);
font-weight: 600;
transition: background var(--transition-fast), color var(--transition-fast);
}
.nav-links a:hover {
background: var(--clr-primary-soft);
text-decoration: none;
}
/* --- 主容器 --- */
.container {
max-inline-size: var(--container-max);
margin-inline: auto;
padding-inline: var(--space-lg);
}
/* --- 卡片组件 --- */
.card {
background: var(--clr-surface);
border: 1px solid var(--clr-border);
border-radius: var(--radius-lg);
padding: var(--space-xl);
margin-block-end: var(--space-lg);
transition: box-shadow var(--transition-base), transform var(--transition-base);
/* 使用容器查询单位 */
container-type: inline-size;
}
.card:hover {
box-shadow: var(--shadow-lg);
transform: translateY(-4px);
}
.card h3 {
margin-block-start: 0;
}
/* --- 标签/徽章 --- */
.badge {
display: inline-block;
padding: 0.2em 0.8em;
border-radius: var(--radius-full);
font-size: var(--text-xs);
font-weight: 700;
letter-spacing: 0.03em;
background: var(--clr-primary-soft);
color: var(--clr-primary);
border: 1px solid color-mix(in oklch, var(--clr-primary) 30%, transparent);
margin-inline-end: var(--space-xs);
margin-block-end: var(--space-xs);
}
.badge.accent { background: color-mix(in oklch, var(--clr-accent) 20%, transparent); color: var(--clr-accent); }
.badge.success { background: color-mix(in oklch, var(--clr-success) 20%, transparent); color: var(--clr-success); }
.badge.warning { background: color-mix(in oklch, var(--clr-warning) 20%, transparent); color: var(--clr-warning); }
/* --- 按钮 --- */
.btn {
display: inline-flex;
align-items: center;
justify-content: center;
gap: var(--space-sm);
padding: var(--space-sm) var(--space-lg);
border-radius: var(--radius-full);
border: 2px solid var(--clr-primary);
background: var(--clr-primary);
color: oklch(0.1 0.02 260);
font-weight: 700;
font-size: var(--text-sm);
cursor: pointer;
transition: all var(--transition-base);
/* 使用 :has() 支持 */
}
.btn:hover {
background: transparent;
color: var(--clr-primary);
box-shadow: var(--shadow-glow);
transform: scale(1.03);
}
.btn:active {
transform: scale(0.97);
}
.btn-outline {
background: transparent;
color: var(--clr-primary);
border-color: var(--clr-border);
}
.btn-outline:hover {
border-color: var(--clr-primary);
background: var(--clr-primary-soft);
box-shadow: none;
transform: none;
}
/* --- 代码块带注释标签 --- */
.code-label {
display: flex;
align-items: center;
gap: var(--space-sm);
font-size: var(--text-xs);
font-weight: 700;
color: var(--clr-text-muted);
text-transform: uppercase;
letter-spacing: 0.08em;
margin-block-end: var(--space-sm);
}
.code-label::before {
content: '';
inline-size: 10px;
block-size: 10px;
border-radius: 50%;
background: var(--clr-primary);
}
}
/* ========== @layer utilities - 工具类 ========== */
@layer utilities {
.flex { display: flex; }
.flex-wrap { flex-wrap: wrap; }
.items-center { align-items: center; }
.justify-between { justify-content: space-between; }
.gap-sm { gap: var(--space-sm); }
.gap-md { gap: var(--space-md); }
.gap-lg { gap: var(--space-lg); }
.text-center { text-align: center; }
.text-muted { color: var(--clr-text-muted); }
.mt-lg { margin-block-start: var(--space-lg); }
.mb-lg { margin-block-end: var(--space-lg); }
.p-lg { padding: var(--space-lg); }
.hidden { display: none !important; }
.sr-only {
position: absolute;
inline-size: 1px;
block-size: 1px;
padding: 0;
margin: -1px;
overflow: hidden;
clip: rect(0,0,0,0);
white-space: nowrap;
border: 0;
}
}
/* ========== @layer animations - 动画 ========== */
@layer animations {
/* --- @keyframes 关键帧动画 --- */
@keyframes fadeIn {
from { opacity: 0; transform: translateY(20px); }
to { opacity: 1; transform: translateY(0); }
}
@keyframes pulse {
0%, 100% { transform: scale(1); }
50% { transform: scale(1.08); }
}
@keyframes spin {
from { transform: rotate(0deg); }
to { transform: rotate(360deg); }
}
@keyframes gradientShift {
0% { background-position: 0% 50%; }
50% { background-position: 100% 50%; }
100% { background-position: 0% 50%; }
}
@keyframes bounce {
0%, 100% { transform: translateY(0); }
40% { transform: translateY(-20px); }
60% { transform: translateY(-10px); }
}
@keyframes shimmer {
0% { background-position: -200% 0; }
100% { background-position: 200% 0; }
}
/* 使用 CSS 动画的应用 */
.animate-fade-in {
animation: fadeIn 0.8s ease-out both;
}
.animate-pulse {
animation: pulse 2s ease-in-out infinite;
}
.animate-spin {
animation: spin 1.5s linear infinite;
}
.animate-gradient {
background-size: 300% 300%;
animation: gradientShift 4s ease-in-out infinite;
}
.animate-bounce {
animation: bounce 1.5s ease-in-out infinite;
}
/* --- 滚动驱动动画 (Scroll-Driven Animations) --- */
@supports (animation-timeline: view()) {
.scroll-reveal {
animation: fadeIn 1s ease-out both;
animation-timeline: view();
animation-range: entry 0% entry 60%;
}
.scroll-progress-bar {
animation: scrollProgress 1s linear both;
animation-timeline: scroll(root);
transform-origin: 0 50%;
}
}
@keyframes scrollProgress {
from { transform: scaleX(0); }
to { transform: scaleX(1); }
}
/* --- 视图过渡 (View Transitions) --- */
@view-transition {
navigation: auto;
}
}
/* ========== 更多高级 CSS 特性演示 ========== */
/* 使用 @supports 进行特性检测 */
@supports (display: grid) {
.grid-demo {
display: grid;
}
}
/* @container - 容器查询 */
.container-query-demo {
container-type: inline-size;
}
@container (min-width: 500px) {
.container-query-demo .cq-item {
flex-direction: row;
font-size: 1.2em;
}
}
/* 子网格 (Subgrid) */
.subgrid-demo {
display: grid;
grid-template-columns: repeat(3, 1fr);
gap: var(--space-md);
}
.subgrid-item {
display: grid;
grid-template-rows: subgrid;
grid-row: span 2;
}
/* 逻辑属性示例 */
.logical-props-demo {
margin-inline: var(--space-lg);
padding-block: var(--space-md);
border-inline-start: 4px solid var(--clr-primary);
border-inline-end: 4px solid var(--clr-secondary);
border-block-start: 2px dashed var(--clr-accent);
border-block-end: 2px dashed var(--clr-success);
writing-mode: horizontal-tb;
}
/* 书写模式 */
.writing-mode-vertical {
writing-mode: vertical-rl;
text-orientation: mixed;
block-size: 200px;
padding: var(--space-md);
border: 1px solid var(--clr-border);
border-radius: var(--radius-md);
}
/* 多列布局 */
.multi-column {
column-count: 3;
column-gap: var(--space-xl);
column-rule: 1px solid var(--clr-border);
column-width: 200px;
}
/* 文本溢出 */
.text-ellipsis {
white-space: nowrap;
overflow: hidden;
text-overflow: ellipsis;
max-inline-size: 200px;
}
.text-clamp {
display: -webkit-box;
-webkit-line-clamp: 3;
-webkit-box-orient: vertical;
overflow: hidden;
}
/* 滤镜 */
.filter-demo img {
filter: grayscale(50%) brightness(1.1) contrast(1.1);
transition: filter var(--transition-base);
}
.filter-demo img:hover {
filter: none;
}
/* 混合模式 */
.blend-demo {
background: linear-gradient(135deg, var(--clr-primary), var(--clr-accent));
mix-blend-mode: screen;
border-radius: var(--radius-md);
padding: var(--space-lg);
}
/* clip-path 裁剪 */
.clip-path-demo {
clip-path: polygon(0 0, 100% 10%, 90% 100%, 10% 90%);
background: linear-gradient(135deg, var(--clr-primary), var(--clr-secondary));
padding: var(--space-xl);
border-radius: var(--radius-md);
}
/* mask 遮罩 */
.mask-demo {
-webkit-mask: radial-gradient(circle at center, black 40%, transparent 70%);
mask: radial-gradient(circle at center, black 40%, transparent 70%);
}
/* CSS 嵌套 */
.nested-demo {
background: var(--clr-surface);
padding: var(--space-lg);
border-radius: var(--radius-md);
&:hover {
background: var(--clr-surface-hover);
& .nested-child {
color: var(--clr-primary);
}
}
.nested-child {
font-weight: 600;
color: var(--clr-text-muted);
transition: color var(--transition-fast);
}
}
/* :has() 选择器 */
.form-group:has(input:focus) {
border-color: var(--clr-primary);
box-shadow: var(--shadow-glow);
}
.card:has(> .card-icon) {
padding-inline-start: var(--space-xl);
}
.parent:has(> .child.active) {
background: var(--clr-primary-soft);
}
/* 滚动吸附 */
.scroll-snap-container {
display: flex;
overflow-x: auto;
scroll-snap-type: x mandatory;
gap: var(--space-md);
padding-block: var(--space-md);
scroll-padding-inline: var(--space-md);
}
.scroll-snap-item {
scroll-snap-align: center;
flex-shrink: 0;
min-inline-size: 200px;
padding: var(--space-xl);
background: var(--clr-surface-2);
border-radius: var(--radius-lg);
border: 1px solid var(--clr-border);
}
/* 锚点定位 */
@supports (position-anchor: --anchor-el) {
.anchor-target {
position: absolute;
position-anchor: --anchor-el;
top: anchor(bottom);
left: anchor(center);
background: var(--clr-surface-2);
padding: var(--space-md);
border-radius: var(--radius-md);
box-shadow: var(--shadow-lg);
}
}
/* 表格响应式 */
.table-wrapper {
overflow-x: auto;
-webkit-overflow-scrolling: touch;
}
table {
inline-size: 100%;
border-collapse: collapse;
border-spacing: 0;
}
th, td {
padding: var(--space-sm) var(--space-md);
text-align: start;
border-block-end: 1px solid var(--clr-border);
}
th {
font-weight: 700;
background: var(--clr-surface-2);
position: sticky;
top: 0;
}
tbody tr:hover {
background: var(--clr-primary-soft);
}
caption {
caption-side: top;
font-weight: 700;
margin-block-end: var(--space-sm);
}
/* 表单样式 */
input, select, textarea {
background: var(--clr-surface-2);
border: 2px solid var(--clr-border);
border-radius: var(--radius-sm);
padding: var(--space-sm) var(--space-md);
color: var(--clr-text);
transition: border-color var(--transition-fast), box-shadow var(--transition-fast);
inline-size: 100%;
max-inline-size: 400px;
}
input:focus, select:focus, textarea:focus {
outline: none;
border-color: var(--clr-primary);
box-shadow: 0 0 0 3px var(--clr-primary-soft);
}
input:invalid {
border-color: var(--clr-danger);
}
input:valid {
border-color: var(--clr-success);
}
input:disabled {
opacity: 0.5;
cursor: not-allowed;
}
input:read-only {
background: var(--clr-surface);
}
::placeholder {
color: var(--clr-text-muted);
opacity: 0.7;
}
/* 下拉选择器 */
select {
appearance: none;
background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='12' height='12' viewBox='0 0 12 12'%3E%3Cpath fill='%23888' d='M6 8L1 3h10z'/%3E%3C/svg%3E");
background-repeat: no-repeat;
background-position: right 12px center;
padding-inline-end: 32px;
}
/* 复选框和单选框自定义 */
input[type="checkbox"], input[type="radio"] {
inline-size: auto;
appearance: none;
-webkit-appearance: none;
inline-size: 20px;
block-size: 20px;
border: 2px solid var(--clr-border);
border-radius: var(--radius-sm);
cursor: pointer;
transition: all var(--transition-fast);
vertical-align: middle;
}
input[type="radio"] {
border-radius: 50%;
}
input[type="checkbox"]:checked, input[type="radio"]:checked {
background: var(--clr-primary);
border-color: var(--clr-primary);
position: relative;
}
input[type="checkbox"]:checked::after {
content: '✓';
color: oklch(0.1 0.02 260);
font-weight: 900;
display: flex;
justify-content: center;
align-items: center;
font-size: 14px;
}
input[type="radio"]:checked::after {
content: '';
position: absolute;
inset: 4px;
background: oklch(0.1 0.02 260);
border-radius: 50%;
}
/* range 滑块 */
input[type="range"] {
appearance: none;
-webkit-appearance: none;
inline-size: 100%;
max-inline-size: 300px;
block-size: 6px;
background: var(--clr-border);
border-radius: var(--radius-full);
border: none;
padding: 0;
}
input[type="range"]::-webkit-slider-thumb {
-webkit-appearance: none;
inline-size: 22px;
block-size: 22px;
border-radius: 50%;
background: var(--clr-primary);
cursor: pointer;
border: 3px solid var(--clr-bg);
box-shadow: var(--shadow-sm);
}
/* progress 进度条 */
progress {
appearance: none;
-webkit-appearance: none;
inline-size: 100%;
max-inline-size: 400px;
block-size: 10px;
border-radius: var(--radius-full);
overflow: hidden;
border: none;
background: var(--clr-surface-2);
}
progress::-webkit-progress-bar {
background: var(--clr-surface-2);
border-radius: var(--radius-full);
}
progress::-webkit-progress-value {
background: linear-gradient(90deg, var(--clr-primary), var(--clr-secondary));
border-radius: var(--radius-full);
}
progress::-moz-progress-bar {
background: linear-gradient(90deg, var(--clr-primary), var(--clr-secondary));
border-radius: var(--radius-full);
}
/* dialog 对话框 */
dialog {
background: var(--clr-surface);
color: var(--clr-text);
border: 1px solid var(--clr-border);
border-radius: var(--radius-lg);
padding: var(--space-xl);
box-shadow: var(--shadow-lg);
max-inline-size: 500px;
inline-size: 90%;
}
dialog::backdrop {
background: oklch(0 0 0 / 0.7);
backdrop-filter: blur(5px);
}
/* details/summary */
details {
border: 1px solid var(--clr-border);
border-radius: var(--radius-md);
padding: var(--space-md);
margin-block-end: var(--space-sm);
}
summary {
font-weight: 700;
cursor: pointer;
user-select: none;
transition: color var(--transition-fast);
}
summary:hover {
color: var(--clr-primary);
}
summary::marker {
color: var(--clr-primary);
}
details[open] {
background: var(--clr-surface-2);
}
/* 图片 object-fit */
.object-fit-demo img {
inline-size: 100%;
block-size: 200px;
object-fit: cover;
object-position: center 30%;
border-radius: var(--radius-md);
}
/* aspect-ratio 宽高比 */
.aspect-ratio-demo {
aspect-ratio: 16/9;
background: linear-gradient(135deg, var(--clr-primary-soft), var(--clr-surface-2));
border-radius: var(--radius-md);
display: flex;
align-items: center;
justify-content: center;
}
/* CSS Grid 高级用法 */
.grid-advanced {
display: grid;
grid-template-columns: repeat(auto-fill, minmax(250px, 1fr));
grid-auto-rows: minmax(100px, auto);
gap: var(--space-md);
}
.grid-item {
background: var(--clr-surface-2);
padding: var(--space-lg);
border-radius: var(--radius-md);
border: 1px solid var(--clr-border);
transition: all var(--transition-base);
}
.grid-item:hover {
background: var(--clr-surface-hover);
transform: scale(1.02);
box-shadow: var(--shadow-md);
}
.grid-item-wide {
grid-column: span 2;
}
.grid-item-tall {
grid-row: span 2;
}
/* Flexbox 高级用法 */
.flex-advanced {
display: flex;
flex-wrap: wrap;
gap: var(--space-md);
align-items: stretch;
}
.flex-item {
flex: 1 1 200px;
background: var(--clr-surface-2);
padding: var(--space-lg);
border-radius: var(--radius-md);
border: 1px solid var(--clr-border);
}
.flex-item-grow {
flex-grow: 3;
}
.flex-item-shrink {
flex-shrink: 0;
flex-basis: 150px;
}
/* 定位示例 */
.position-demo {
position: relative;
block-size: 250px;
background: var(--clr-surface-2);
border-radius: var(--radius-md);
overflow: hidden;
border: 1px solid var(--clr-border);
}
.position-static { position: static; }
.position-relative { position: relative; inset-inline-start: 20px; inset-block-start: 10px; }
.position-absolute { position: absolute; inset-block-start: 20px; inset-inline-end: 20px; }
.position-fixed { position: fixed; inset-block-end: 20px; inset-inline-end: 20px; z-index: 50; }
.position-sticky { position: sticky; inset-block-start: 100px; }
/* 浮动 */
.float-demo {
background: var(--clr-surface-2);
border-radius: var(--radius-md);
padding: var(--space-lg);
overflow: hidden;
}
.float-left {
float: inline-start;
margin-inline-end: var(--space-md);
margin-block-end: var(--space-sm);
inline-size: 120px;
block-size: 80px;
background: var(--clr-primary-soft);
border-radius: var(--radius-sm);
display: flex;
align-items: center;
justify-content: center;
}
.float-right {
float: inline-end;
margin-inline-start: var(--space-md);
margin-block-end: var(--space-sm);
inline-size: 120px;
block-size: 80px;
background: color-mix(in oklch, var(--clr-accent) 30%, transparent);
border-radius: var(--radius-sm);
display: flex;
align-items: center;
justify-content: center;
}
/* 渐变背景 */
.gradient-demo {
background:
radial-gradient(circle at 20% 30%, var(--clr-gradient-1) 0%, transparent 50%),
radial-gradient(circle at 80% 70%, var(--clr-gradient-2) 0%, transparent 50%),
linear-gradient(135deg, var(--clr-surface) 0%, var(--clr-surface-2) 100%);
background-size: 300% 300%;
animation: gradientShift 5s ease-in-out infinite;
padding: var(--space-xl);
border-radius: var(--radius-lg);
text-align: center;
}
/* conic-gradient 圆锥渐变 */
.conic-gradient-demo {
inline-size: 150px;
block-size: 150px;
border-radius: 50%;
background: conic-gradient(from 0deg,
var(--clr-primary), var(--clr-secondary),
var(--clr-accent), var(--clr-success),
var(--clr-primary));
margin: var(--space-md) auto;
}
/* 文本阴影 */
.text-shadow-demo {
text-shadow:
2px 2px 0 oklch(0.7 0.15 200 / 0.5),
-2px -2px 0 oklch(0.7 0.18 40 / 0.5),
4px 4px 8px oklch(0 0 0 / 0.4);
font-size: var(--text-2xl);
font-weight: 900;
}
/* 3D 变换 */
.transform-3d-demo {
perspective: 500px;
}
.transform-3d-demo .cube {
inline-size: 100px;
block-size: 100px;
background: linear-gradient(135deg, var(--clr-primary), var(--clr-secondary));
border-radius: var(--radius-md);
transform: rotateX(25deg) rotateY(35deg);
transition: transform var(--transition-slow);
margin: var(--space-lg) auto;
}
.transform-3d-demo .cube:hover {
transform: rotateX(0deg) rotateY(0deg) rotateZ(45deg) scale(1.1);
}
/* 响应式图片 */
picture, figure {
margin-block-end: var(--space-md);
}
figcaption {
font-size: var(--text-sm);
color: var(--clr-text-muted);
text-align: center;
margin-block-start: var(--space-sm);
}
/* 工具提示 */
.tooltip {
position: relative;
cursor: help;
border-block-end: 2px dotted var(--clr-primary);
}
.tooltip::after {
content: attr(data-tooltip);
position: absolute;
inset-block-end: 100%;
inset-inline-start: 50%;
transform: translateX(-50%) translateY(8px);
background: var(--clr-surface-2);
color: var(--clr-text);
padding: var(--space-sm) var(--space-md);
border-radius: var(--radius-sm);
font-size: var(--text-xs);
white-space: nowrap;
opacity: 0;
pointer-events: none;
transition: opacity var(--transition-fast), transform var(--transition-fast);
box-shadow: var(--shadow-md);
z-index: 10;
}
.tooltip:hover::after {
opacity: 1;
transform: translateX(-50%) translateY(0);
}
/* 首字母和首行 */
.first-letter-demo::first-letter {
font-size: 3em;
font-weight: 900;
color: var(--clr-primary);
float: inline-start;
margin-inline-end: var(--space-sm);
line-height: 1;
}
.first-line-demo::first-line {
font-weight: 700;
color: var(--clr-secondary);
}
/* 计数器 */
.counter-list {
counter-reset: section-counter;
list-style: none;
padding: 0;
}
.counter-list li {
counter-increment: section-counter;
padding-inline-start: var(--space-lg);
position: relative;
margin-block-end: var(--space-sm);
}
.counter-list li::before {
content: counter(section-counter) ". ";
font-weight: 700;
color: var(--clr-primary);
position: absolute;
inset-inline-start: 0;
}
/* 自定义滚动条区域 */
.custom-scroll {
max-block-size: 300px;
overflow-y: auto;
scrollbar-width: thin;
scrollbar-color: var(--clr-primary) var(--clr-surface-2);
}
.custom-scroll::-webkit-scrollbar {
inline-size: 6px;
}
.custom-scroll::-webkit-scrollbar-track {
background: var(--clr-surface-2);
border-radius: var(--radius-full);
}
.custom-scroll::-webkit-scrollbar-thumb {
background: var(--clr-primary);
border-radius: var(--radius-full);
}
/* content-visibility */
.content-visibility-demo {
content-visibility: auto;
contain-intrinsic-size: 200px;
}
/* 媒体查询示例 */
@media (max-width: 768px) {
.grid-advanced {
grid-template-columns: 1fr;
}
.multi-column {
column-count: 1;
}
.nav-links {
display: none;
}
.card {
padding: var(--space-md);
}
.site-header {
padding-inline: var(--space-md);
}
}
@media (min-width: 769px) and (max-width: 1200px) {
.grid-advanced {
grid-template-columns: repeat(2, 1fr);
}
}
@media (min-width: 1200px) {
.grid-advanced {
grid-template-columns: repeat(3, 1fr);
}
}
@media (max-width: 480px) {
:root {
--space-xl: 1.2rem;
--space-lg: 1rem;
--space-md: 0.8rem;
}
body {
font-size: 0.9rem;
}
}
@media print {
.site-header, .btn, .tooltip {
display: none !important;
}
body {
background: white;
color: black;
}
.card {
break-inside: avoid;
box-shadow: none;
}
}
@media (prefers-reduced-motion: reduce) {
*, *::before, *::after {
animation-duration: 0.01ms !important;
animation-iteration-count: 1 !important;
transition-duration: 0.01ms !important;
scroll-behavior: auto !important;
}
}
@media (prefers-contrast: high) {
:root {
--clr-border: oklch(0.5 0.05 260);
--clr-text: oklch(0.1 0.02 260);
--clr-bg: oklch(0.98 0.01 260);
}
}
</style>
</head>
<body>
<!-- ========== 滚动进度条 ========== -->
<div class="scroll-progress-bar" style="position: fixed; inset-block-start: 0; inset-inline-start: 0; inline-size: 100%; block-size: 4px; background: linear-gradient(90deg, var(--clr-primary), var(--clr-secondary), var(--clr-accent)); z-index: 9999; transform-origin: 0 50%;"></div>
<!-- ========== 页头 (语义化 header) ========== -->
<header class="site-header" role="banner">
<div class="logo" aria-label="前端学习全景图">📚 前端学习全景图</div>
<nav aria-label="主导航" role="navigation">
<ul class="nav-links">
<li><a href="#html-basics">HTML基础</a></li>
<li><a href="#css-selectors">CSS选择器</a></li>
<li><a href="#box-model">盒模型</a></li>
<li><a href="#layout">布局</a></li>
<li><a href="#animations">动画</a></li>
<li><a href="#modern-css">现代CSS</a></li>
<li><a href="#responsive">响应式</a></li>
</ul>
</nav>
</header>
<!-- ========== 主体内容 ========== -->
<main class="container" role="main">
<!-- ==========================================
英雄区域 - Hero Section
========================================== -->
<section class="card animate-fade-in gradient-demo" style="text-align: center; margin-block-start: var(--space-xl);" aria-label="欢迎区域">
<h1 style="font-size: var(--text-3xl); font-weight: 900;">
🌐 前端学习全景图
</h1>
<p style="font-size: var(--text-lg); color: var(--clr-text-muted);">
涵盖 <strong>HTML5</strong> 全部语义化标签与 <strong>CSS3+ 现代特性</strong> —
从选择器到容器查询,从Flex到Grid,从过渡到滚动驱动动画。
</p>
<div class="flex flex-wrap gap-md items-center justify-between" style="margin-block-start: var(--space-lg);">
<span class="badge">HTML5 语义化</span>
<span class="badge accent">CSS Grid + Subgrid</span>
<span class="badge success">Flexbox</span>
<span class="badge warning">容器查询</span>
<span class="badge">级联层 @layer</span>
<span class="badge accent">嵌套CSS</span>
<span class="badge success">:has() 选择器</span>
<span class="badge warning">滚动驱动动画</span>
</div>
<div style="margin-block-start: var(--space-lg); display: flex; gap: var(--space-md); justify-content: center; flex-wrap: wrap;">
<button class="btn" onclick="document.getElementById('demo-dialog').showModal();">打开对话框</button>
<button class="btn btn-outline" onclick="document.getElementById('popover-demo').togglePopover();">切换 Popover</button>
<a class="btn btn-outline" href="#html-basics">开始学习 ↓</a>
</div>
</section>
<!-- ==========================================
一、HTML 基础知识
========================================== -->
<section id="html-basics" class="scroll-reveal" aria-label="HTML基础知识">
<h2>📄 一、HTML 核心知识点</h2>
<p class="text-muted">语义化标签、文档结构、文本、列表、表格、表单、多媒体等</p>
<!-- 语义化标签 -->
<div class="card">
<h3>1.1 语义化标签 <span class="badge">Semantic HTML</span></h3>
<p>使用 <code><header></code> <code><nav></code> <code><main></code> <code><section></code> <code><article></code> <code><aside></code> <code><footer></code> 等标签构建清晰的文档结构。</p>
<div style="display: grid; gap: var(--space-sm); margin-block-start: var(--space-md);">
<header style="background: var(--clr-primary-soft); padding: var(--space-md); border-radius: var(--radius-sm); text-align: center; font-weight: 700;"><header> 页头</header>
<nav style="background: color-mix(in oklch, var(--clr-secondary) 20%, transparent); padding: var(--space-md); border-radius: var(--radius-sm); text-align: center; font-weight: 700;"><nav> 导航</nav>
<div style="display: grid; grid-template-columns: 2fr 1fr; gap: var(--space-sm);">
<main style="background: color-mix(in oklch, var(--clr-success) 20%, transparent); padding: var(--space-md); border-radius: var(--radius-sm); text-align: center; min-block-size: 100px; display: flex; align-items: center; justify-content: center; font-weight: 700;"><main> 主内容区</main>
<aside style="background: color-mix(in oklch, var(--clr-accent) 20%, transparent); padding: var(--space-md); border-radius: var(--radius-sm); text-align: center; display: flex; align-items: center; justify-content: center; font-weight: 700;"><aside> 侧栏</aside>
</div>
<footer style="background: var(--clr-surface-2); padding: var(--space-md); border-radius: var(--radius-sm); text-align: center; font-weight: 700;"><footer> 页脚</footer>
</div>
</div>
<!-- 文本标签 -->
<div class="card">
<h3>1.2 文本级标签 <span class="badge">Text Elements</span></h3>
<p>示例文本展示各种文本标签:</p>
<p>
<strong><strong> 重要文本</strong> |
<em><em> 强调文本</em> |
<mark><mark> 高亮文本</mark> |
<del><del> 删除文本</del> |
<ins><ins> 插入文本</ins> |
<sub><sub> 下标</sub> |
<sup><sup> 上标</sup> |
<small><small> 小字</small> |
<abbr title="HyperText Markup Language"><abbr> 缩写</abbr> |
<cite><cite> 引用</cite> |
<q><q> 短引用</q> |
<code><code> 代码</code> |
<kbd><kbd> 键盘输入</kbd> |
<samp><samp> 输出</samp> |
<var><var> 变量</var> |
<time datetime="2024-01-15"><time> 时间</time> |
<bdo dir="rtl"><bdo> 文字方向</bdo> |
<bdi><bdi> 隔离文本</bdi>
</p>
<p>这是 <span style="color: var(--clr-primary); font-weight: 700;"><span> 通用行内容器</span> 和 <div style="background: var(--clr-primary-soft); padding: var(--space-sm); border-radius: var(--radius-sm); display: inline-block; margin-inline-start: var(--space-sm);"><div> 通用块容器</div></p>
<p>使用 <code><blockquote></code> 创建引用块:</p>
<blockquote style="border-inline-start: 4px solid var(--clr-primary); padding-inline-start: var(--space-md); color: var(--clr-text-muted); font-style: italic;">
学而不思则罔,思而不学则殆。—— <cite>《论语》</cite>
</blockquote>
<p>使用 <code><pre></code> 保留格式:</p>
<pre> function hello() {
console.log("Hello, World!");
}</pre>
</div>
<!-- 列表 -->
<div class="card">
<h3>1.3 列表 <span class="badge">Lists</span></h3>
<div style="display: grid; grid-template-columns: repeat(auto-fit, minmax(250px, 1fr)); gap: var(--space-lg);">
<div>
<h4><ul> 无序列表</h4>
<ul>
<li>列表项 1</li>
<li>列表项 2
<ul>
<li>嵌套列表 2.1</li>
<li>嵌套列表 2.2</li>
</ul>
</li>
<li>列表项 3</li>
</ul>
</div>
<div>
<h4><ol> 有序列表</h4>
<ol start="5" reversed>
<li>第 5 项(使用 start 属性)</li>
<li>第 4 项</li>
<li>第 3 项</li>
</ol>
<h4><dl> 描述列表</h4>
<dl>
<dt>HTML</dt>
<dd>超文本标记语言</dd>
<dt>CSS</dt>
<dd>层叠样式表</dd>
</dl>
</div>
</div>
</div>
<!-- 表格 -->
<div class="card">
<h3>1.4 表格 <span class="badge">Tables</span></h3>
<div class="table-wrapper">
<table>
<caption>前端技术对比表</caption>
<thead>
<tr>
<th scope="col">技术</th>
<th scope="col">类型</th>
<th scope="col">难度</th>
<th scope="col">流行度</th>
</tr>
</thead>
<tbody>
<tr>
<th scope="row">HTML5</th>
<td>标记语言</td>
<td>⭐</td>
<td>⭐⭐⭐⭐⭐</td>
</tr>
<tr>
<th scope="row">CSS3</th>
<td>样式语言</td>
<td>⭐⭐⭐</td>
<td>⭐⭐⭐⭐⭐</td>
</tr>
<tr>
<th scope="row">JavaScript</th>
<td>编程语言</td>
<td>⭐⭐⭐⭐</td>
<td>⭐⭐⭐⭐⭐</td>
</tr>
</tbody>
<tfoot>
<tr>
<td colspan="4" style="text-align: center; font-style: italic;">数据更新于 2024年</td>
</tr>
</tfoot>
</table>
</div>
</div>
<!-- 表单 -->
<div class="card">
<h3>1.5 表单 <span class="badge">Forms</span></h3>
<form onsubmit="event.preventDefault(); alert('表单已提交(演示)');" aria-label="演示表单">
<fieldset style="border: 1px solid var(--clr-border); border-radius: var(--radius-md); padding: var(--space-lg);">
<legend>📝 演示表单</legend>
<div class="form-group" style="margin-block-end: var(--space-md);">
<label for="name">姓名:</label>
<input type="text" id="name" name="name" placeholder="请输入姓名" required autocomplete="name">
</div>
<div class="form-group" style="margin-block-end: var(--space-md);">
<label for="email">邮箱:</label>
<input type="email" id="email" name="email" placeholder="example@mail.com" required>
</div>
<div class="form-group" style="margin-block-end: var(--space-md);">
<label for="password">密码:</label>
<input type="password" id="password" name="password" minlength="8" required placeholder="至少8位">
</div>
<div class="form-group" style="margin-block-end: var(--space-md);">
<label for="age">年龄:</label>
<input type="number" id="age" name="age" min="1" max="150" value="25">
</div>
<div class="form-group" style="margin-block-end: var(--space-md);">
<label for="date">日期:</label>
<input type="date" id="date" name="date">
</div>
<div class="form-group" style="margin-block-end: var(--space-md);">
<label for="color">颜色选择:</label>
<input type="color" id="color" name="color" value="#4a9eff">
</div>
<div class="form-group" style="margin-block-end: var(--space-md);">
<label for="range">范围滑块:</label>
<input type="range" id="range" name="range" min="0" max="100" value="60">
<output for="range">60</output>
</div>
<div class="form-group" style="margin-block-end: var(--space-md);">
<label for="file">文件上传:</label>
<input type="file" id="file" name="file" accept="image/*,.pdf">
</div>
<div class="form-group" style="margin-block-end: var(--space-md);">
<label for="search">搜索:</label>
<input type="search" id="search" name="search" placeholder="搜索...">
</div>
<div class="form-group" style="margin-block-end: var(--space-md);">
<label for="phone">电话:</label>
<input type="tel" id="phone" name="phone" pattern="[0-9]{11}" placeholder="11位手机号">
</div>
<div class="form-group" style="margin-block-end: var(--space-md);">
<label for="url">网址:</label>
<input type="url" id="url" name="url" placeholder="https://...">
</div>
<div class="form-group" style="margin-block-end: var(--space-md); display: flex; gap: var(--space-md); flex-wrap: wrap;">
<label><input type="checkbox" checked> 复选框 1</label>
<label><input type="checkbox"> 复选框 2</label>
<label><input type="radio" name="radio-group" checked> 单选 1</label>
<label><input type="radio" name="radio-group"> 单选 2</label>
</div>
<div class="form-group" style="margin-block-end: var(--space-md);">
<label for="select">下拉选择:</label>
<select id="select" name="select">
<option value="">请选择</option>
<option value="html">HTML</option>
<option value="css">CSS</option>
<option value="js">JavaScript</option>
<optgroup label="框架">
<option value="react">React</option>
<option value="vue">Vue</option>
</optgroup>
</select>
</div>
<div class="form-group" style="margin-block-end: var(--space-md);">
<label for="textarea">多行文本:</label>
<textarea id="textarea" name="textarea" rows="4" placeholder="请输入多行文本..."></textarea>
</div>
<div class="form-group" style="margin-block-end: var(--space-md);">
<label for="progress">进度条:</label>
<progress id="progress" value="70" max="100">70%</progress>
<meter value="0.7" min="0" max="1" style="margin-inline-start: var(--space-md);">70%</meter>
</div>
<div style="display: flex; gap: var(--space-md); flex-wrap: wrap;">
<button type="submit" class="btn">提交</button>
<button type="reset" class="btn btn-outline">重置</button>
<button type="button" class="btn btn-outline" disabled>禁用按钮</button>
</div>
</fieldset>
</form>
</div>
<!-- 多媒体 -->
<div class="card">
<h3>1.6 多媒体 <span class="badge">Media</span></h3>
<!-- 响应式图片 -->
<h4><picture> 响应式图片</h4>
<picture>
<source media="(min-width: 1200px)" srcset="https://picsum.photos/seed/large/1200/400" type="image/webp">
<source media="(min-width: 768px)" srcset="https://picsum.photos/seed/medium/800/300">
<img src="https://picsum.photos/seed/small/400/200" alt="响应式图片示例" loading="lazy" decoding="async">
</picture>
<figcaption>📸 使用 <picture> 和 <source> 实现响应式图片</figcaption>
<!-- Figure -->
<figure>
<img src="https://picsum.photos/seed/figure/300/200" alt="Figure 示例" loading="lazy" width="300" height="200">
<figcaption><figure> + <figcaption> 图文组合</figcaption>
</figure>
<!-- 音频 -->
<h4><audio> 音频</h4>
<audio controls preload="metadata" style="inline-size: 100%; max-inline-size: 400px;">
<source src="https://www.w3schools.com/html/horse.mp3" type="audio/mpeg">
您的浏览器不支持 audio 元素。
</audio>
<!-- 视频 -->
<h4><video> 视频</h4>
<video controls width="400" poster="https://picsum.photos/seed/video/400/225" preload="metadata">
<source src="https://www.w3schools.com/html/mov_bbb.mp4" type="video/mp4">
您的浏览器不支持 video 元素。
</video>
<!-- Canvas -->
<h4><canvas> 画布</h4>
<canvas id="demo-canvas" width="300" height="150" style="border: 1px solid var(--clr-border); border-radius: var(--radius-sm);"></canvas>
<!-- SVG -->
<h4><svg> 矢量图形</h4>
<svg width="200" height="100" viewBox="0 0 200 100" aria-label="SVG 示例">
<rect x="10" y="20" width="50" height="50" rx="8" fill="var(--clr-primary)" />
<circle cx="100" cy="45" r="30" fill="var(--clr-secondary)" />
<polygon points="150,20 180,20 170,70 140,70" fill="var(--clr-accent)" />
<text x="90" y="90" font-size="12" fill="var(--clr-text)" text-anchor="middle">SVG 图形</text>
</svg>
</div>
<!-- 交互元素 -->
<div class="card">
<h3>1.7 交互元素 <span class="badge">Interactive</span></h3>
<!-- details/summary -->
<details>
<summary>点击展开 — <details> 和 <summary></summary>
<p>这是展开后的内容。使用了 HTML5 的详情披露组件。</p>
</details>
<details open>
<summary>默认展开的详情</summary>
<p>这个 details 元素使用了 open 属性,默认展开。</p>
</details>
<!-- dialog -->
<dialog id="demo-dialog" aria-label="演示对话框">
<h3 style="margin-block-start: 0;">📦 原生对话框</h3>
<p>这是使用 <dialog> 元素创建的原生对话框。</p>
<div style="display: flex; gap: var(--space-md); justify-content: flex-end;">
<button class="btn btn-outline" onclick="document.getElementById('demo-dialog').close();">关闭</button>
</div>
</dialog>
<!-- Popover -->
<div id="popover-demo" popover style="background: var(--clr-surface); border: 1px solid var(--clr-border); border-radius: var(--radius-md); padding: var(--space-lg); box-shadow: var(--shadow-lg); max-inline-size: 300px;">
<p>💡 这是使用 popover 属性创建的原生弹出层!</p>
</div>
<!-- 自定义数据属性 -->
<div data-custom-value="这是自定义数据" data-id="123" style="margin-block-start: var(--space-md);">
<p><code>data-*</code> 自定义数据属性:<span class="tooltip" data-tooltip="通过 data-tooltip 属性实现纯 CSS 工具提示">悬停查看提示</span></p>
</div>
<!-- contenteditable -->
<div contenteditable="true" style="border: 2px dashed var(--clr-border); border-radius: var(--radius-md); padding: var(--space-md); margin-block-start: var(--space-md);" aria-label="可编辑区域">
✏️ 这是一个 <strong>contenteditable</strong> 元素 — 点击即可编辑此文本!
</div>
<!-- draggable -->
<div draggable="true" style="background: var(--clr-surface-2); border: 1px solid var(--clr-border); border-radius: var(--radius-sm); padding: var(--space-sm); margin-block-start: var(--space-sm); cursor: grab; text-align: center;">
🖐️ 这是一个 <strong>draggable</strong> 元素
</div>
</div>
</section>
<!-- ==========================================
二、CSS 选择器
========================================== -->
<section id="css-selectors" class="scroll-reveal" aria-label="CSS选择器">
<h2>🎯 二、CSS 选择器大全</h2>
<p class="text-muted">从基础选择器到现代 :has() 和伪元素</p>
<div class="card">
<h3>2.1 基础选择器</h3>
<div class="grid-advanced">
<div class="grid-item">
<h4>元素选择器</h4>
<code>p { color: red; }</code>
<p style="color: var(--clr-danger);">这是 p 元素</p>
</div>
<div class="grid-item">
<h4>类选择器</h4>
<code>.highlight { ... }</code>
<p><span style="background: var(--clr-primary-soft); padding: 0.2em 0.5em; border-radius: var(--radius-sm);">类选择器效果</span></p>
</div>
<div class="grid-item">
<h4>ID 选择器</h4>
<code>#unique { ... }</code>
<p id="unique-id" style="font-weight: 900; color: var(--clr-accent);">ID 选择器效果</p>
</div>
<div class="grid-item">
<h4>通配符选择器</h4>
<code>* { margin: 0; }</code>
<p>选择所有元素</p>
</div>
<div class="grid-item">
<h4>属性选择器</h4>
<code>[data-type="demo"]</code>
<p><span data-type="demo" style="background: var(--clr-success); padding: 0.2em 0.5em; border-radius: var(--radius-sm); color: oklch(0.1 0.02 260);">[data-type="demo"]</span></p>
<p><code>[href^="https"]</code> 以...开头 | <code>[href$=".pdf"]</code> 以...结尾 | <code>[class*="btn"]</code> 包含</p>
</div>
</div>
</div>
<div class="card">
<h3>2.2 组合选择器</h3>
<div class="grid-advanced">
<div class="grid-item">
<h4>后代选择器</h4>
<code>.parent .child { }</code>
<div style="border: 1px solid var(--clr-border); padding: var(--space-sm); border-radius: var(--radius-sm);">
外层
<div style="margin-inline-start: var(--space-md); color: var(--clr-primary);">内层(后代)</div>
</div>
</div>
<div class="grid-item">
<h4>子代选择器</h4>
<code>.parent > .child { }</code>
<p>只选择直接子元素</p>
</div>
<div class="grid-item">
<h4>相邻兄弟</h4>
<code>h4 + p { }</code>
<p>紧接在后的兄弟元素</p>
</div>
<div class="grid-item">
<h4>通用兄弟</h4>
<code>h4 ~ p { }</code>
<p>同一父元素下后续所有兄弟</p>
</div>
</div>
</div>
<div class="card">
<h3>2.3 伪类选择器 <span class="badge accent">Pseudo-classes</span></h3>
<div class="grid-advanced">
<div class="grid-item">
<h4>:hover / :active / :focus</h4>
<button class="btn" style="font-size: 0.8rem;">悬停/点击/聚焦</button>
</div>
<div class="grid-item">
<h4>:first-child / :last-child</h4>
<ul>
<li style="color: var(--clr-success); font-weight: 700;">第一个子元素 (:first-child)</li>
<li>中间子元素</li>
<li style="color: var(--clr-accent); font-weight: 700;">最后一个子元素 (:last-child)</li>
</ul>
</div>
<div class="grid-item">
<h4>:nth-child(n) / :nth-of-type(n)</h4>
<ul>
<li style="background: var(--clr-primary-soft);">nth-child(odd) 奇数</li>
<li>偶数</li>
<li style="background: var(--clr-primary-soft);">奇数</li>
<li>偶数</li>
</ul>
</div>
<div class="grid-item">
<h4>:not() 否定伪类</h4>
<p><span style="font-weight: 700;">:not(.excluded) 选中所有非该类的元素</span></p>
</div>
<div class="grid-item">
<h4>:is() / :where() 匹配伪类</h4>
<code>:is(h1, h2, h3) { margin: 0; }</code>
<p>零特异性(:where) vs 最高特异性(:is)</p>
</div>
<div class="grid-item">
<h4>:has() 关系伪类 <span class="badge">NEW!</span></h4>
<p><code>.card:has(> img) { }</code></p>
<div class="parent" style="border: 2px solid var(--clr-border); padding: var(--space-sm); border-radius: var(--radius-sm);">
<div class="child active" style="background: var(--clr-success); padding: var(--space-xs); border-radius: var(--radius-sm);">:has(.child.active) 选中此父元素</div>
</div>
</div>
<div class="grid-item">
<h4>:empty / :checked / :disabled</h4>
<input type="checkbox" checked> 已选中<br>
<input type="checkbox" disabled> 已禁用
</div>
<div class="grid-item">
<h4>:target / :focus-within / :focus-visible</h4>
<p><code>:focus-within</code> 当内部元素聚焦时</p>
<div class="form-group" style="padding: var(--space-sm); border: 2px solid var(--clr-border); border-radius: var(--radius-sm); transition: all var(--transition-fast);">
<input type="text" placeholder="聚焦此输入框试试 :focus-within" style="border: none; background: transparent; padding: 0;">
</div>
</div>
</div>
</div>
<div class="card">
<h3>2.4 伪元素 <span class="badge">Pseudo-elements</span></h3>
<div class="grid-advanced">
<div class="grid-item">
<h4>::before / ::after</h4>
<p><span style="position: relative; padding-inline-start: 20px;">::before 图标 →</span></p>
<p><span style="position: relative; padding-inline-end: 20px;">← ::after 图标</span></p>
</div>
<div class="grid-item">
<h4>::first-letter</h4>
<p class="first-letter-demo" style="font-size: 0.9rem;">首字母大写装饰效果,使用 ::first-letter 伪元素。</p>
</div>
<div class="grid-item">
<h4>::first-line</h4>
<p class="first-line-demo">使用 ::first-line 伪元素来改变第一行的样式。这一行会显示为粗体并使用不同的颜色。</p>
</div>
<div class="grid-item">
<h4>::selection</h4>
<p>选中此文本查看自定义选中颜色效果。</p>
</div>
<div class="grid-item">
<h4>::marker</h4>
<ul>
<li>自定义列表标记颜色</li>
<li>使用 ::marker 伪元素</li>
</ul>
</div>
<div class="grid-item">
<h4>::placeholder</h4>
<input type="text" placeholder="自定义占位符颜色" style="font-size: 0.85rem;">
</div>
</div>
</div>
</section>
<!-- ==========================================
三、盒模型
========================================== -->
<section id="box-model" class="scroll-reveal" aria-label="CSS盒模型">
<h2>📦 三、CSS 盒模型与定位</h2>
<div class="card">
<h3>3.1 盒模型 <span class="badge">Box Model</span></h3>
<p>内容(content) + 内边距(padding) + 边框(border) + 外边距(margin)</p>
<div style="display: flex; justify-content: center; margin: var(--space-xl) 0;">
<div style="background: var(--clr-accent); padding: 30px; border-radius: var(--radius-md);">
<div style="background: var(--clr-success); padding: 30px; border-radius: var(--radius-sm);">
<div style="background: var(--clr-primary); padding: 30px; border-radius: var(--radius-sm);">
<div style="background: var(--clr-surface); padding: 40px; border-radius: var(--radius-sm); text-align: center; font-weight: 700;">
content
</div>
</div>
</div>
</div>
</div>
<p><code>box-sizing: border-box</code> 是最常用的盒模型,使 padding 和 border 包含在总宽高内。</p>
<div style="display: grid; grid-template-columns: repeat(auto-fit, minmax(180px, 1fr)); gap: var(--space-md); text-align: center;">
<div style="background: var(--clr-surface-2); padding: var(--space-md); border-radius: var(--radius-sm); border: 4px solid var(--clr-primary); box-sizing: content-box;">
<code>box-sizing: content-box</code>
<p style="font-size: var(--text-xs); margin-block-start: var(--space-xs);">宽高不含 padding/border</p>
</div>
<div style="background: var(--clr-surface-2); padding: var(--space-md); border-radius: var(--radius-sm); border: 4px solid var(--clr-secondary); box-sizing: border-box;">
<code>box-sizing: border-box</code>
<p style="font-size: var(--text-xs); margin-block-start: var(--space-xs);">宽高含 padding/border</p>
</div>
</div>
</div>
<div class="card">
<h3>3.2 定位 <span class="badge">Positioning</span></h3>
<div class="position-demo" style="margin-block-end: var(--space-lg);">
<div class="position-static" style="background: var(--clr-surface-2); padding: var(--space-sm); border-radius: var(--radius-sm); display: inline-block; margin: var(--space-sm);">static</div>
<div class="position-relative" style="background: var(--clr-primary-soft); padding: var(--space-sm); border-radius: var(--radius-sm); display: inline-block;">relative (偏移)</div>
<div class="position-absolute" style="background: color-mix(in oklch, var(--clr-accent) 40%, transparent); padding: var(--space-sm); border-radius: var(--radius-sm);">absolute</div>
</div>
<p>固定定位示例(右下角的固定按钮):</p>
<button class="btn position-fixed" style="font-size: 0.8rem; z-index: 50;">🔝 固定按钮</button>
<p><code>sticky</code> 定位示例 — 请参考页面顶部的导航栏(<code>position: sticky; top: 0</code>)</p>
</div>
<div class="card">
<h3>3.3 浮动与清除 <span class="badge">Float</span></h3>
<div class="float-demo">
<div class="float-left">float: left</div>
<div class="float-right">float: right</div>
<p>这是环绕浮动元素的文本内容。使用 <code>float: inline-start</code>(逻辑属性)和 <code>float: inline-end</code>。文本会围绕浮动元素排列,展示传统的浮动布局方式。</p>
<p style="clear: both;">使用 <code>clear: both</code> 清除浮动。</p>
</div>
</div>
</section>
<!-- ==========================================
四、布局系统
========================================== -->
<section id="layout" class="scroll-reveal" aria-label="CSS布局">
<h2>📐 四、现代 CSS 布局</h2>
<!-- Flexbox -->
<div class="card">
<h3>4.1 Flexbox 弹性布局 <span class="badge">Flexbox</span></h3>
<p>一维布局系统,用于在行或列中排列元素。</p>
<div class="flex-advanced" style="margin-block-end: var(--space-lg);">
<div class="flex-item">flex: 1 1 200px<br>项目 1</div>
<div class="flex-item flex-item-grow">flex-grow: 3<br>项目 2(增长更多)</div>
<div class="flex-item flex-item-shrink">flex-shrink: 0<br>flex-basis: 150px<br>项目 3(不收缩)</div>
<div class="flex-item">项目 4</div>
</div>
<p>对齐属性:<code>justify-content</code>(主轴对齐)<code>align-items</code>(交叉轴对齐)<code>gap</code>(间距)</p>
<div style="display: flex; justify-content: space-between; gap: var(--space-md); background: var(--clr-surface-2); padding: var(--space-md); border-radius: var(--radius-sm);">
<div style="background: var(--clr-primary-soft); padding: var(--space-sm); border-radius: var(--radius-xs);">space-between</div>
<div style="background: var(--clr-primary-soft); padding: var(--space-sm); border-radius: var(--radius-xs);">space-between</div>
<div style="background: var(--clr-primary-soft); padding: var(--space-sm); border-radius: var(--radius-xs);">space-between</div>
</div>
</div>
<!-- Grid -->
<div class="card">
<h3>4.2 CSS Grid 网格布局 <span class="badge">Grid</span></h3>
<p>二维布局系统,同时控制行和列。</p>
<div class="grid-advanced" style="margin-block-end: var(--space-lg);">
<div class="grid-item">1fr 1fr 1fr</div>
<div class="grid-item grid-item-wide">grid-column: span 2</div>
<div class="grid-item grid-item-tall">grid-row: span 2</div>
<div class="grid-item">auto-fill + minmax</div>
<div class="grid-item">响应式网格</div>
<div class="grid-item">自动调整</div>
</div>
<!-- 子网格 Subgrid -->
<h4>子网格 <span class="badge accent">Subgrid</span></h4>
<div class="subgrid-demo">
<div class="subgrid-item" style="background: var(--clr-primary-soft); padding: var(--space-md); border-radius: var(--radius-sm);">
<strong>子网格项 1</strong>
<p style="font-size: var(--text-xs);">此项目使用 <code>grid-template-rows: subgrid</code> 与父网格对齐。</p>
</div>
<div class="subgrid-item" style="background: color-mix(in oklch, var(--clr-secondary) 30%, transparent); padding: var(--space-md); border-radius: var(--radius-sm);">
<strong>子网格项 2</strong>
<p style="font-size: var(--text-xs);">子网格允许嵌套网格继承父网格的轨道定义。</p>
<p style="font-size: var(--text-xs);">这是子网格的第二行内容,与父网格对齐。</p>
</div>
<div class="subgrid-item" style="background: color-mix(in oklch, var(--clr-accent) 30%, transparent); padding: var(--space-md); border-radius: var(--radius-sm);">
<strong>子网格项 3</strong>
</div>
</div>
</div>
<!-- 多列布局 -->
<div class="card">
<h3>4.3 多列布局 <span class="badge">Multi-column</span></h3>
<div class="multi-column">
<p>这是多列布局的示例文本。使用 <code>column-count</code> 和 <code>column-gap</code> 属性可以轻松创建类似报纸的多列排版效果。文本会自动从一列流到下一列。</p>
<p>多列布局非常适合展示大段的文本内容。你可以使用 <code>column-rule</code> 添加列之间的分隔线。</p>
<p>使用 <code>column-width</code> 替代 <code>column-count</code> 可以创建响应式的多列布局,列数会根据容器宽度自动调整。</p>
</div>
</div>
<!-- 容器查询 -->
<div class="card">
<h3>4.4 容器查询 <span class="badge warning">Container Queries</span></h3>
<p>使用 <code>container-type</code> 和 <code>@container</code> 根据容器尺寸而非视口尺寸应用样式。</p>
<div style="display: grid; grid-template-columns: 1fr 1fr; gap: var(--space-lg);">
<div class="container-query-demo" style="border: 2px solid var(--clr-border); border-radius: var(--radius-md); padding: var(--space-md);">
<div class="cq-item" style="display: flex; flex-direction: column; gap: var(--space-sm); align-items: center; text-align: center;">
<span>📦</span>
<p style="font-size: var(--text-sm);">小容器(<500px 时纵向排列)</p>
</div>
</div>
<div class="container-query-demo" style="border: 2px solid var(--clr-border); border-radius: var(--radius-md); padding: var(--space-md); min-inline-size: 500px;">
<div class="cq-item" style="display: flex; flex-direction: column; gap: var(--space-sm); align-items: center; text-align: center;">
<span>📦</span>
<p style="font-size: var(--text-sm);">大容器(≥500px 时横向排列,通过 @container 实现)</p>
</div>
</div>
</div>
</div>
</section>
<!-- ==========================================
五、动画与过渡
========================================== -->
<section id="animations" class="scroll-reveal" aria-label="CSS动画">
<h2>🎬 五、动画与过渡</h2>
<div class="card">
<h3>5.1 CSS 过渡 <span class="badge">Transitions</span></h3>
<p>使用 <code>transition</code> 属性在状态变化时实现平滑过渡。</p>
<div style="display: flex; gap: var(--space-md); flex-wrap: wrap; align-items: center;">
<div style="background: var(--clr-primary); padding: var(--space-md); border-radius: var(--radius-sm); transition: all 0.5s cubic-bezier(0.22,1,0.36,1); cursor: pointer;"
onmouseover="this.style.background='var(--clr-accent)'; this.style.transform='scale(1.1) rotate(5deg)';"
onmouseout="this.style.background='var(--clr-primary)'; this.style.transform='scale(1) rotate(0)';">
悬停过渡
</div>
<div style="background: var(--clr-secondary); padding: var(--space-md); border-radius: var(--radius-full); transition: all 0.3s ease-in-out; cursor: pointer;"
onmouseover="this.style.borderRadius='4px'; this.style.padding='var(--space-xl)';"
onmouseout="this.style.borderRadius='var(--radius-full)'; this.style.padding='var(--space-md)';">
形状过渡
</div>
</div>
<p>缓动函数:<code>ease</code> <code>ease-in</code> <code>ease-out</code> <code>ease-in-out</code> <code>linear</code> <code>cubic-bezier()</code> <code>steps()</code></p>
</div>
<div class="card">
<h3>5.2 CSS 关键帧动画 <span class="badge">@keyframes</span></h3>
<div style="display: flex; gap: var(--space-xl); flex-wrap: wrap; align-items: center; margin-block: var(--space-lg);">
<div class="animate-pulse" style="background: var(--clr-primary); inline-size: 60px; block-size: 60px; border-radius: 50%;"></div>
<div class="animate-spin" style="border: 4px solid var(--clr-border); border-block-start-color: var(--clr-primary); inline-size: 60px; block-size: 60px; border-radius: 50%;"></div>
<div class="animate-bounce" style="background: var(--clr-accent); inline-size: 60px; block-size: 60px; border-radius: var(--radius-md);"></div>
<div class="animate-gradient" style="background: linear-gradient(135deg, var(--clr-primary), var(--clr-secondary), var(--clr-accent)); inline-size: 120px; block-size: 60px; border-radius: var(--radius-md);"></div>
</div>
<pre>@keyframes fadeIn {
from { opacity: 0; transform: translateY(20px); }
to { opacity: 1; transform: translateY(0); }
}
.element {
animation: fadeIn 0.8s ease-out both;
}</pre>
</div>
<div class="card">
<h3>5.3 滚动驱动动画 <span class="badge warning">Scroll-Driven</span></h3>
<p>使用 <code>animation-timeline: view()</code> 或 <code>scroll()</code> 让动画随滚动进度驱动。</p>
<p>页面顶部的彩色进度条就是使用 <code>animation-timeline: scroll(root)</code> 实现的滚动驱动动画。</p>
<p>向下滚动页面,观察元素的滚动触发动画:</p>
<div style="display: grid; grid-template-columns: repeat(3, 1fr); gap: var(--space-md);">
<div style="background: var(--clr-surface-2); border: 1px solid var(--clr-border); border-radius: var(--radius-md); padding: var(--space-lg); min-block-size: 100px; display: flex; align-items: center; justify-content: center;"
class="scroll-reveal">滚动触发 1</div>
<div style="background: var(--clr-surface-2); border: 1px solid var(--clr-border); border-radius: var(--radius-md); padding: var(--space-lg); min-block-size: 100px; display: flex; align-items: center; justify-content: center; animation-delay: 0.2s;"
class="scroll-reveal">滚动触发 2</div>
<div style="background: var(--clr-surface-2); border: 1px solid var(--clr-border); border-radius: var(--radius-md); padding: var(--space-lg); min-block-size: 100px; display: flex; align-items: center; justify-content: center; animation-delay: 0.4s;"
class="scroll-reveal">滚动触发 3</div>
</div>
</div>
<div class="card">
<h3>5.4 变换 Transform <span class="badge">2D / 3D</span></h3>
<p>2D 变换:<code>translate</code> <code>rotate</code> <code>scale</code> <code>skew</code></p>
<div style="display: flex; gap: var(--space-xl); flex-wrap: wrap; align-items: center; margin-block: var(--space-md);">
<div style="background: var(--clr-primary-soft); padding: var(--space-md); border-radius: var(--radius-sm); transform: translate(10px, -5px);">translate</div>
<div style="background: var(--clr-primary-soft); padding: var(--space-md); border-radius: var(--radius-sm); transform: rotate(15deg);">rotate</div>
<div style="background: var(--clr-primary-soft); padding: var(--space-md); border-radius: var(--radius-sm); transform: scale(1.3);">scale</div>
<div style="background: var(--clr-primary-soft); padding: var(--space-md); border-radius: var(--radius-sm); transform: skewX(-15deg);">skewX</div>
</div>
<p>3D 变换(悬停查看效果):</p>
<div class="transform-3d-demo">
<div class="cube"></div>
</div>
<p>使用 <code>perspective</code> 创建3D透视效果。</p>
</div>
<div class="card">
<h3>5.5 滤镜与混合模式 <span class="badge">Filters</span></h3>
<div style="display: flex; gap: var(--space-lg); flex-wrap: wrap; align-items: center;">
<div class="filter-demo">
<img src="https://picsum.photos/seed/filter/150/150" alt="滤镜示例" width="150" height="150" style="border-radius: var(--radius-md);" loading="lazy">
<figcaption>悬停移除滤镜</figcaption>
</div>
<div class="blend-demo" style="inline-size: 150px; block-size: 150px; display: flex; align-items: center; justify-content: center; font-weight: 700;">
mix-blend-mode
</div>
<div class="clip-path-demo" style="inline-size: 150px; block-size: 150px; display: flex; align-items: center; justify-content: center; font-weight: 700;">
clip-path
</div>
<div class="mask-demo" style="inline-size: 150px; block-size: 150px; background: linear-gradient(135deg, var(--clr-primary), var(--clr-accent)); border-radius: var(--radius-md);"></div>
</div>
</div>
</section>
<!-- ==========================================
六、现代 CSS 特性
========================================== -->
<section id="modern-css" class="scroll-reveal" aria-label="现代CSS特性">
<h2>🚀 六、现代 CSS 特性</h2>
<div class="card">
<h3>6.1 CSS 自定义属性 <span class="badge">Custom Properties</span></h3>
<p>使用 <code>--variable-name</code> 定义变量,<code>var()</code> 引用。</p>
<pre>:root {
--primary-color: oklch(0.75 0.15 200);
--spacing-unit: 1rem;
}
.element {
color: var(--primary-color);
padding: var(--spacing-unit);
}</pre>
<p>使用 <code>@property</code> 注册自定义属性类型:</p>
<pre>@property --angle {
syntax: '<angle>';
inherits: false;
initial-value: 0deg;
}</pre>
</div>
<div class="card">
<h3>6.2 CSS 嵌套 <span class="badge accent">Native Nesting</span></h3>
<pre>.parent {
color: blue;
& .child {
color: red;
}
&:hover {
color: green;
}
.sibling {
font-weight: bold;
}
}</pre>
<div class="nested-demo">
<span class="nested-child">悬停此元素查看嵌套CSS效果(子元素会变色)</span>
</div>
</div>
<div class="card">
<h3>6.3 级联层 <span class="badge">@layer</span></h3>
<pre>@layer reset, base, components, utilities;
/* 后面的层优先级更高 */
@layer reset { ... }
@layer base { ... }
@layer components { ... }</pre>
<p>本页面的所有样式都组织在 <code>@layer</code> 中,优先级从低到高依次为:reset → base → components → utilities → animations</p>
</div>
<div class="card">
<h3>6.4 逻辑属性 <span class="badge">Logical Properties</span></h3>
<p>使用相对书写方向的属性,替代物理方向属性。</p>
<div class="logical-props-demo">
<p>此元素使用 <code>margin-inline</code> <code>padding-block</code> <code>border-inline-start</code> 等逻辑属性。</p>
<p>逻辑属性会根据 <code>writing-mode</code> 和 <code>direction</code> 自动调整。</p>
</div>
<div class="writing-mode-vertical" style="margin-block-start: var(--space-md);">
<p>这是使用 <code>writing-mode: vertical-rl</code> 的竖排文字示例。</p>
</div>
</div>
<div class="card">
<h3>6.5 颜色函数 <span class="badge">Color Functions</span></h3>
<p>现代 CSS 颜色:<code>oklch()</code> <code>color-mix()</code> <code>lab()</code> <code>lch()</code></p>
<div style="display: flex; gap: var(--space-md); flex-wrap: wrap;">
<div style="inline-size: 80px; block-size: 80px; border-radius: var(--radius-md); background: oklch(0.7 0.15 200);"></div>
<div style="inline-size: 80px; block-size: 80px; border-radius: var(--radius-md); background: oklch(0.7 0.2 40);"></div>
<div style="inline-size: 80px; block-size: 80px; border-radius: var(--radius-md); background: oklch(0.7 0.2 140);"></div>
<div style="inline-size: 80px; block-size: 80px; border-radius: var(--radius-md); background: color-mix(in oklch, oklch(0.7 0.15 200) 50%, oklch(0.7 0.2 40) 50%);"></div>
<div style="inline-size: 80px; block-size: 80px; border-radius: var(--radius-md); background: color-mix(in srgb, red 30%, blue 70%);"></div>
</div>
<p style="margin-block-start: var(--space-md);">圆锥渐变示例:</p>
<div class="conic-gradient-demo"></div>
</div>
<div class="card">
<h3>6.6 数学函数 <span class="badge">Math Functions</span></h3>
<p><code>calc()</code> <code>min()</code> <code>max()</code> <code>clamp()</code></p>
<pre>/* clamp() 用于流式排版 */
font-size: clamp(1rem, 0.8rem + 0.5vw, 1.5rem);
/* min() 取最小值 */
inline-size: min(100%, 800px);
/* max() 取最大值 */
padding: max(1rem, 2vw);
/* calc() 计算 */
inline-size: calc(100% - 2rem);</pre>
</div>
<div class="card">
<h3>6.7 滚动行为 <span class="badge">Scroll</span></h3>
<div class="scroll-snap-container">
<div class="scroll-snap-item">滚动吸附 1<br><small>scroll-snap-align: center</small></div>
<div class="scroll-snap-item">滚动吸附 2</div>
<div class="scroll-snap-item">滚动吸附 3</div>
<div class="scroll-snap-item">滚动吸附 4</div>
<div class="scroll-snap-item">滚动吸附 5</div>
</div>
<p><code>scroll-behavior: smooth</code> 实现平滑滚动,<code>scroll-snap-type</code> 实现滚动吸附。</p>
<div class="custom-scroll" style="margin-block-start: var(--space-md); border: 1px solid var(--clr-border); border-radius: var(--radius-md); padding: var(--space-md);">
<p>自定义滚动条样式区域。向下滚动查看效果。</p>
<p>可以使用 <code>::-webkit-scrollbar</code> 和 <code>scrollbar-width</code> <code>scrollbar-color</code> 来定制滚动条。</p>
<p>这是一段用来演示自定义滚动条样式的文本内容。继续向下滚动可以看到滚动条的颜色和宽度已经改变。</p>
<p>滚动条的轨道使用了 <code>var(--clr-surface-2)</code> 颜色,滑块使用了 <code>var(--clr-primary)</code> 颜色。</p>
</div>
</div>
<div class="card">
<h3>6.8 文本样式 <span class="badge">Typography</span></h3>
<p>使用 <code>text-wrap: balance</code> 和 <code>text-wrap: pretty</code> 优化文本排版。</p>
<div class="text-ellipsis" style="margin-block-end: var(--space-sm);">这是一个使用 text-overflow: ellipsis 的溢出文本示例,文本超出容器宽度时会被截断并显示省略号。</div>
<div class="text-clamp" style="margin-block-end: var(--space-sm);">这是一个使用 -webkit-line-clamp 进行多行文本截断的示例。当文本超过指定行数时,会被截断并显示省略号。这是第二行内容。这是第三行内容,超过三行就会被截断。</div>
<p class="text-shadow-demo" style="text-align: center;">文字阴影效果</p>
<p style="text-decoration: underline wavy var(--clr-primary); text-underline-offset: 6px;">波浪线下划线</p>
<p style="letter-spacing: 0.2em; text-transform: uppercase;">字母间距与大小写转换</p>
<p style="word-spacing: 0.5em; line-height: 2;">单词间距与行高设置示例文本</p>
</div>
<div class="card">
<h3>6.9 宽高比与图片 <span class="badge">Aspect Ratio</span></h3>
<div class="aspect-ratio-demo" style="margin-block-end: var(--space-md);">
aspect-ratio: 16/9
</div>
<div class="object-fit-demo">
<img src="https://picsum.photos/seed/objectfit/800/400" alt="object-fit 示例" loading="lazy">
<figcaption>object-fit: cover + object-position: center 30%</figcaption>
</div>
</div>
<div class="card">
<h3>6.10 计数器 <span class="badge">Counters</span></h3>
<ol class="counter-list">
<li>使用 counter-reset 初始化计数器</li>
<li>使用 counter-increment 递增计数器</li>
<li>使用 ::before 和 counter() 显示计数</li>
</ol>
</div>
<div class="card">
<h3>6.11 内容可见性 <span class="badge">content-visibility</span></h3>
<p><code>content-visibility: auto</code> 可以提升大型页面的渲染性能。</p>
<div class="content-visibility-demo" style="border: 1px dashed var(--clr-border); border-radius: var(--radius-md); padding: var(--space-md);">
<p>此元素使用 <code>content-visibility: auto</code> 和 <code>contain-intrinsic-size: 200px</code> 进行性能优化。</p>
</div>
</div>
</section>
<!-- ==========================================
七、响应式设计
========================================== -->
<section id="responsive" class="scroll-reveal" aria-label="响应式设计">
<h2>📱 七、响应式设计</h2>
<div class="card">
<h3>7.1 媒体查询 <span class="badge">@media</span></h3>
<p>使用 <code>@media</code> 根据设备特征应用不同样式。</p>
<pre>@media (max-width: 768px) {
/* 移动端样式 */
}
@media (min-width: 769px) and (max-width: 1200px) {
/* 平板端样式 */
}
@media (min-width: 1200px) {
/* 桌面端样式 */
}
@media (prefers-reduced-motion: reduce) {
/* 用户偏好减少动画 */
}
@media (prefers-color-scheme: dark) {
/* 暗色模式 */
}
@media print {
/* 打印样式 */
}</pre>
<p>当前页面根据视口宽度自动调整网格列数、字体大小和间距。尝试调整浏览器窗口大小来查看效果。</p>
</div>
<div class="card">
<h3>7.2 响应式单位 <span class="badge">Viewport Units</span></h3>
<p>视口单位:<code>vh</code> <code>vw</code> <code>vmin</code> <code>vmax</code> <code>dvh</code> <code>svh</code> <code>lvh</code></p>
<div style="display: grid; grid-template-columns: repeat(auto-fit, minmax(120px, 1fr)); gap: var(--space-md); text-align: center;">
<div style="background: var(--clr-primary-soft); padding: var(--space-md); border-radius: var(--radius-sm);">
<code>100vw</code><br><small>视口宽度</small>
</div>
<div style="background: color-mix(in oklch, var(--clr-secondary) 30%, transparent); padding: var(--space-md); border-radius: var(--radius-sm);">
<code>100dvh</code><br><small>动态视口高度</small>
</div>
<div style="background: color-mix(in oklch, var(--clr-accent) 30%, transparent); padding: var(--space-md); border-radius: var(--radius-sm);">
<code>50vmin</code><br><small>视口短边的50%</small>
</div>
<div style="background: color-mix(in oklch, var(--clr-success) 30%, transparent); padding: var(--space-md); border-radius: var(--radius-sm);">
<code>50vmax</code><br><small>视口长边的50%</small>
</div>
</div>
<p style="margin-block-start: var(--space-md);">相对单位:<code>em</code> <code>rem</code> <code>ch</code> <code>ex</code> <code>lh</code> <code>rlh</code> <code>%</code></p>
</div>
<div class="card">
<h3>7.3 响应式图片 <span class="badge">Responsive Images</span></h3>
<p>使用 <code>srcset</code> 和 <code>sizes</code> 属性根据设备像素比和视口宽度加载不同尺寸的图片。</p>
<img src="https://picsum.photos/seed/responsive/800/300"
srcset="https://picsum.photos/seed/responsive/400/150 400w,
https://picsum.photos/seed/responsive/800/300 800w,
https://picsum.photos/seed/responsive/1200/450 1200w"
sizes="(max-width: 600px) 400px, (max-width: 1000px) 800px, 1200px"
alt="响应式图片 srcset 示例" loading="lazy" style="border-radius: var(--radius-md);">
<figcaption>根据视口宽度自动选择最佳图片尺寸</figcaption>
</div>
</section>
<!-- ==========================================
八、其他进阶特性
========================================== -->
<section class="scroll-reveal" aria-label="其他进阶CSS特性">
<h2>⚡ 八、其他进阶特性</h2>
<div class="card">
<h3>8.1 @supports 特性检测</h3>
<pre>@supports (display: grid) {
/* 支持 Grid 的浏览器应用这些样式 */
.layout { display: grid; }
}
@supports not (display: grid) {
/* 不支持的浏览器使用 fallback */
.layout { display: flex; }
}</pre>
</div>
<div class="card">
<h3>8.2 @scope 样式作用域</h3>
<pre>@scope (.card) {
/* 这些样式只作用于 .card 内部 */
h3 { color: var(--clr-primary); }
p { font-size: 0.95em; }
:scope { border: 1px solid var(--clr-border); }
}</pre>
</div>
<div class="card">
<h3>8.3 工具提示(纯 CSS)</h3>
<p>使用 <code>::after</code> 和 <code>data-*</code> 属性创建纯 CSS 工具提示:</p>
<p>悬停查看 <span class="tooltip" data-tooltip="这是纯 CSS 工具提示!">这个文本</span> 的效果。</p>
</div>
<div class="card">
<h3>8.4 首字母下沉</h3>
<p class="first-letter-demo">这是一个使用 ::first-letter 伪元素实现首字母下沉效果的段落。首字母会变大并浮动到左侧,其他文字环绕排列。这种效果常见于杂志和报纸的排版中。</p>
</div>
<div class="card">
<h3>8.5 CSS 变量继承</h3>
<div style="--custom-color: var(--clr-accent); padding: var(--space-md); border: 1px solid var(--clr-border); border-radius: var(--radius-md);">
<p style="color: var(--custom-color);">此元素继承了父级定义的 <code>--custom-color</code> 变量。</p>
<div style="--custom-color: var(--clr-success);">
<p style="color: var(--custom-color);">子元素重新定义了 <code>--custom-color</code> 变量。</p>
</div>
<p style="color: var(--custom-color, var(--clr-text));">使用 fallback 值:<code>var(--undefined, fallback)</code></p>
</div>
</div>
<div class="card">
<h3>8.6 文本方向与国际化</h3>
<p><code>dir="rtl"</code> 从右到左:</p>
<p dir="rtl" style="background: var(--clr-surface-2); padding: var(--space-md); border-radius: var(--radius-sm);">هذا نص باللغة العربية</p>
<p><code><bdo></code> 双向覆盖:<bdo dir="rtl">这段文字会被从右到左显示</bdo></p>
<p><code><bdi></code> 双向隔离:<bdi>用户输入内容</bdi></p>
</div>
<div class="card">
<h3>8.7 CSS 动画性能优化</h3>
<p>使用 <code>will-change</code> 提示浏览器优化动画性能:</p>
<pre>.animated-element {
will-change: transform, opacity;
/* 动画结束后移除 will-change */
}</pre>
<p>优先使用 <code>transform</code> 和 <code>opacity</code> 进行动画,避免触发布局和绘制。</p>
</div>
</section>
<!-- ========== 页脚 (语义化 footer) ========== -->
<footer class="card" style="text-align: center; margin-block-start: var(--space-3xl);" role="contentinfo">
<h3>📚 前端学习全景图</h3>
<p class="text-muted">本页面涵盖了 HTML5 和 CSS3 的核心知识点及最新特性</p>
<div class="flex flex-wrap gap-sm items-center justify-between" style="margin-block-start: var(--space-lg);">
<span class="badge">HTML5 语义化</span>
<span class="badge accent">CSS Grid + Flexbox</span>
<span class="badge success">容器查询</span>
<span class="badge warning">@layer 级联层</span>
<span class="badge">CSS 嵌套</span>
<span class="badge accent">:has() 选择器</span>
<span class="badge success">滚动驱动动画</span>
<span class="badge warning">逻辑属性</span>
<span class="badge">oklch 颜色</span>
<span class="badge accent">color-mix()</span>
<span class="badge success">subgrid 子网格</span>
<span class="badge warning">@container</span>
<span class="badge">aspect-ratio</span>
<span class="badge accent">clip-path</span>
<span class="badge success">mix-blend-mode</span>
<span class="badge warning">popover / dialog</span>
<span class="badge">scroll-snap</span>
<span class="badge accent">prefers-reduced-motion</span>
<span class="badge success">@supports</span>
<span class="badge warning">@scope</span>
</div>
<p style="margin-block-start: var(--space-xl); font-size: var(--text-sm); color: var(--clr-text-muted);">
构建于 2024 · 使用最新 CSS 特性 · 持续更新中
</p>
<address style="font-style: normal; margin-block-start: var(--space-md);">
📧 联系:<a href="mailto:learn@frontend.dev">learn@frontend.dev</a>
</address>
<p style="margin-block-start: var(--space-md);">
<a href="#" aria-label="回到顶部">↑ 回到顶部</a>
</p>
</footer>
</main>
<!-- ========== Canvas 绘制脚本 ========== -->
<script>
// Canvas 绘图示例
(function() {
const canvas = document.getElementById('demo-canvas');
if (canvas && canvas.getContext) {
const ctx = canvas.getContext('2d');
// 绘制渐变背景
const gradient = ctx.createLinearGradient(0, 0, 300, 150);
gradient.addColorStop(0, '#4a9eff');
gradient.addColorStop(0.5, '#00d4aa');
gradient.addColorStop(1, '#ff9500');
ctx.fillStyle = gradient;
ctx.fillRect(0, 0, 300, 150);
// 绘制文字
ctx.fillStyle = '#fff';
ctx.font = 'bold 20px Inter, sans-serif';
ctx.textAlign = 'center';
ctx.fillText('Canvas 绘图', 150, 50);
ctx.font = '14px Inter, sans-serif';
ctx.fillText('使用 JavaScript 在画布上绘制', 150, 80);
// 绘制圆形
ctx.beginPath();
ctx.arc(150, 110, 20, 0, Math.PI * 2);
ctx.fillStyle = '#fff';
ctx.fill();
ctx.strokeStyle = '#333';
ctx.lineWidth = 2;
ctx.stroke();
}
})();
</script>
</body>
</html>