标题字号折中;软件选择移入右上角汉堡菜单
用户反馈三点: 1. 顶栏图标太大(56px) 2. 顶栏文字反而比内容区还小 —— 主次颠倒 3. 不要再整页显示「选择软件:」,改成右上角三横线按钮,点开下拉选 字号标准(用户给的基准): 「选择软件」标签 13.5px,比它大两号 ≈ 17px。 → 顶栏 17px 字 / 30px 图标;内容区 15px 字 / 24px 图标。 这样 17 > 15,层级正确。 之前两轮都搞错了: - 先给顶栏 46px 图标 + 22px 字:图标过大 - 再给 56px + 26px:更大 - 而且内容区当时是 30px,比顶栏还大,视觉上「上面比下面小」 软件选择改造: - 顶栏右侧新增汉堡按钮(三横线,展开变×) - 抽屉面板放在 header 内、正文之上,默认 hidden - 列出软件:图标 + 名字 + 当前项标记 - index.php 删除整行「选择软件:」+ chips - new.php 表单内也删除那排 chip(同一选择不该出现两次) - 交互:点击展开/再点收起/点外部关闭/Esc 关闭 - 宽屏抽屉横向排列,窄屏纵向 验证(CDP 驱动真实浏览器): 汉堡按钮存在、初始收起、点击展开、aria 同步、软件条目与当前标记齐全、 再点收起、点外部关闭 —— 全部 PASS; 顶栏字号 17px > 内容区 15px,页面无裸露 ?>; 全部路由 200;窄屏 15px/13px 层级仍正确。
This commit is contained in:
@@ -801,6 +801,44 @@
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* ---------- 顶栏软件抽屉(右上角汉堡按钮) ----------
|
||||||
|
* 原来「选择软件」平铺在列表上方占一整行,软件一多就把内容往下推。
|
||||||
|
* 现在收进抽屉:点击展开 / 再次点击收起 / 点外部关闭 / Esc 关闭。
|
||||||
|
* 用 hidden 属性而非纯 class,保证无 JS 时抽屉默认不显示(不会闪一下)。 */
|
||||||
|
function bindSoftwarePanel() {
|
||||||
|
var btn = document.getElementById('swToggle');
|
||||||
|
var panel = document.getElementById('swPanel');
|
||||||
|
if (!btn || !panel) { return; }
|
||||||
|
|
||||||
|
function open() {
|
||||||
|
panel.hidden = false;
|
||||||
|
btn.setAttribute('aria-expanded', 'true');
|
||||||
|
}
|
||||||
|
function close() {
|
||||||
|
panel.hidden = true;
|
||||||
|
btn.setAttribute('aria-expanded', 'false');
|
||||||
|
}
|
||||||
|
function toggle() {
|
||||||
|
if (panel.hidden) { open(); } else { close(); }
|
||||||
|
}
|
||||||
|
|
||||||
|
btn.addEventListener('click', function (e) {
|
||||||
|
e.stopPropagation();
|
||||||
|
toggle();
|
||||||
|
});
|
||||||
|
|
||||||
|
// 点面板内部不算「点外部」
|
||||||
|
panel.addEventListener('click', function (e) { e.stopPropagation(); });
|
||||||
|
|
||||||
|
document.addEventListener('click', function () {
|
||||||
|
if (!panel.hidden) { close(); }
|
||||||
|
});
|
||||||
|
|
||||||
|
document.addEventListener('keydown', function (e) {
|
||||||
|
if (e.key === 'Escape' && !panel.hidden) { close(); btn.focus(); }
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
/* ---------- 邮件测试发送(后台设置页) ---------- */
|
/* ---------- 邮件测试发送(后台设置页) ---------- */
|
||||||
function bindMailTest() {
|
function bindMailTest() {
|
||||||
var btn = document.getElementById('mailTestBtn');
|
var btn = document.getElementById('mailTestBtn');
|
||||||
@@ -853,6 +891,7 @@
|
|||||||
bindWontfixPanel();
|
bindWontfixPanel();
|
||||||
bindColorPicker();
|
bindColorPicker();
|
||||||
bindIconPicker();
|
bindIconPicker();
|
||||||
|
bindSoftwarePanel();
|
||||||
bindMailTest();
|
bindMailTest();
|
||||||
bindInlineValidate(); // ★ 必须在 bindNoDoubleSubmit 之前
|
bindInlineValidate(); // ★ 必须在 bindNoDoubleSubmit 之前
|
||||||
bindNoDoubleSubmit();
|
bindNoDoubleSubmit();
|
||||||
|
|||||||
+62
-15
@@ -32,16 +32,66 @@ p{margin:8px 0}
|
|||||||
-webkit-backdrop-filter:saturate(180%) blur(14px);
|
-webkit-backdrop-filter:saturate(180%) blur(14px);
|
||||||
border-bottom:1px solid var(--line);
|
border-bottom:1px solid var(--line);
|
||||||
}
|
}
|
||||||
.topbar .wrap{display:flex; align-items:center; gap:14px; height:72px}
|
.topbar .wrap{display:flex; align-items:center; gap:14px; height:66px}
|
||||||
.topbar .brand-mini{display:flex; align-items:center; gap:10px; font-weight:700; font-size:17px; color:var(--fg); min-width:0}
|
.topbar .brand-mini{display:flex; align-items:center; gap:10px; font-weight:700; font-size:17px; color:var(--fg); min-width:0}
|
||||||
.topbar .brand-mini:hover{text-decoration:none; color:var(--fg)}
|
.topbar .brand-mini:hover{text-decoration:none; color:var(--fg)}
|
||||||
/* 顶栏里的软件标识:图标与「XX 反馈系统」一起放大,成为页面主标题 */
|
/* 顶栏里的软件标识:17px 字 + 32px 图标 ——
|
||||||
.topbar .brand-mini .sw-badge{gap:11px}
|
* 比「选择软件」标签(13.5px)大两号,又不至于压过内容区标题。 */
|
||||||
.topbar .brand-mini .sw-badge-nm{font-size:22px; font-weight:700}
|
.topbar .brand-mini .sw-badge{gap:9px}
|
||||||
|
.topbar .brand-mini .sw-badge-nm{font-size:17px; font-weight:700; letter-spacing:.2px}
|
||||||
@media (max-width:560px){
|
@media (max-width:560px){
|
||||||
.topbar .wrap{height:62px}
|
.topbar .wrap{height:60px}
|
||||||
.topbar .brand-mini .sw-badge-nm{font-size:17px}
|
.topbar .brand-mini .sw-badge-nm{font-size:15.5px}
|
||||||
.topbar .brand-mini .sw-badge-img{width:32px !important; height:32px !important}
|
.topbar .brand-mini .sw-badge-img{width:26px !important; height:26px !important}
|
||||||
|
.topbar .brand-mini .sw-badge{gap:7px}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* ---------- 右上角汉堡按钮 + 软件抽屉 ---------- */
|
||||||
|
.sw-toggle{
|
||||||
|
flex:none; width:40px; height:40px; padding:0; margin-left:2px;
|
||||||
|
display:inline-flex; flex-direction:column; align-items:center; justify-content:center; gap:5px;
|
||||||
|
background:transparent; border:1px solid var(--line); border-radius:10px;
|
||||||
|
cursor:pointer;
|
||||||
|
}
|
||||||
|
.sw-toggle span{
|
||||||
|
display:block; width:17px; height:2px; border-radius:2px;
|
||||||
|
background:var(--fg); transition:transform .18s ease, opacity .18s ease;
|
||||||
|
}
|
||||||
|
.sw-toggle:hover{border-color:var(--brand); background:var(--brand-soft)}
|
||||||
|
.sw-toggle[aria-expanded="true"]{border-color:var(--brand); background:var(--brand-soft)}
|
||||||
|
/* 展开时变成 × */
|
||||||
|
.sw-toggle[aria-expanded="true"] span:nth-child(1){transform:translateY(7px) rotate(45deg)}
|
||||||
|
.sw-toggle[aria-expanded="true"] span:nth-child(2){opacity:0}
|
||||||
|
.sw-toggle[aria-expanded="true"] span:nth-child(3){transform:translateY(-7px) rotate(-45deg)}
|
||||||
|
|
||||||
|
.sw-panel{
|
||||||
|
border-top:1px solid var(--line);
|
||||||
|
background:var(--card);
|
||||||
|
box-shadow:0 8px 20px -12px rgba(20,30,50,.18);
|
||||||
|
}
|
||||||
|
.sw-panel .wrap{padding-top:14px; padding-bottom:16px}
|
||||||
|
.sw-panel-hd{
|
||||||
|
font-size:13.5px; font-weight:600; color:var(--muted);
|
||||||
|
margin-bottom:10px; letter-spacing:.2px;
|
||||||
|
}
|
||||||
|
.sw-panel-list{display:flex; flex-direction:column; gap:2px}
|
||||||
|
.sw-item{
|
||||||
|
display:flex; align-items:center; gap:10px;
|
||||||
|
padding:9px 10px; border-radius:10px; color:var(--fg);
|
||||||
|
}
|
||||||
|
.sw-item:hover{background:var(--bg, #f6f8fb); text-decoration:none; color:var(--fg)}
|
||||||
|
.sw-item.on{background:var(--brand-soft)}
|
||||||
|
.sw-item.on .sw-badge-nm{color:var(--brand); font-weight:700}
|
||||||
|
.sw-item-cur{
|
||||||
|
margin-left:auto; font-size:11.5px; font-weight:600; color:var(--brand);
|
||||||
|
background:var(--card); border:1px solid var(--brand);
|
||||||
|
padding:1px 8px; border-radius:99px;
|
||||||
|
}
|
||||||
|
@media (min-width:561px){
|
||||||
|
.sw-panel-list{flex-direction:row; flex-wrap:wrap; gap:8px}
|
||||||
|
.sw-item{padding:7px 12px; border:1px solid var(--line)}
|
||||||
|
.sw-item.on{border-color:var(--brand)}
|
||||||
|
.sw-item-cur{margin-left:4px}
|
||||||
}
|
}
|
||||||
.topbar .brand-text{overflow:hidden; text-overflow:ellipsis; white-space:nowrap}
|
.topbar .brand-text{overflow:hidden; text-overflow:ellipsis; white-space:nowrap}
|
||||||
.topbar .logo-mark{
|
.topbar .logo-mark{
|
||||||
@@ -139,14 +189,11 @@ main.wrap{padding-top:24px; padding-bottom:40px; min-height:60vh}
|
|||||||
overflow:hidden; text-overflow:ellipsis; white-space:nowrap;
|
overflow:hidden; text-overflow:ellipsis; white-space:nowrap;
|
||||||
}
|
}
|
||||||
.sw-badge-sm .sw-badge-nm{font-size:14px}
|
.sw-badge-sm .sw-badge-nm{font-size:14px}
|
||||||
.sw-badge-md .sw-badge-nm{font-size:17px}
|
.sw-badge-md .sw-badge-nm{font-size:19px}
|
||||||
.sw-badge-lg .sw-badge-nm{font-size:28px; font-weight:700}
|
.sw-badge-lg .sw-badge-nm{font-size:22px; font-weight:700}
|
||||||
/* 顶栏主标题:图标 + 「XX 反馈系统」,要明显大于正文 */
|
/* 顶栏主标题:比「选择软件」标签(13.5px)大两号 = 17px。
|
||||||
.sw-badge-brand .sw-badge-nm{font-size:22px; font-weight:700; letter-spacing:.2px}
|
* 之前给到 26px 反而比内容区标题还小,主次颠倒;这里保持克制。 */
|
||||||
@media (max-width:560px){
|
.sw-badge-brand .sw-badge-nm{font-size:17px; font-weight:700; letter-spacing:.2px}
|
||||||
/* 窄屏收一点,避免把「全部问题 / 管理后台」挤掉 */
|
|
||||||
.sw-badge-brand .sw-badge-nm{font-size:18px}
|
|
||||||
}
|
|
||||||
/* 页头副行:图标 + 软件名 */
|
/* 页头副行:图标 + 软件名 */
|
||||||
.page-sw-id{margin:0; display:flex; align-items:center}
|
.page-sw-id{margin:0; display:flex; align-items:center}
|
||||||
/* 提交页顶部的软件上下文条:同样无背景色,只留一行轻分隔 */
|
/* 提交页顶部的软件上下文条:同样无背景色,只留一行轻分隔 */
|
||||||
|
|||||||
@@ -103,16 +103,6 @@ fb_layout_head($sw ? fb_software_site_title($sw) : $headTitle, ['software' => $s
|
|||||||
<a class="btn primary" href="new.php<?php echo $sw ? '?sw=' . e(urlencode((string)$sw['slug'])) : ''; ?>">我要反馈</a>
|
<a class="btn primary" href="new.php<?php echo $sw ? '?sw=' . e(urlencode((string)$sw['slug'])) : ''; ?>">我要反馈</a>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="software-bar">
|
|
||||||
<span class="sw-label">选择软件:</span>
|
|
||||||
<div class="chips">
|
|
||||||
<?php foreach ($swList as $s): ?>
|
|
||||||
<a class="chip <?php echo ($sw && (int)$s['id'] === (int)$sw['id']) ? 'on' : ''; ?>"
|
|
||||||
href="<?php echo e(fb_qs(['sw' => (string)$s['slug'], 'cat' => null, 'page' => null]) ?: ('?sw=' . e(urlencode((string)$s['slug'])))); ?>"><?php echo fb_software_badge($s, 'sm'); ?></a>
|
|
||||||
<?php endforeach; ?>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div class="filters">
|
<div class="filters">
|
||||||
<div class="chips">
|
<div class="chips">
|
||||||
<a class="chip <?php echo $cat === '' ? 'on' : ''; ?>" href="<?php echo e(fb_qs(['cat' => null, 'page' => null]) ?: '?'); ?>">全部</a>
|
<a class="chip <?php echo $cat === '' ? 'on' : ''; ?>" href="<?php echo e(fb_qs(['cat' => null, 'page' => null]) ?: '?'); ?>">全部</a>
|
||||||
|
|||||||
+40
-3
@@ -55,8 +55,13 @@ function fb_layout_head($title, array $opt = []) {
|
|||||||
/* 顶栏品牌位:当前在哪个软件下,就显示「图标 + XX 反馈系统」。
|
/* 顶栏品牌位:当前在哪个软件下,就显示「图标 + XX 反馈系统」。
|
||||||
* 这是页面唯一的主标题 —— 多软件共用一套反馈系统,
|
* 这是页面唯一的主标题 —— 多软件共用一套反馈系统,
|
||||||
* 用户要一眼看清「我现在是在给哪个软件的反馈系统提问题」。
|
* 用户要一眼看清「我现在是在给哪个软件的反馈系统提问题」。
|
||||||
* 内容区不再重复一遍同样的文字,只保留「图标 + 软件名」。 */
|
* 内容区不再重复一遍同样的文字,只保留「图标 + 软件名」。
|
||||||
|
*
|
||||||
|
* 字号刻意比「选择软件」那个标签大一号左右(17px),
|
||||||
|
* 不再压过内容区标题 —— 之前给到 26px 反而比下面的字还小,
|
||||||
|
* 视觉上主次颠倒。 */
|
||||||
$curSw = isset($opt['software']) && is_array($opt['software']) ? $opt['software'] : null;
|
$curSw = isset($opt['software']) && is_array($opt['software']) ? $opt['software'] : null;
|
||||||
|
$swList = fb_softwares(true);
|
||||||
?>
|
?>
|
||||||
<?php if ($curSw): ?>
|
<?php if ($curSw): ?>
|
||||||
<a class="brand-mini" href="./" title="<?php echo e(fb_software_site_title($curSw)); ?>">
|
<a class="brand-mini" href="./" title="<?php echo e(fb_software_site_title($curSw)); ?>">
|
||||||
@@ -70,9 +75,41 @@ function fb_layout_head($title, array $opt = []) {
|
|||||||
<?php endif; ?>
|
<?php endif; ?>
|
||||||
<div class="spacer"></div>
|
<div class="spacer"></div>
|
||||||
<a class="navlink hide-sm" href="./">全部问题</a>
|
<a class="navlink hide-sm" href="./">全部问题</a>
|
||||||
<?php if (fb_admin_logged_in()): ?><a class="navlink" href="admin.php">管理后台</a><?php endif; ?>
|
<?php if (fb_admin_logged_in()): ?><a class="navlink hide-sm" href="admin.php">管理后台</a><?php endif; ?>
|
||||||
<a class="btn-mini" href="new.php">我要反馈</a>
|
<a class="btn-mini hide-sm" href="new.php">我要反馈</a>
|
||||||
|
|
||||||
|
<?php if (count($swList) > 1): ?>
|
||||||
|
<?php /* 软件切换收进右上角汉堡菜单:
|
||||||
|
* 原来平铺一行「选择软件:」+ 若干 chip,占掉一整行,
|
||||||
|
* 而且软件一多就把列表往下推。收进抽屉后页面更干净,
|
||||||
|
* 移动端也不用单独适配那排 chip。 */ ?>
|
||||||
|
<button type="button" class="sw-toggle" id="swToggle"
|
||||||
|
aria-label="切换软件" aria-expanded="false" aria-controls="swPanel">
|
||||||
|
<span></span><span></span><span></span>
|
||||||
|
</button>
|
||||||
|
<?php endif; ?>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
<?php if (count($swList) > 1): ?>
|
||||||
|
<div class="sw-panel" id="swPanel" hidden>
|
||||||
|
<div class="wrap">
|
||||||
|
<div class="sw-panel-hd">选择软件</div>
|
||||||
|
<div class="sw-panel-list">
|
||||||
|
<?php foreach ($swList as $s): ?>
|
||||||
|
<?php
|
||||||
|
$on = $curSw && (int)$s['id'] === (int)$curSw['id'];
|
||||||
|
$href = fb_qs(['sw' => (string)$s['slug'], 'cat' => null, 'page' => null]);
|
||||||
|
if ($href === '') { $href = '?sw=' . urlencode((string)$s['slug']); }
|
||||||
|
?>
|
||||||
|
<a class="sw-item<?php echo $on ? ' on' : ''; ?>" href="<?php echo e($href); ?>">
|
||||||
|
<?php echo fb_software_badge($s, 'md'); ?>
|
||||||
|
<?php if ($on): ?><span class="sw-item-cur">当前</span><?php endif; ?>
|
||||||
|
</a>
|
||||||
|
<?php endforeach; ?>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<?php endif; ?>
|
||||||
</header>
|
</header>
|
||||||
<main class="wrap">
|
<main class="wrap">
|
||||||
<?php
|
<?php
|
||||||
|
|||||||
+11
-7
@@ -335,13 +335,17 @@ function fb_software_badge($software, $size = 'md', $label = '') {
|
|||||||
$icon = fb_software_icon($software);
|
$icon = fb_software_icon($software);
|
||||||
$name = $label !== '' ? (string)$label : (string)$software['name'];
|
$name = $label !== '' ? (string)$label : (string)$software['name'];
|
||||||
|
|
||||||
/* 尺寸档位:
|
/* 尺寸档位(以「选择软件」标签的 13.5px 为基准,逐档放大):
|
||||||
* sm 软件选择器里的小标签
|
* sm 18px 图标 / 14px 字 软件选择器里的小标签
|
||||||
* md 一般位置
|
* md 26px 图标 / 19px 字 「选择软件」抽屉里的条目
|
||||||
* lg 内容区「图标 + 软件名」
|
* lg 40px 图标 / 22px 字 内容区「图标 + 软件名」
|
||||||
* brand 顶栏主标题,要显著大于正文,图标与「XX 反馈系统」一起放大 */
|
* brand 32px 图标 / 17px 字 顶栏主标题
|
||||||
$px = ['sm' => 18, 'md' => 26, 'lg' => 38, 'brand' => 46];
|
*
|
||||||
$fs = ['sm' => 14, 'md' => 19, 'lg' => 28, 'brand' => 32];
|
* 🔴 用户明确指出:顶栏标题的字号「比下面还小」是错的,但给到 26px 又太大。
|
||||||
|
* 折中标准 = 比「选择软件」那个 13.5px 标签大两号 ≈ 17px。
|
||||||
|
* 图标同比缩到 32px,别让图标压过文字。 */
|
||||||
|
$px = ['sm' => 18, 'md' => 26, 'lg' => 40, 'brand' => 32];
|
||||||
|
$fs = ['sm' => 14, 'md' => 19, 'lg' => 22, 'brand' => 17];
|
||||||
$box = isset($px[$size]) ? $px[$size] : 26;
|
$box = isset($px[$size]) ? $px[$size] : 26;
|
||||||
$fnt = isset($fs[$size]) ? $fs[$size] : 19;
|
$fnt = isset($fs[$size]) ? $fs[$size] : 19;
|
||||||
|
|
||||||
|
|||||||
@@ -161,17 +161,8 @@ fb_layout_head('我要反馈', ['robots' => 'noindex,follow', 'software' => $sw]
|
|||||||
|
|
||||||
<?php if ($sw): ?>
|
<?php if ($sw): ?>
|
||||||
<input type="hidden" name="software_id" value="<?php echo (int)$sw['id']; ?>">
|
<input type="hidden" name="software_id" value="<?php echo (int)$sw['id']; ?>">
|
||||||
<div class="field">
|
<?php /* 软件切换统一收到顶栏的汉堡菜单里,表单内不再平铺一排 chip ——
|
||||||
<span>所属软件 <b class="req">*</b><i class="hint">换软件会刷新下面的分类</i></span>
|
免得同一个选择在两个地方出现,用户不知道该点哪个。 */ ?>
|
||||||
<div class="chips">
|
|
||||||
<?php foreach ($swList as $one): ?>
|
|
||||||
<a class="chip <?php echo ((int)$one['id'] === $swId) ? 'on' : ''; ?>"
|
|
||||||
href="new.php?sw=<?php echo e(urlencode((string)$one['slug'])); ?>"><?php echo fb_software_badge($one, 'sm'); ?></a>
|
|
||||||
<?php endforeach; ?>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<?php elseif ($sw): ?>
|
|
||||||
<input type="hidden" name="software_id" value="<?php echo (int)$sw['id']; ?>">
|
|
||||||
<?php endif; ?>
|
<?php endif; ?>
|
||||||
|
|
||||||
<?php if ($cats): ?>
|
<?php if ($cats): ?>
|
||||||
|
|||||||
Reference in New Issue
Block a user