Skip to content

Commit bbce43c

Browse files
committed
style: 重构导航栏状态切换为单状态 Toggle 圆形按钮并实现旋转动效
1 parent 435fdbd commit bbce43c

4 files changed

Lines changed: 55 additions & 92 deletions

File tree

index.html

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -35,16 +35,18 @@ <h1>Claude Code 中文速查表</h1>
3535
<div class="os-toggle" id="osToggle" aria-label="系统快捷键切换">
3636
<button class="os-btn active" type="button" data-os="mac" title="Mac 快捷键" aria-label="切换到 Mac 快捷键">
3737
<svg width="14" height="14" viewBox="0 0 814 1000" fill="currentColor" aria-hidden="true"><path d="M788.1 340.9c-5.8 4.5-108.2 62.2-108.2 190.5 0 148.4 130.3 200.9 134.2 202.2-.6 3.2-20.7 71.9-68.7 141.9-42.8 61.6-87.5 123.1-155.5 123.1s-85.5-39.5-164-39.5c-76.5 0-103.7 40.8-165.9 40.8s-105.6-57.8-155.5-127.4c-58.4-83-106.3-211.5-106.3-334.2 0-196.5 127.8-300.9 253.3-300.9 66.8 0 122.4 43.4 164.1 43.4 39.5 0 101.1-46 176.2-46 28.5 0 130.9 2.6 198.3 99.1zm-169.5-92.8c31.2-37 52.4-88.1 52.4-139.3 0-7.1-.6-14.3-1.9-20.1-50 1.6-109.2 33.3-145 75.1-25.8 29.3-52.4 79.8-52.4 131.6 0 7.8.6 15.6 1.3 18.2 2.6.6 6.4 1.3 10.3 1.3 44.7 0 101.1-30.5 135.3-66.8z"/></svg>
38-
<span class="os-btn-label">Mac</span>
3938
</button>
4039
<button class="os-btn" type="button" data-os="win" title="Windows 快捷键" aria-label="切换到 Windows 快捷键">
4140
<svg width="14" height="14" viewBox="0 0 88 88" fill="currentColor" aria-hidden="true"><path d="M0 12.402l35.687-4.86.016 34.423-35.67.203zm35.67 33.529l.028 34.453L.028 71.48l-.026-25.55zm4.326-39.025L87.314 0v41.527l-47.318.376zm47.329 39.349l-.011 41.34-47.318-6.678-.066-34.739z"/></svg>
42-
<span class="os-btn-label">Win</span>
4341
</button>
4442
</div>
4543
<div class="theme-toggle" id="themeToggle" aria-label="主题切换">
46-
<button class="theme-btn active" type="button" data-theme="light" aria-label="切换到浅色主题"></button>
47-
<button class="theme-btn" type="button" data-theme="dark" aria-label="切换到深色主题"></button>
44+
<button class="theme-btn active" type="button" data-theme="light" aria-label="切换到浅色主题">
45+
<svg width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2.5" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"><circle cx="12" cy="12" r="4"/><path d="M12 2v2M12 20v2M4.93 4.93l1.41 1.41M17.66 17.66l1.41 1.41M2 12h2M20 12h2M6.34 17.66l-1.41 1.41M19.07 4.93l-1.41 1.41"/></svg>
46+
</button>
47+
<button class="theme-btn" type="button" data-theme="dark" aria-label="切换到深色主题">
48+
<svg width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2.5" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"><path d="M12 3a6 6 0 0 0 9 9 9 9 0 1 1-9-9Z"/></svg>
49+
</button>
4850
</div>
4951
</div>
5052
<div class="header-meta">

script.js

Lines changed: 12 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -68,7 +68,12 @@
6868
buttons.forEach(function (button) {
6969
button.addEventListener("click", function () {
7070
localStorage.setItem("cc-os-manual", "1");
71-
applyOS(button.dataset.os);
71+
if (button.classList.contains("active")) {
72+
var nextOS = button.dataset.os === "mac" ? "win" : "mac";
73+
applyOS(nextOS);
74+
} else {
75+
applyOS(button.dataset.os);
76+
}
7277
});
7378
});
7479

@@ -103,7 +108,12 @@
103108
if (buttons.length > 0) {
104109
buttons.forEach(function (button) {
105110
button.addEventListener("click", function () {
106-
applyTheme(button.dataset.theme);
111+
if (button.classList.contains("active")) {
112+
var nextTheme = button.dataset.theme === "light" ? "dark" : "light";
113+
applyTheme(nextTheme);
114+
} else {
115+
applyTheme(button.dataset.theme);
116+
}
107117
});
108118
});
109119
}

styles.css

Lines changed: 36 additions & 85 deletions
Original file line numberDiff line numberDiff line change
@@ -342,70 +342,50 @@ a,
342342
.theme-toggle {
343343
position: relative;
344344
display: inline-flex;
345+
width: 36px;
346+
height: 36px;
345347
align-items: center;
346-
padding: 0.2rem;
348+
justify-content: center;
347349
border: 1px solid var(--control-border);
348-
border-radius: 999px;
350+
border-radius: 50%;
349351
background: var(--control-bg);
350352
isolation: isolate;
353+
cursor: pointer;
354+
transition: background-color 0.2s ease, border-color 0.2s ease, transform 0.1s ease;
351355
}
352356

353-
/* 滑块指示器 */
354-
.os-toggle::before,
355-
.theme-toggle::before {
356-
content: "";
357-
position: absolute;
358-
top: 0.2rem;
359-
bottom: 0.2rem;
360-
left: 0.2rem;
361-
width: calc(50% - 0.2rem);
362-
background: var(--toggle-indicator-bg);
363-
border-radius: 999px;
364-
box-shadow: var(--toggle-indicator-shadow);
365-
transition: transform 0.28s cubic-bezier(0.25, 1, 0.5, 1);
366-
z-index: 1;
357+
.os-toggle:hover,
358+
.theme-toggle:hover {
359+
border-color: var(--border-strong);
360+
background: color-mix(in srgb, var(--panel) 60%, var(--control-bg));
367361
}
368362

369-
/* 滑动位移 */
370-
.os-toggle:has([data-os="win"].active)::before,
371-
.theme-toggle:has([data-theme="dark"].active)::before {
372-
transform: translateX(100%);
363+
.os-toggle:active,
364+
.theme-toggle:active {
365+
transform: scale(0.92);
373366
}
374367

375368
.os-btn,
376369
.theme-btn {
377370
appearance: none;
378371
border: none;
379372
background: transparent;
380-
color: var(--text-soft);
381-
font: inherit;
382-
cursor: pointer;
383-
min-height: 44px;
384-
padding: 0.6rem 0.95rem;
385-
border-radius: 999px;
373+
padding: 0;
374+
margin: 0;
375+
width: 100%;
376+
height: 100%;
377+
position: absolute;
378+
inset: 0;
386379
display: inline-flex;
387380
align-items: center;
388381
justify-content: center;
389-
gap: 0.4rem;
390-
position: relative;
391-
z-index: 2;
392-
flex: 1;
393-
transition: color 0.2s ease, transform 0.1s ease;
394-
}
395-
396-
.os-btn {
397-
min-width: 4.8rem;
398-
}
399-
400-
.theme-btn {
401-
min-width: 3.2rem;
402-
font-weight: 700;
403-
}
404-
405-
/* 按钮点击缩放反馈 */
406-
.os-btn:active,
407-
.theme-btn:active {
408-
transform: scale(0.95);
382+
border-radius: 50%;
383+
cursor: pointer;
384+
opacity: 0;
385+
transform: scale(0.6) rotate(-90deg);
386+
pointer-events: none;
387+
transition: opacity 0.3s cubic-bezier(0.34, 1.56, 0.64, 1), transform 0.3s cubic-bezier(0.34, 1.56, 0.64, 1);
388+
color: var(--text-soft);
409389
}
410390

411391
.github-star-link {
@@ -455,34 +435,24 @@ a,
455435
font-weight: 800;
456436
}
457437

458-
.theme-btn {
459-
min-width: 2.6rem;
460-
font-weight: 700;
461-
}
462-
463-
.os-btn-label {
464-
font-size: 0.82rem;
465-
line-height: 1;
466-
font-weight: 700;
467-
letter-spacing: 0.02em;
468-
}
469-
470438
.os-btn.active,
471439
.theme-btn.active {
440+
opacity: 1;
441+
transform: scale(1) rotate(0deg);
442+
pointer-events: auto;
443+
color: var(--text);
444+
}
445+
446+
.os-btn:hover,
447+
.theme-btn:hover {
472448
color: var(--text);
473-
font-weight: 800;
474449
}
475450

476451
.section-switcher-btn.active {
477452
background: var(--control-active-bg);
478453
color: var(--control-active-text);
479454
}
480455

481-
.os-btn:hover:not(.active),
482-
.theme-btn:hover:not(.active) {
483-
color: var(--text);
484-
}
485-
486456
.section-switcher-btn:hover:not(.active) {
487457
background: color-mix(in srgb, var(--panel) 60%, var(--control-bg));
488458
}
@@ -1165,28 +1135,9 @@ a,
11651135
}
11661136

11671137
.header-controls {
1168-
display: grid;
1169-
grid-template-columns: minmax(0, 1fr) auto;
1138+
display: flex;
11701139
gap: 0.5rem;
1171-
width: 100%;
1172-
}
1173-
1174-
.os-toggle,
1175-
.theme-toggle {
1176-
min-width: 0;
1177-
justify-content: space-between;
1178-
}
1179-
1180-
.os-toggle {
1181-
width: 100%;
1182-
}
1183-
1184-
.os-btn,
1185-
.theme-btn {
1186-
min-height: 38px;
1187-
padding: 0.48rem 0.72rem;
1188-
flex: 1;
1189-
min-width: 0;
1140+
align-items: center;
11901141
}
11911142

11921143
.github-star-link {

styles.test.mjs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -28,7 +28,7 @@ test('styles.css 包含 GitHub Star 入口和手机端响应式契约', () => {
2828
assert.doesNotMatch(styles, /@media \(max-width:\s*1180px\)/);
2929
assert.match(styles, /@media \(max-width:\s*760px\) \{[\s\S]*\.page-sidebar\s*\{[\s\S]*grid-column:\s*1;/);
3030
assert.match(styles, /@media \(max-width:\s*680px\) \{[\s\S]*\.header\s*\{[\s\S]*position:\s*static;/);
31-
assert.match(styles, /@media \(max-width:\s*680px\) \{[\s\S]*\.header-controls\s*\{[\s\S]*grid-template-columns:\s*minmax\(0,\s*1fr\) auto;/);
31+
assert.match(styles, /@media \(max-width:\s*680px\) \{[\s\S]*\.header-controls\s*\{[\s\S]*display:\s*flex;/);
3232
assert.match(styles, /@media \(max-width:\s*680px\) \{[\s\S]*\.page-sidebar\s*\{[\s\S]*position:\s*sticky;/);
3333
assert.match(styles, /\.page-sidebar\s*\{[\s\S]*min-width:\s*0;/);
3434
assert.match(styles, /@media \(max-width:\s*680px\) \{[\s\S]*\.page-shell\s*\{[\s\S]*min-width:\s*0;/);

0 commit comments

Comments
 (0)