// ==UserScript== // @name 哔哩哔哩电脑网页版手机端适配优化脚本简洁版 // @namespace http://tampermonkey.net/ // @version 132.10 // @description B站电脑版网页手机端适配(CSS为主,JS只补CSS做不到的事)。通用:隐藏PC头部/侧栏/页脚,内置52px搜索栏(综合·直播·专栏·用户互切),全站两列卡片,禁止横向溢出。搜索页:+必含/-排除 屏蔽语法并显示过滤条数。视频·播放列表·番剧页:播放器16:9满宽、控制栏手机化、右滑呼出右侧列表、全屏同步。动态·话题·opus:卡片两列、评论区对齐。UP主空间:两列、信息卡固定屏内。直播间:只留播放器+聊天区,双击进出原生全屏,返回键先退全屏,控制栏只留时间与清晰度,遮罩铺满。 // @author YourName // @match *://*.bilibili.com/* // @grant none // @run-at document-start // @license All Rights Reserved // ==/UserScript== (function () { 'use strict'; /* ============================================================ 变更记录(精简后移到这里,@description 只留功能简介) ---- 直播间控制栏 / 遮罩 ---- v132.01 全屏点画面唤出的控制栏被底部 84px 空档顶起 → 按键贴屏幕底 v132.03 上一版顶掉了站内的 height / transform 状态通道,导致控制栏 弹出来不隐藏;改为只做 margin 位移补偿(偏移由 JS 实测), 收起行为完全交回站内 v132.05 站内遮罩层带 bottom:84px 让位,唤出瞬间先渲染在 84px 处, 补偿永远慢一拍 → 弃用该层,改由 #live-player::after 自建铺满式渐变遮罩(opacity 淡入) ---- 首屏零闪 ---- v132.06 顶部导航等改用不依赖 body class 的直播间独有选择器隐藏 v132.07 JS 兜底:脚本一执行即写行内 display:none + MutationObserver 盯住 DOM 节点一插入即藏;injectStyle 未就绪时改为重试 ---- 顶部栏 / 卡片 ---- v132.08 「排序」「切换」按钮改为只显示图标(36x36 正圆), 把横向空间全留给搜索框 v132.09 直播卡 UP主名行与综合页对齐(21px 高 + margin-top 4px, info 75→77、wrap→172) v132.10 修正 v132.09 引入的"UP 图标与名字分家":该行 width:100% 把名字格撑满且文字居中 → 改为 inline-flex 收缩到内容宽、 名字紧贴图标左对齐 ============================================================ */ const isHome = () => { const h = location.hostname, p = location.pathname; return (h === 'www.bilibili.com' || h === 'bilibili.com') && (p === '/' || p === '/index.html' || p === ''); }; const isVideoPage = () => location.hostname === 'www.bilibili.com' && /^\/video\//.test(location.pathname); // 收藏夹/合集播放列表页(/list/mlxxx、/medialist/play/mlxxx):DOM 与视频页同构,完整复用视频页优化 const isListPage = () => location.hostname === 'www.bilibili.com' && (/^\/list\//.test(location.pathname) || /^\/medialist\/play\//.test(location.pathname)); const isBangumiPage = () => location.hostname === 'www.bilibili.com' && /^\/bangumi\/play\//.test(location.pathname); const isTBiliDynamic = () => location.hostname === 't.bilibili.com'; const isOpusPage = () => { const h = location.hostname, p = location.pathname; return (h === 'www.bilibili.com' || h === 'bilibili.com') && (/^\/opus\//.test(p) || /^\/read\//.test(p)); }; const isSearchPage = () => location.hostname === 'search.bilibili.com'; const isSpacePage = () => location.hostname === 'space.bilibili.com'; // 直播间页(live.bilibili.com/房间号、live.bilibili.com/blanc/房间号) // 探针 bili_probe_2026-09-30_08-03-19 实测结构: // body.supportWebp > div.live-room-app > main.app-content(padding-top 74) // > div.app-body > section.player-and-aside-area // > #player-ctnr(#head-info-vm + .fullscreen-container-paddingbox > #fullscreen-container > .player-section / #gift-control-vm) // > #aside-area-vm(absolute 右侧:#rank-list-vm + .chat-history-panel + #chat-control-panel-vm) // > #sections-vm(动态/公告)> footer.link-footer // 只认房间号路径,直播中心 / 活动页等不处理 const isLiveRoomPage = () => { if (location.hostname !== 'live.bilibili.com') return false; const p = location.pathname; if (/^\/(live-center|studio|activity|blackboard|h5|p)(\/|$)/.test(p)) return false; return /^\/blanc\/\d+/.test(p) || /^\/\d+(\/|$)/.test(p); }; function installShadowRootPatch() { if (installShadowRootPatch._installed) return; installShadowRootPatch._installed = true; const originalAttachShadow = Element.prototype.attachShadow; Element.prototype.attachShadow = function(init) { const shadowRoot = originalAttachShadow.call(this, init); // 动态详情页(t.bilibili.com/xxx)与 opus 详情页(/opus/xxx)评论区 // 都与视频页同源(bili-comments),一并注入才能做到"与视频页完全一致" if (init.mode === 'open' && (isVideoPage() || isBangumiPage() || isListPage() || isTBiliDynamic() || isOpusPage())) { try { const style = document.createElement('style'); style.setAttribute('data-bili-mobile-hidden', 'true'); style.textContent = ` bili-comment-box, #commentbox { display: none !important; visibility: hidden !important; height: 0 !important; } #like, #dislike, #reply, #more { display: none !important; visibility: hidden !important; height: 0 !important; } bili-comments-vote-card, #vote { display: none !important; visibility: hidden !important; height: 0 !important; } bili-comments-header-renderer { margin-bottom: 0 !important; padding-bottom: 0 !important; } #header { margin-bottom: 0 !important; padding-bottom: 0 !important; } #contents { margin-top: 0 !important; padding-top: 0 !important; } `; shadowRoot.appendChild(style); } catch (e) {} } return shadowRoot; }; } function fixViewport() { const apply = () => { const root = document.head || document.documentElement; if (!root) return; let vp = document.querySelector('meta[name="viewport"]'); if (!vp) { vp = document.createElement('meta'); vp.name = 'viewport'; root.appendChild(vp); } const content = 'width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=no, viewport-fit=cover'; if (vp.getAttribute('content') !== content) { vp.setAttribute('content', content); } }; apply(); [0, 50, 200, 500, 1000, 2000, 5000].forEach(t => setTimeout(apply, t)); document.addEventListener('DOMContentLoaded', apply); window.addEventListener('load', apply); try { const obs = new MutationObserver(() => apply()); obs.observe(document.head || document.documentElement, { childList: true, subtree: true, attributes: true, attributeFilter: ['content'] }); } catch (e) {} } function injectStyle() { if (document.getElementById('bili-mobile-style')) return; const root = document.head || document.documentElement; // document-start 时 documentElement 可能还没建好 —— 这种情况下 // 必须重试,否则整份样式表永远注入不进来(首屏就会全裸) if (!root) { setTimeout(injectStyle, 0); return; } const style = document.createElement('style'); style.id = 'bili-mobile-style'; style.textContent = ` /* ===== 全局 ===== */ html, body { background-color: #ffffff !important; width: 100% !important; max-width: 100vw !important; min-width: 0 !important; overflow-x: hidden !important; margin: 0 !important; padding: 0 !important; overscroll-behavior-y: none !important; } html { background-color: #ffffff !important; } * { box-sizing: border-box !important; } body:not(.video-fullscreen) > * { max-width: 100vw !important; } .bili-header, .international-header, .mini-header, #biliMainHeader, .bili-header-m, .nav-menu { display: none !important; visibility: hidden !important; height: 0 !important; overflow: hidden !important; } #bili-header-container, .bili-header--mini, .bili-header--fixed { display: none !important; height: 0 !important; overflow: hidden !important; } /* ===== 自建搜索栏 ===== */ #my-bili-searchbar { position: fixed !important; top: 0 !important; left: 0 !important; right: 0 !important; width: 100% !important; max-width: 100vw !important; height: 52px !important; background: #ffffff !important; box-shadow: 0 1px 4px rgba(0,0,0,0.08) !important; z-index: 2147483646 !important; display: flex !important; align-items: center !important; padding: 0 10px !important; box-sizing: border-box !important; gap: 8px !important; } #my-bili-dynamic-btn { flex-shrink: 0 !important; display: flex !important; align-items: center !important; justify-content: center !important; height: 36px !important; padding: 0 10px !important; background: #f1f2f3 !important; border-radius: 18px !important; color: #18191c !important; text-decoration: none !important; cursor: pointer !important; white-space: nowrap !important; user-select: none !important; } #my-bili-dynamic-btn:active { background: #e3e5e7 !important; } #my-bili-dynamic-btn svg { width: 18px !important; height: 18px !important; flex-shrink: 0 !important; } #my-bili-searchbar .my-search-wrap { flex: 1 !important; display: flex !important; align-items: center !important; background: #f1f2f3 !important; border-radius: 20px !important; height: 36px !important; padding: 0 6px 0 14px !important; overflow: hidden !important; min-width: 0 !important; } #my-bili-searchbar #my-bili-search-input { flex: 1 !important; border: none !important; outline: none !important; background: transparent !important; font-size: 14px !important; color: #18191c !important; height: 100% !important; padding: 0 !important; margin: 0 !important; min-width: 0 !important; -webkit-appearance: none !important; appearance: none !important; } #my-bili-searchbar #my-bili-search-input::placeholder { color: #9499a0 !important; } #my-bili-searchbar .my-search-btn { width: 32px !important; height: 32px !important; border-radius: 50% !important; border: none !important; background: transparent !important; color: #61666d !important; display: flex !important; align-items: center !important; justify-content: center !important; cursor: pointer !important; padding: 0 !important; flex-shrink: 0 !important; } /* v132.08:只留左侧图标(文字与右侧小箭头都隐藏), 按钮收成正圆 36x36,把宽度全让给中间的搜索框。 aria-label 仍在,读屏与无障碍不受影响。 */ #my-bili-order-btn { flex-shrink: 0 !important; display: flex !important; align-items: center !important; justify-content: center !important; gap: 0 !important; width: 36px !important; min-width: 36px !important; max-width: 36px !important; height: 36px !important; padding: 0 !important; background: #f1f2f3 !important; border-radius: 50% !important; color: #18191c !important; font-size: 13px !important; cursor: pointer !important; white-space: nowrap !important; user-select: none !important; -webkit-tap-highlight-color: transparent !important; } #my-bili-order-btn:active { background: #e3e5e7 !important; } #my-bili-order-btn svg { width: 18px !important; height: 18px !important; flex-shrink: 0 !important; color: #61666d !important; } /* ===== 搜索页:「切换」按钮 + 展开行 ===== 展开/收起是纯 CSS:两个隐藏 checkbox 打头, :checked ~ 兄弟选择器控制下方那一行 display。 JS 只负责生成 HTML、互斥、点击外部收起、构造跳转链接。 */ .my-bili-menu-cb { position: absolute !important; width: 0 !important; height: 0 !important; opacity: 0 !important; pointer-events: none !important; margin: 0 !important; padding: 0 !important; border: none !important; appearance: none !important; -webkit-appearance: none !important; } #my-bili-switch-btn { flex-shrink: 0 !important; display: flex !important; align-items: center !important; justify-content: center !important; gap: 0 !important; width: 36px !important; min-width: 36px !important; max-width: 36px !important; height: 36px !important; padding: 0 !important; background: #f1f2f3 !important; border-radius: 50% !important; color: #18191c !important; font-size: 13px !important; cursor: pointer !important; white-space: nowrap !important; user-select: none !important; -webkit-tap-highlight-color: transparent !important; } #my-bili-switch-btn:active { background: #e3e5e7 !important; } #my-bili-switch-btn svg { width: 18px !important; height: 18px !important; flex-shrink: 0 !important; } /* ---- 只留图标:文字标签与右侧小箭头一并隐藏 ---- */ #my-bili-order-btn .order-label, #my-bili-switch-btn .switch-label, #my-bili-order-btn .my-bili-menu-caret, #my-bili-switch-btn .my-bili-menu-caret { display: none !important; width: 0 !important; height: 0 !important; margin: 0 !important; padding: 0 !important; overflow: hidden !important; } /* 小箭头没了,展开状态改由「底色 + 图标变蓝」表示,不占额外宽度 */ #my-bili-order-cb:checked ~ #my-bili-order-btn, #my-bili-switch-cb:checked ~ #my-bili-switch-btn { background: #e3e5e7 !important; } #my-bili-order-cb:checked ~ #my-bili-order-btn svg, #my-bili-switch-cb:checked ~ #my-bili-switch-btn svg { color: #00aeec !important; } /* 展开行:紧贴搜索框容器(52px)下方,高度与容器一致 52px */ .my-bili-menu-row { display: none !important; position: absolute !important; top: 52px !important; left: 0 !important; right: 0 !important; width: 100% !important; height: 52px !important; padding: 0 10px !important; box-sizing: border-box !important; background: #ffffff !important; box-shadow: 0 2px 6px rgba(0,0,0,0.10) !important; align-items: center !important; gap: 8px !important; z-index: 1 !important; } #my-bili-order-cb:checked ~ #my-bili-order-row, #my-bili-switch-cb:checked ~ #my-bili-switch-row { display: flex !important; } .my-bili-menu-item { flex: 1 1 0 !important; min-width: 0 !important; height: 36px !important; display: flex !important; align-items: center !important; justify-content: center !important; background: #f1f2f3 !important; border-radius: 18px !important; color: #61666d !important; font-size: 13px !important; text-decoration: none !important; cursor: pointer !important; white-space: nowrap !important; overflow: hidden !important; -webkit-tap-highlight-color: transparent !important; } .my-bili-menu-item:active { background: #e3e5e7 !important; } /* 当前所在的那个分类 / 排序:高亮 */ .my-bili-menu-item.is-current { background: #00aeec !important; color: #ffffff !important; font-weight: 600 !important; } /* ============================================================ ========== 首页 ========== ============================================================ */ body.bili-home-page { padding-top: 52px !important; } body.bili-home-page .banner, body.bili-home-page .bili-banner, body.bili-home-page .carousel, body.bili-home-page .carousel-container, body.bili-home-page .carousel-area, body.bili-home-page .carousel-area-img, body.bili-home-page .recommend-banner, body.bili-home-page [class*="carousel"], body.bili-home-page [class*="vui_carousel"], body.bili-home-page .recommended-swipe, body.bili-home-page .recommended-swipe-body, body.bili-home-page .recommended-swipe-body-normal, body.bili-home-page .floor, body.bili-home-page .bili-floor, body.bili-home-page .floor-single-card, body.bili-home-page .fixed-sidebar, body.bili-home-page .go-top, body.bili-home-page .bili-fixed-sidebar, body.bili-home-page .footer, body.bili-home-page .bili-footer, body.bili-home-page .international-footer, body.bili-home-page .mini-footer, body.bili-home-page .ad-report, body.bili-home-page .ad-floor, body.bili-home-page .channel-menu, body.bili-home-page .nav-channel, body.bili-home-page .bili-header__channel, body.bili-home-page .bili-header__channel-sticky, body.bili-home-page .header-channel, body.bili-home-page .bili-header-channel, body.bili-home-page .nav-channel-list, body.bili-home-page [class*="channel"][class*="header"], body.bili-home-page [class*="header"][class*="channel"], body.bili-home-page .header-nav, body.bili-home-page .nav-bar, body.bili-home-page .roll-btn, body.bili-home-page .roll-btn-text, body.bili-home-page .feed-roll-btn, body.bili-home-page [class*="roll-btn"], body.bili-home-page .bili-header__menu, body.bili-home-page .bili-header__bar, body.bili-home-page .bili-header-banner-img, body.bili-home-page .banner-img, body.bili-home-page .animated-banner, body.bili-home-page .taper-line, body.bili-home-page .palette-button-outer, body.bili-home-page .palette-feed4, body.bili-home-page [class*="right-side"], body.bili-home-page [class*="right-bar"], body.bili-home-page [class*="right-tool"], body.bili-home-page [class*="side-tool"], body.bili-home-page [class*="toolbar"], body.bili-home-page [class*="feedback"], body.bili-home-page [class*="customer-service"], body.bili-home-page [class*="service-btn"], body.bili-home-page [class*="back-top"], body.bili-home-page [class*="goto-top"], body.bili-home-page [class*="to-top"], body.bili-home-page .go-top, body.bili-home-page .bili-go-top { display: none !important; visibility: hidden !important; height: 0 !important; min-height: 0 !important; padding: 0 !important; margin: 0 !important; overflow: hidden !important; } body.bili-home-page .container, body.bili-home-page .container.is-version8, body.bili-home-page .recommended-container_floor-aside .container { display: grid !important; grid-template-columns: repeat(2, minmax(0, 1fr)) !important; grid-grid-gap: 8px !important; gap: 8px !important; width: 100% !important; max-width: 100% !important; padding: 8px !important; margin: 0 !important; background-color: #f1f2f3 !important; box-sizing: border-box !important; align-items: start !important; align-content: start !important; grid-auto-rows: auto !important; } body.bili-home-page .bili-feed4, body.bili-home-page .bili-feed4-layout, body.bili-home-page .feed2, body.bili-home-page .recommended-container_floor-aside { width: 100% !important; max-width: 100% !important; padding: 0 !important; margin: 0 !important; box-sizing: border-box !important; } body.bili-home-page .bili-feed4 * { max-width: 100% !important; } body.bili-home-page .container > .feed-card, body.bili-home-page .container > .bili-feed-card { display: contents !important; } body.bili-home-page .container > .feed-card:not(:has(.bili-video-card__wrap)):not(:has(.bili-live-card__wrap)), body.bili-home-page .container > .bili-feed-card:not(:has(.bili-video-card__wrap)):not(:has(.bili-live-card__wrap)), body.bili-home-page .container > .feed-card:has(.bili-video-card__info--ad), body.bili-home-page .container > .feed-card:has(.bili-video-card__info--creative-ad), body.bili-home-page .container > .feed-card:has([href^="//cm.bilibili.com/cm/api/"]), body.bili-home-page .container > .bili-feed-card:has(.bili-video-card__info--ad), body.bili-home-page .container > .bili-feed-card:has(.bili-video-card__info--creative-ad), body.bili-home-page .container > .bili-feed-card:has([href^="//cm.bilibili.com/cm/api/"]) { display: none !important; } /* ============================================================ ========== 搜索页 ========== ============================================================ */ html:has(body.bili-search-page), body.bili-search-page { width: 100vw !important; max-width: 100vw !important; min-width: 0 !important; overflow-x: hidden !important; padding: 0 !important; margin: 0 !important; background-color: #f1f2f3 !important; } body.bili-search-page { padding-top: 52px !important; } /* ===== 搜索页容器链统一背景色(v131.74)===== body.bili-search-page 早已是 #f1f2f3,但专栏页 / 用户页的中间容器 (.search-content / .search-page 等)自带白色背景把它盖住了, 结果加上的白卡与页面同色、完全看不出来。 综合页之所以正常,是因为它挂了 B站原生的 .search-content--gray。 这里把整条容器链(含综合页)统一强制成同一个 #f1f2f3, 既让专栏页白卡凸显,也保证与综合页字面一致。 ⚠ 只作用于容器,不碰 .media-list / .video-list / 卡片本体, 否则会把刚加的白卡也刷成灰色。 ---- */ html body.bili-search-page #app, html body.bili-search-page #app > div, html body.bili-search-page #app .search-layout, html body.bili-search-page #app .search-layout.clearfix, html body.bili-search-page #app .search-layout.clearfix > div, html body.bili-search-page #app .search-content, html body.bili-search-page #app .search-content--gray, html body.bili-search-page #app .search-content--gray.search-content, html body.bili-search-page #app .search-page-wrapper, html body.bili-search-page #app .search-page, html body.bili-search-page #app .search-page.search-page-all, html body.bili-search-page #app .search-page.search-page-article, html body.bili-search-page #app .search-page.search-page-upuser, html body.bili-search-page #app .search-page.search-page-live, html body.bili-search-page #app .search-page > div, html body.bili-search-page #app .video.i_wrapper, html body.bili-search-page #app .video.i_wrapper.search-all-list, body.bili-search-page #app, body.bili-search-page #app > div, body.bili-search-page .search-layout, body.bili-search-page .search-layout > div, body.bili-search-page .search-content, body.bili-search-page .search-content--gray, body.bili-search-page .search-page-wrapper, body.bili-search-page .search-page, body.bili-search-page .search-page > div, body.bili-search-page .video.i_wrapper, body.bili-search-page .video.i_wrapper.search-all-list { background: #f1f2f3 !important; background-color: #f1f2f3 !important; background-image: none !important; } /* ===== 用户搜索页(/upuser):隐藏原生排序与筛选按钮区 ===== 探针实测:.search-page-upuser > div:nth-of-type(1) > .search-conditions.mt_lg(360x222,含 mt 20) ├─ .conditions-order(默认排序/粉丝数由高到低/由低到高/ │ Lv等级由高到低/由低到高 + 更多筛选) └─ .more-conditions(全部用户/UP主用户/普通用户/认证用户) 整块吃掉 242px,隐藏后第一个用户卡片直接顶上来。 只作用于 .search-page-upuser,不影响综合/直播/专栏页。 ---- */ body.bili-search-page .search-page-upuser .search-conditions, body.bili-search-page .search-page-upuser .search-conditions.mt_lg, body.bili-search-page .search-page-upuser .conditions-order, body.bili-search-page .search-page-upuser .more-conditions, body.bili-search-page .search-page-upuser .condition-row, body.bili-search-page .search-page-upuser .i_button_more { display: none !important; visibility: hidden !important; width: 0 !important; height: 0 !important; min-height: 0 !important; max-height: 0 !important; padding: 0 !important; margin: 0 !important; border: none !important; overflow: hidden !important; } /* 外层那个包着 conditions 的空壳 div 也一起收掉,避免残留 20px mt */ body.bili-search-page .search-page-upuser > div:nth-of-type(1) { padding: 0 !important; margin: 0 !important; min-height: 0 !important; height: auto !important; } /* ===== 用户搜索页卡片:左右边距统一 8px(v131.71)===== 实测(360 屏,.search-page-upuser): .col_6 left=8 w=344 → 距屏幕左 8、距屏幕右 8 a.mr_md(头像) left=8 w=86 → 头像左边距 8 ✓ .user-content left=109 w=243 → 盒子右边 352,距屏幕右 8 但 .pr_md 自带 padding-right 15px, 里面的 h2 / user-actions 实际只到 337 → 距屏幕右 23px 所以「头像距左 8px」与「文字距右 23px」并不相等。 这里把 .pr_md 的 padding-right 归零,文字右边界回到 352(距右 8px), 与头像左边距 8px 完全一致。 ---- */ html body.bili-search-page #app .search-page-upuser .b-user-info-card, body.bili-search-page .search-page-upuser .b-user-info-card { width: 100% !important; max-width: 100% !important; min-width: 0 !important; padding-left: 0 !important; margin-left: 0 !important; margin-right: 0 !important; box-sizing: border-box !important; } html body.bili-search-page #app .search-page-upuser .b-user-info-card .user-content, html body.bili-search-page #app .search-page-upuser .b-user-info-card .user-content.pr_md, body.bili-search-page .search-page-upuser .b-user-info-card .user-content, body.bili-search-page .search-page-upuser .b-user-info-card .user-content.pr_md { padding-right: 0 !important; min-width: 0 !important; box-sizing: border-box !important; } /* ===== 用户搜索页分页条:上间距 = 下间距 = 8px(v131.71)===== 实测滚动到底时(#app top=-2954,页高 3754 = 屏高 800 + 滚动量): 最后一个用户卡片 bottom=710 + 卡片 margin-bottom 16 (.mb_x60 被规则3改成 16) + .media-list padding-bottom 8 + 分页条 margin-top 8 ([class*="mt_x50"]) = 分页条 top 742 → 距最后一张卡片 32px 分页条 bottom=792,+ margin-bottom 8 = 内容底 800 → 距屏幕底 8px 上下不对称(32 vs 8),这里把上方压到 8: 最后一个卡片 mb → 0、列表容器 pb → 0、分页条 mt 保持 8 = 710 + 0 + 0 + 8 = 718,间距 8px,与距屏幕底的 8px 相等。 只去掉「最后一个」卡片的下边距,卡片之间的 16px 间距不动。 ---- */ html body.bili-search-page #app .search-page-upuser .media-list > [class*="col_"]:last-child, html body.bili-search-page #app .search-page-upuser .media-list > [class*="col_md_"]:last-child, body.bili-search-page .search-page-upuser .media-list > [class*="col_"]:last-child, body.bili-search-page .search-page-upuser .media-list > [class*="col_md_"]:last-child { margin-bottom: 0 !important; } html body.bili-search-page #app .search-page-upuser .media-list, body.bili-search-page .search-page-upuser .media-list { padding-bottom: 0 !important; } html body.bili-search-page #app .search-page-upuser .mt_x50.mb_lg, html body.bili-search-page #app .search-page-upuser .flex_center.mt_x50, body.bili-search-page .search-page-upuser .mt_x50.mb_lg, body.bili-search-page .search-page-upuser .flex_center.mt_x50 { margin-top: 8px !important; margin-bottom: 8px !important; } /* ============================================================ ===== 专栏搜索页(/article)v131.72 ===== 三件事,与用户页(/upuser)同一套口径: 1) 隐藏原生排序区 2) 卡片「封面距左」「文字距右」都统一 8px 3) 分页条上间距 = 下间距 = 8px ============================================================ */ /* ---- 1. 隐藏原生排序区 ---- 探针实测(.search-page-article,360 屏): > div:nth-of-type(1) [360x126] └─ .search-conditions.mt_lg [360x96] mt=20 └─ .conditions-order.flex_between.mb_sm mb=10 ├─ .condition-row [260x96] 综合排序/最新发布/最多点击/最多喜欢/最多评论 └─ .i_button_more [100x34] 更多筛选 126 = 20(mt) + 96 + 10(mb 穿透),整块隐藏后归零, 内容区 div:nth-of-type(2) 从 top=178 直接顶到 52。 ⚠ 专栏页没有 .more-conditions(那是用户页才有的类型筛选), 所以这里只处理 conditions-order 这一支。 ---- */ html body.bili-search-page #app .search-page-article .search-conditions, html body.bili-search-page #app .search-page-article .search-conditions.mt_lg, html body.bili-search-page #app .search-page-article .conditions-order, html body.bili-search-page #app .search-page-article .condition-row, html body.bili-search-page #app .search-page-article .i_button_more, body.bili-search-page .search-page-article .search-conditions, body.bili-search-page .search-page-article .search-conditions.mt_lg, body.bili-search-page .search-page-article .conditions-order, body.bili-search-page .search-page-article .condition-row, body.bili-search-page .search-page-article .i_button_more { display: none !important; visibility: hidden !important; width: 0 !important; height: 0 !important; min-height: 0 !important; max-height: 0 !important; padding: 0 !important; margin: 0 !important; border: none !important; overflow: hidden !important; } /* 外壳 div 一起收掉,避免 20px mt / 10px mb 穿透留下残高 */ html body.bili-search-page #app .search-page-article > div:nth-of-type(1), body.bili-search-page .search-page-article > div:nth-of-type(1) { padding: 0 !important; margin: 0 !important; min-height: 0 !important; height: auto !important; } /* ---- 2. 卡片左右边距统一 8px ---- 实测:.col_6 left=8 w=344(距左 8、距右 8) .article-banner(封面) left=8 w=154 → 距左 8 ✓ .article-content.pr_md left=174 w=178 → 盒子右边 352(距右 8) 但 .pr_md 自带 padding-right 15px(178-163=15), 里面的 h2 / .atc-desc 实际只到 337 → 距右 23px ✗ 把 padding-right 归零,文字右边界回到 352,与封面左边距 8px 对称。 ---- */ html body.bili-search-page #app .search-page-article .b-article-card, body.bili-search-page .search-page-article .b-article-card { width: 100% !important; max-width: 100% !important; min-width: 0 !important; padding-left: 0 !important; margin-left: 0 !important; margin-right: 0 !important; box-sizing: border-box !important; } html body.bili-search-page #app .search-page-article .b-article-card .article-content, html body.bili-search-page #app .search-page-article .b-article-card .article-content.pr_md, body.bili-search-page .search-page-article .b-article-card .article-content, body.bili-search-page .search-page-article .b-article-card .article-content.pr_md { /* v131.79:右侧留 4px,别让文字贴着白卡边缘。 卡片右边界 352(屏幕 360 - 8),文字内容右边界因此是 348, 距屏幕 12px。原生 .pr_md 是 15px,之前为了「左右统一 8px」 被归零,现在白卡有了,贴边确实难看,补 4px 收一点。 注意:内容区因此窄了 4px(178 → 174), h2 / atc-desc / atc-author 都会更早触发省略, atc-author 那行靠 2d 的 flex 收缩自动吸收,不会溢出。 */ padding-right: 4px !important; /* 综合页视频卡的文字区带上下 8px padding,这里同样补上: .article-content 是 align-items:stretch 撑满卡片高度的, 配合 border-box 加上下 padding 后盒子高度不变,卡片不会被撑高。 */ padding-top: 8px !important; padding-bottom: 8px !important; min-width: 0 !important; box-sizing: border-box !important; } /* ---- 2a2. 卡片之间的间距 16 → 8(v131.76)---- 上面的通用规则把 .col_6 / .col_md_4 的 margin-bottom 钉成 16px (那条是给番剧垂搜页定的:卡片间距 = 距屏幕左右边距 = 16)。 专栏页实测间距 16(卡片 bottom 191 → 下一张 top 207), 与用户页 8、综合页 8 不一致,这里在专栏页作用域内压回 8px。 特异性 (1,3,3) > 通用规则的 (1,2,3),能覆盖。 ⚠ 最后一个卡片仍是 0(下面第 3 组的 :last-child 规则), 所以「分页条距最后一张卡片 = 8」不受影响。 ---- */ html body.bili-search-page #app .search-page-article .media-list [class*="col_6"], html body.bili-search-page #app .search-page-article .media-list [class*="col_md_4"], html body.bili-search-page #app .search-page-article .media-list .mb_x40, html body.bili-search-page #app .search-page-article .media-list > div, body.bili-search-page .search-page-article .media-list [class*="col_6"], body.bili-search-page .search-page-article .media-list [class*="col_md_4"], body.bili-search-page .search-page-article .media-list .mb_x40, body.bili-search-page .search-page-article .media-list > div { margin-bottom: 8px !important; margin-top: 0 !important; } /* ---- 2b. 专栏卡片白卡皮肤:照抄综合页 .bili-video-card ---- 综合页视频卡(探针 .search-page-all,360 屏): .bili-video-card [168x172] background: #ffffff border: none border-radius: 8px box-shadow: 0 1px 3px rgba(0,0,0,0.08) overflow: hidden 专栏卡(探针 .search-page-article): .b-article-card [344x116] flex 横排 ├─ .article-banner [154x116] 封面(贴左、贴上下) └─ .article-content [178x116] 标题 + 摘要 ⚠ 只加背景,不加内边距:卡片本身已占满 344(屏幕左右各 8px), 再加 padding 会把内容推成 16px,破坏上一轮「左右统一 8px」的约定。 封面贴边被圆角裁切,与综合页封面被裁的效果一致。 ---- */ html body.bili-search-page #app .search-page-article .b-article-card, html body.bili-search-page #app .search-page-article .b-article-card.b-article-card, body.bili-search-page .search-page-article .b-article-card, body.bili-search-page .search-page-article .b-article-card.b-article-card { background: #ffffff !important; border: none !important; border-radius: 8px !important; box-shadow: 0 1px 3px rgba(0,0,0,0.08) !important; overflow: hidden !important; box-sizing: border-box !important; position: relative !important; } /* 封面:四角都给 8px 圆角(v131.76 改为全圆角)。 上一版只给了左两角(8px 0 0 8px),右边缘是直角, 与右侧文字区的留白风格不搭,现在四角统一。 封面内的 a / picture / img 是绝对定位铺满的(见 2c), 靠 .article-banner 的 overflow: hidden 裁出圆角。 ---- */ html body.bili-search-page #app .search-page-article .article-banner, body.bili-search-page .search-page-article .article-banner { border-radius: 8px !important; overflow: hidden !important; box-sizing: border-box !important; } /* ---- 2c. 卡片高度 = 封面图片高度(v131.75 重写)---- ❌ v131.74 为什么没生效: 给 .article-banner 写了 height: 100%!important。 flex 项只有在交叉轴尺寸是 auto 时才会 stretch, 而 100% 不是 auto → stretch 被禁用;百分比又算不出来 (卡片高度 auto,不确定)→ 回落到 B站原生的 116px。 同时文字区被我加了 8+8 padding,内容 115 + 16 = 131, 卡片 = max(封面 116, 文字 131) = 131。 结果 卡片 131 ≠ 封面 116,封面底下露出 15px 白边。 探针实测(20 张卡全部如此):卡片 131 / 封面 116。 ✅ 正确做法:反过来让「封面跟着卡片长」,两边恒等。 a) 封面 align-self: stretch + height: auto → 封面高度 = 卡片交叉尺寸,永远等于卡片高度 b) 封面内 a / picture / img 全部绝对定位铺满(top/right/bottom/left:0) → 图片高度 = 封面高度,且内容脱离文档流后 封面自身不再贡献高度(假设交叉尺寸 = 0), 卡片高度就只由「文字区」和 min-height 116 决定 c) img 用 object-fit: cover,拉高不变形 d) 文字区 align-self: stretch,撑满即可,不额外顶高 结果:卡片 = max(116, 文字) → 封面 stretch 到同值,两者恒等。 文字多 → 卡片 131、封面 131;文字少 → 都是 116。 ---- */ html body.bili-search-page #app .search-page-article .b-article-card, body.bili-search-page .search-page-article .b-article-card { align-items: stretch !important; min-height: 116px !important; } html body.bili-search-page #app .search-page-article .article-banner, body.bili-search-page .search-page-article .article-banner { /* 关键:height 必须是 auto,stretch 才会生效(100% 会禁用 stretch) */ height: auto !important; align-self: stretch !important; min-height: 116px !important; max-height: none !important; flex-shrink: 0 !important; position: relative !important; } /* 图片整条链绝对定位铺满封面:图片高度 = 封面高度 = 卡片高度 */ html body.bili-search-page #app .search-page-article .article-banner > a, html body.bili-search-page #app .search-page-article .article-banner a, html body.bili-search-page #app .search-page-article .article-banner picture, body.bili-search-page .search-page-article .article-banner > a, body.bili-search-page .search-page-article .article-banner a, body.bili-search-page .search-page-article .article-banner picture { position: absolute !important; top: 0 !important; right: 0 !important; bottom: 0 !important; left: 0 !important; display: block !important; width: 100% !important; height: 100% !important; min-height: 0 !important; max-height: none !important; margin: 0 !important; padding: 0 !important; overflow: hidden !important; box-sizing: border-box !important; } html body.bili-search-page #app .search-page-article .article-banner img, body.bili-search-page .search-page-article .article-banner img { position: absolute !important; top: 0 !important; right: 0 !important; bottom: 0 !important; left: 0 !important; display: block !important; width: 100% !important; height: 100% !important; min-height: 0 !important; max-height: none !important; margin: 0 !important; padding: 0 !important; object-fit: cover !important; box-sizing: border-box !important; } /* 文字区撑满卡片高度即可,不要额外把卡片顶高 */ html body.bili-search-page #app .search-page-article .b-article-card .article-content, body.bili-search-page .search-page-article .b-article-card .article-content { align-self: stretch !important; height: auto !important; max-height: none !important; overflow: hidden !important; } /* ---- 2d. UP主名 + 日期行(.atc-author)不超出卡片(v131.78)---- ❌ v131.76 / v131.77 改错了元素: 改的是 p.atc-info(「日常 · 0点赞 · 评论」那行), 而 UP主名 · 日期 其实在 div.atc-author,两者是不同的兄弟节点。 所以前两版对这行的溢出毫无作用(.atc-info 本来就不溢出)。 真实结构(含隐藏节点的探针,20 张卡一致): div.atc-author.text_ellipsis.flex_start.d_flex.fs_5 [178x16] │ B站自己就是 flex 容器 + overflow:hidden ├─ a.flex_start.flex_inline.text3 [132x18] UP主名 │ ├─ svg.author-icon.mr_2 [0x18] (宽度 0,无可见图标) │ └─ span.lh_xs [130x13] 名字文本 └─ span.text3.ml_4 [45x16] "· 09-26" 日期 溢出实测(20 张卡中 5 张): .atc-author left=174 w=178 → 右边界 352(= 卡片右边界) 名字 a[132] + ml_4(4) + 日期[45] = 181 > 178 → 日期 right=355,超出卡片 3px,被 overflow:hidden 硬裁掉 ⚠ 为什么 B站自带的 .text_ellipsis 没生效: text-overflow 只对「块容器」有效,而 .atc-author 是 flex 容器, 省略号不会渲染,只能硬裁。所以必须在「名字」这一层做省略号。 ✅ 做法:让名字可收缩、日期固定不收缩 a) .atc-author 锁 nowrap + overflow hidden(兜底,任何情况不溢出) b) 名字 :flex 0 1 auto + min-width 0 → 空间不够时收缩 c) 名字内 span.lh_xs:作为 flex 项会被块级化, 此时给它 ellipsis 就能渲染「…」,名字变「做一个莫得感情的彩…」 d) 日期 span.text3.ml_4:flex 0 0 auto,永不收缩,日期完整保留 名字短时(如卡2/3/10)本来就不溢出,不会有任何变化。 ---- */ html body.bili-search-page #app .search-page-article .atc-author, html body.bili-search-page #app .search-page-article .b-article-card .atc-author, html body.bili-search-page #app .search-page-article .article-content .atc-author, body.bili-search-page .search-page-article .atc-author, body.bili-search-page .search-page-article .b-article-card .atc-author, body.bili-search-page .search-page-article .article-content .atc-author { display: flex !important; flex-direction: row !important; flex-wrap: nowrap !important; align-items: center !important; width: 100% !important; max-width: 100% !important; min-width: 0 !important; overflow: hidden !important; box-sizing: border-box !important; margin-left: 0 !important; margin-right: 0 !important; } /* 名字链接:唯一可收缩的项 */ html body.bili-search-page #app .search-page-article .atc-author > a, body.bili-search-page .search-page-article .atc-author > a { display: flex !important; flex: 0 1 auto !important; min-width: 0 !important; max-width: 100% !important; overflow: hidden !important; box-sizing: border-box !important; } /* 名字文本:flex 项 → 块级化 → ellipsis 生效 */ html body.bili-search-page #app .search-page-article .atc-author > a > span, html body.bili-search-page #app .search-page-article .atc-author > a .lh_xs, body.bili-search-page .search-page-article .atc-author > a > span, body.bili-search-page .search-page-article .atc-author > a .lh_xs { display: block !important; flex: 0 1 auto !important; min-width: 0 !important; max-width: 100% !important; overflow: hidden !important; white-space: nowrap !important; text-overflow: ellipsis !important; box-sizing: border-box !important; } /* 名字里的图标:宽度已是 0,防止它占位影响收缩 */ html body.bili-search-page #app .search-page-article .atc-author > a > svg, body.bili-search-page .search-page-article .atc-author > a > svg { flex: 0 0 auto !important; max-width: 18px !important; } /* 日期:永不收缩,完整显示「· 09-26」 */ html body.bili-search-page #app .search-page-article .atc-author > span, html body.bili-search-page #app .search-page-article .atc-author .ml_4, body.bili-search-page .search-page-article .atc-author > span, body.bili-search-page .search-page-article .atc-author .ml_4 { display: block !important; flex: 0 0 auto !important; min-width: 0 !important; max-width: none !important; overflow: visible !important; white-space: nowrap !important; text-overflow: clip !important; box-sizing: border-box !important; } /* ---- 3. 分页条:上间距 = 下间距 = 8px ---- 探针未滚动,用文档坐标推算(#app top=52,文档底 2900,屏高 800): 最后一张专栏卡片 bottom = 2810 + 卡片 mb 16 (.mb_x40 被规则3改成 16) + .media-list pb 8 + 分页条 mt 8 ([class*="mt_x50"]) = 分页条 top 2842 → 距最后一张卡片 32px 分页条 bottom 2892 + mb 8 = 2900(文档底) 滚到底时距屏幕底 = 8px 上下不对称(32 vs 8)。压上方: 最后一个卡片 mb→0、media-list pb→0、分页条 mt 保持 8 = 2810 + 8 = 2818,间距 8px,与距屏幕底 8px 相等。 只改「最后一个」卡片,卡片之间的 16px 不动。 ---- */ html body.bili-search-page #app .search-page-article .media-list > [class*="col_"]:last-child, html body.bili-search-page #app .search-page-article .media-list > [class*="col_md_"]:last-child, body.bili-search-page .search-page-article .media-list > [class*="col_"]:last-child, body.bili-search-page .search-page-article .media-list > [class*="col_md_"]:last-child { margin-bottom: 0 !important; } html body.bili-search-page #app .search-page-article .media-list, body.bili-search-page .search-page-article .media-list { padding-bottom: 0 !important; } html body.bili-search-page #app .search-page-article .mt_x50.mb_lg, html body.bili-search-page #app .search-page-article .flex_center.mt_x50, body.bili-search-page .search-page-article .mt_x50.mb_lg, body.bili-search-page .search-page-article .flex_center.mt_x50 { margin-top: 8px !important; margin-bottom: 8px !important; } /* ============================================================ ===== 直播搜索页(/live)v131.80 ===== 探针实测(360 屏,.search-page-live,文档高 1710): div.mt_xxl.live-condition.mt_lg [360x32] top=52 全部/主播/直播间 div:nth-of-type(2) └─ div.mt_xxl.live-user.mt_xl [360x606] top=114 mt=30 ├─ h1.b_text.flex_between [360x34] top=114 主播 共找到… 查看更多 └─ div.live-user-cards.row.mt_lg left=-8 w=360 top=168 mt=20 └─ div.col_6.col_md_4 left=-8 w=360 h=138 └─ div.b-user-live-card [344x86] left=0 mb=52 └─ div.live-room.mt_sm [360x966] top=730 ├─ h1.room-header [360x60] top=730 直播间 排序… └─ div.live-room-cards.row.mt_lg left=-8 w=360 top=810 └─ div.video-list-item.col_3… [90x118] 4 列 └─ div.bili-live-card [74x86] div.mt_x50.mb_lg.flex_center [360x50] top=1704 分页条 ⚠ 关键:两个 .row 容器实测 left=-8 w=360(右边界 352), 整体比父容器左移了 8px,导致卡片距屏幕左 0、距右 16,不对称。 所以先把 row 的负 margin 归零,再由容器 padding 提供左右 8px。 ============================================================ */ /* ---- 1. 隐藏「全部 / 主播 / 直播间」切换行([360x32])---- */ html body.bili-search-page #app .search-page-live .live-condition, html body.bili-search-page #app .search-page-live .live-condition.mt_xxl, html body.bili-search-page #app .search-page-live .live-condition.mt_lg, body.bili-search-page .search-page-live .live-condition, body.bili-search-page .search-page-live .live-condition.mt_xxl, body.bili-search-page .search-page-live .live-condition.mt_lg { display: none !important; visibility: hidden !important; width: 0 !important; height: 0 !important; min-height: 0 !important; max-height: 0 !important; padding: 0 !important; margin: 0 !important; border: none !important; overflow: hidden !important; } /* ---- 2. 整个主播区 .live-user 隐藏(v131.81 改)---- v131.80 只隐藏了里面的 h1 标题,4 张用户卡还在; 用户确认主播卡也不需要 → 整块(含 h1「主播 · 共找到1000+个结果 · 查看更多」)隐藏。 (下面第 3~5 组给主播卡加的白卡 / 间距规则因此全部失效,留着无副作用。) ---- */ html body.bili-search-page #app .search-page-live .live-user, html body.bili-search-page #app .search-page-live .live-user.mt_xxl, html body.bili-search-page #app .search-page-live .live-user.mt_xl, body.bili-search-page .search-page-live .live-user, body.bili-search-page .search-page-live .live-user.mt_xxl, body.bili-search-page .search-page-live .live-user.mt_xl { display: none !important; visibility: hidden !important; width: 0 !important; height: 0 !important; min-height: 0 !important; max-height: 0 !important; padding: 0 !important; margin: 0 !important; border: none !important; overflow: hidden !important; } /* ---- 3. 主播区:容器归位(row 负 margin 清零)+ 顶部/左右 8px ---- */ html body.bili-search-page #app .search-page-live .live-user, html body.bili-search-page #app .search-page-live .live-user.mt_xxl, body.bili-search-page .search-page-live .live-user, body.bili-search-page .search-page-live .live-user.mt_xxl { margin-top: 0 !important; margin-bottom: 0 !important; width: 100% !important; max-width: 100% !important; min-width: 0 !important; } html body.bili-search-page #app .search-page-live .live-user-cards, html body.bili-search-page #app .search-page-live .live-user-cards.row, html body.bili-search-page #app .search-page-live .live-user-cards.row.mt_lg, body.bili-search-page .search-page-live .live-user-cards, body.bili-search-page .search-page-live .live-user-cards.row, body.bili-search-page .search-page-live .live-user-cards.row.mt_lg { display: block !important; width: 100% !important; max-width: 100% !important; min-width: 0 !important; /* 负 margin 归零后:容器 0~360,padding 8 → 内容 8~352, 卡片距屏幕左右各 8px(改前是距左 0 / 距右 16) */ margin: 8px 0 0 0 !important; padding: 0 8px !important; box-sizing: border-box !important; float: none !important; } /* ---- 4. 主播卡:列间距 52 → 8(最后一个 0)---- */ html body.bili-search-page #app .search-page-live .live-user-cards > [class*="col_"], html body.bili-search-page #app .search-page-live .live-user-cards > [class*="col_md_"], body.bili-search-page .search-page-live .live-user-cards > [class*="col_"], body.bili-search-page .search-page-live .live-user-cards > [class*="col_md_"] { display: block !important; width: 100% !important; max-width: 100% !important; min-width: 0 !important; padding: 0 !important; margin: 0 0 8px 0 !important; box-sizing: border-box !important; float: none !important; } html body.bili-search-page #app .search-page-live .live-user-cards > [class*="col_"]:last-child, body.bili-search-page .search-page-live .live-user-cards > [class*="col_"]:last-child { margin-bottom: 0 !important; } /* ---- 5. 主播卡白卡皮肤(与综合页视频卡同参数)---- 实测改前 [344x86] 无背景,白卡是后面加的。 ⚠ 只加外框,不动内容区(头像 86 + .live-content)内部排布。 ---- */ html body.bili-search-page #app .search-page-live .b-user-live-card, html body.bili-search-page #app .search-page-live .b-user-live-card.b-user-live-card, body.bili-search-page .search-page-live .b-user-live-card, body.bili-search-page .search-page-live .b-user-live-card.b-user-live-card { width: 100% !important; max-width: 100% !important; min-width: 0 !important; margin: 0 !important; padding: 0 !important; height: auto !important; display: flex !important; background: #ffffff !important; border: none !important; border-radius: 8px !important; box-shadow: 0 1px 3px rgba(0,0,0,0.08) !important; overflow: hidden !important; box-sizing: border-box !important; float: none !important; } /* ---- 6. 直播间区:4 列 74px → 2 列 168px(照抄综合页 grid 参数)---- 综合页 .video-list:grid repeat(2, minmax(0,1fr)) + gap 8 + padding 8 → 360 - 16(padding) = 344,(344 - 8)/2 = 168 ✓ 与综合页同宽同间距 ---- */ html body.bili-search-page #app .search-page-live .live-room, body.bili-search-page .search-page-live .live-room { width: 100% !important; max-width: 100% !important; min-width: 0 !important; margin-top: 8px !important; margin-bottom: 0 !important; } html body.bili-search-page #app .search-page-live .live-room-cards, html body.bili-search-page #app .search-page-live .live-room-cards.row, html body.bili-search-page #app .search-page-live .live-room-cards.row.mt_lg, body.bili-search-page .search-page-live .live-room-cards, body.bili-search-page .search-page-live .live-room-cards.row, body.bili-search-page .search-page-live .live-room-cards.row.mt_lg { display: grid !important; grid-template-columns: repeat(2, minmax(0, 1fr)) !important; grid-gap: 8px !important; gap: 8px !important; row-gap: 8px !important; column-gap: 8px !important; width: 100% !important; max-width: 100% !important; min-width: 0 !important; /* v131.83:上 padding 也归零,否则与 h1 的 mb 8 叠成 16px。 下 padding 同样是 0:让「最后一行卡片 → 分页条」= 分页条的 mt 8px, 与分页条距屏幕底的 8px 相等。 */ padding: 0 8px 0 8px !important; margin: 0 !important; box-sizing: border-box !important; list-style: none !important; align-items: start !important; align-content: start !important; grid-auto-rows: auto !important; float: none !important; } html body.bili-search-page #app .search-page-live .live-room-cards > *, html body.bili-search-page #app .search-page-live .live-room-cards > [class*="col_"], html body.bili-search-page #app .search-page-live .live-room-cards > [class*="video-list-item"], body.bili-search-page .search-page-live .live-room-cards > *, body.bili-search-page .search-page-live .live-room-cards > [class*="col_"], body.bili-search-page .search-page-live .live-room-cards > [class*="video-list-item"] { width: 100% !important; max-width: 100% !important; min-width: 0 !important; margin: 0 !important; padding: 0 !important; box-sizing: border-box !important; float: none !important; position: static !important; flex: 1 1 auto !important; } /* .bili-live-card 的白卡皮肤在「通用两列视频卡片」段已定义 (body.bili-search-page .bili-live-card),这里只把高度对齐综合页的 172px */ html body.bili-search-page #app .search-page-live .bili-live-card, body.bili-search-page .search-page-live .bili-live-card { min-height: 172px !important; width: 100% !important; max-width: 100% !important; min-width: 0 !important; margin: 0 !important; } /* ---- 6b. 直播间标题行:只留「共找到 N 个结果」(v131.81)---- 结构(探针 .live-room > h1.room-header [360x60]): h1.room-header.b_text.flex_between └─ span.flex_start [360x60] ├─ 裸文本节点「直播间」 ← CSS 选不中文本节点 ├─ div.room-order [210x28] 综合排序 / 最新开播 └─ span.ml_md.fs_4.text3 [75x35] 共找到214个结果 需求:隐藏「直播间 + 综合排序 + 最新开播」,保留「共找到 N 个结果」。 · div.room-order 直接 display:none · 「直播间」是裸文本节点 → 给父级 span.flex_start 设 font-size:0 (字号为 0 时文本不占宽也不显示),再把 span.ml_md 的字号还原 (B站 fs_4 = 14px),这样无论官方有没有包一层元素都能干掉 那两个排序按钮改由搜索框左侧的「排序」接管,见 JS 部分。 ---- */ html body.bili-search-page #app .search-page-live .live-room > h1, html body.bili-search-page #app .search-page-live .live-room > h1.room-header, body.bili-search-page .search-page-live .live-room > h1, body.bili-search-page .search-page-live .live-room > h1.room-header { display: flex !important; /* v131.82:改为居中。原为 flex-end(右对齐,实测 left=244 right=352)。 内容区 8~352 = 344,结果数 108 宽 → 居中后 left = 8+(344-108)/2 = 126 */ justify-content: center !important; align-items: center !important; width: 100% !important; max-width: 100% !important; min-width: 0 !important; height: auto !important; min-height: 0 !important; padding: 0 8px !important; /* 下间距:由这一条 margin-bottom 提供唯一的 8px。 ⚠ v131.83 修复:实测「共找到9个结果」到第一张卡片是 16px—— h1 的 mb 8 + .live-room-cards 的 padding-top 8 叠加成了 16 (探针:h1 bottom=80、cards 盒子 top=88、卡 top=96)。 所以下面把 cards 的 padding-top 归零,间距只由这里给。 */ margin: 0 0 8px 0 !important; box-sizing: border-box !important; } /* font-size:0 干掉裸文本「直播间」 */ html body.bili-search-page #app .search-page-live .live-room h1 > span.flex_start, body.bili-search-page .search-page-live .live-room h1 > span.flex_start { font-size: 0 !important; line-height: 0 !important; width: auto !important; min-width: 0 !important; margin: 0 !important; } html body.bili-search-page #app .search-page-live .live-room .room-order, body.bili-search-page .search-page-live .live-room .room-order { display: none !important; visibility: hidden !important; width: 0 !important; height: 0 !important; min-width: 0 !important; max-width: 0 !important; padding: 0 !important; margin: 0 !important; border: none !important; overflow: hidden !important; } /* 结果数字号还原(fs_4 = 14px),右对齐、距屏幕右 8px */ html body.bili-search-page #app .search-page-live .live-room .ml_md, body.bili-search-page .search-page-live .live-room .ml_md { font-size: 14px !important; line-height: 20px !important; display: inline-block !important; max-width: 100% !important; margin-left: 0 !important; white-space: nowrap !important; } /* ---- 7. 分页条:上间距 = 下间距 = 8px ---- 已有通用规则 [class*="mt_x50"] { margin: 8px 0 }, 这里再把「最后一个卡片 mb」和「容器 pb」压到 0 即可两端相等。 ---- */ html body.bili-search-page #app .search-page-live .live-room-cards > *:last-child, body.bili-search-page .search-page-live .live-room-cards > *:last-child { margin-bottom: 0 !important; } /* ===== 关键词屏蔽提示条(+必含 / -排除)v131.62 ===== 固定在自建搜索栏(52px)正下方,告诉用户当前哪些词被排除了、 一共过滤掉多少条,并提供"清除"回到不带屏蔽词的搜索结果。 它占 30px,所以下面配套一条 body.has-filter-bar 把正文再下推 30px, 免得盖住第一条结果。 ---- */ #my-bili-filterbar { position: fixed !important; top: 52px !important; left: 0 !important; right: 0 !important; z-index: 2147483645 !important; display: flex !important; align-items: center !important; gap: 6px !important; height: 30px !important; padding: 0 10px !important; background: #fff7f7 !important; border-bottom: 1px solid #ffe3e3 !important; color: #61666d !important; font-size: 12px !important; line-height: 30px !important; box-sizing: border-box !important; overflow-x: auto !important; overflow-y: hidden !important; white-space: nowrap !important; -webkit-overflow-scrolling: touch !important; } #my-bili-filterbar .fb-label { flex-shrink: 0 !important; color: #9499a0 !important; } #my-bili-filterbar .fb-word { flex-shrink: 0 !important; height: 20px !important; padding: 0 8px !important; line-height: 20px !important; background: #ffe0e0 !important; color: #e34d59 !important; border-radius: 10px !important; } #my-bili-filterbar .fb-count { flex-shrink: 0 !important; margin-left: auto !important; color: #9499a0 !important; } #my-bili-filterbar .fb-clear { flex-shrink: 0 !important; padding: 0 4px 0 8px !important; color: #00aeec !important; cursor: pointer !important; user-select: none !important; -webkit-tap-highlight-color: transparent !important; } /* 提示条占位:52(搜索栏) + 30(提示条) = 82 */ body.has-filter-bar { padding-top: 82px !important; } body.bili-search-page * { max-width: 100% !important; box-sizing: border-box !important; } body.bili-search-page img, body.bili-search-page video, body.bili-search-page picture { max-width: 100% !important; height: auto !important; } html body.bili-search-page #app, html body.bili-search-page #app > div, html body.bili-search-page #search-app, html body.bili-search-page #app .search-layout, html body.bili-search-page #app .search-layout.clearfix, html body.bili-search-page #app .search-content, html body.bili-search-page #app .search-content--gray, html body.bili-search-page #app .search-page-wrapper, html body.bili-search-page #app .search-page, html body.bili-search-page #app .search-page.search-page-all, html body.bili-search-page #app .search-page > div, html body.bili-search-page #app .video.i_wrapper, html body.bili-search-page #app .video.i_wrapper.search-all-list, html body.bili-search-page #app .search-all-list, body.bili-search-page .search-container, body.bili-search-page .search-result, body.bili-search-page .search-result-wrapper, body.bili-search-page .search-page-container, body.bili-search-page .search-page-content, body.bili-search-page .video-list-container { width: 100% !important; max-width: 100% !important; min-width: 0 !important; padding-left: 0 !important; padding-right: 0 !important; padding-top: 0 !important; padding-bottom: 0 !important; margin-left: 0 !important; margin-right: 0 !important; margin-top: 0 !important; margin-bottom: 0 !important; box-sizing: border-box !important; position: static !important; left: 0 !important; right: 0 !important; transform: none !important; overflow-x: hidden !important; float: none !important; } body.bili-search-page .bili-header, body.bili-search-page .international-header, body.bili-search-page .mini-header, body.bili-search-page #biliMainHeader, body.bili-search-page #bili-header-container, body.bili-search-page .bili-header--mini, body.bili-search-page .bili-header--fixed, body.bili-search-page .bili-header__bar, body.bili-search-page .bili-header__menu, body.bili-search-page .nav-menu, body.bili-search-page .channel-menu, body.bili-search-page .nav-channel, body.bili-search-page .header-channel, body.bili-search-page .nav-bar, body.bili-search-page .footer, body.bili-search-page .bili-footer, body.bili-search-page .international-footer, body.bili-search-page .mini-footer, body.bili-search-page .go-top, body.bili-search-page .bili-go-top, body.bili-search-page [class*="back-top"], body.bili-search-page [class*="to-top"], body.bili-search-page [class*="right-side"], body.bili-search-page [class*="right-bar"], body.bili-search-page [class*="right-tool"], body.bili-search-page [class*="side-tool"], body.bili-search-page [class*="toolbar"], body.bili-search-page [class*="feedback"], body.bili-search-page [class*="customer-service"], body.bili-search-page [class*="service-btn"], body.bili-search-page .ad-report, body.bili-search-page .ad-floor, body.bili-search-page .fixed-sidebar, body.bili-search-page .bili-fixed-sidebar { display: none !important; visibility: hidden !important; height: 0 !important; min-height: 0 !important; padding: 0 !important; margin: 0 !important; overflow: hidden !important; } body.bili-search-page .search-condition, body.bili-search-page .search-condition-wrapper, body.bili-search-page .filter-wrap, body.bili-search-page .search-filter, body.bili-search-page .left-search-filter, body.bili-search-page .search-page-left, body.bili-search-page aside.left, body.bili-search-page .search-filters, body.bili-search-page .search-condition-left, body.bili-search-page .search-header, body.bili-search-page .search-navbar, body.bili-search-page .nav-search, body.bili-search-page .search-input, body.bili-search-page .search-input-container, body.bili-search-page .bili-header__search, body.bili-search-page [class*="search-header"], body.bili-search-page [class*="search-nav"], body.bili-search-page .search-hot, body.bili-search-page .hot-search, body.bili-search-page .search-trending, body.bili-search-page .trending, body.bili-search-page [class*="hot-word"], body.bili-search-page [class*="hotsearch"] { display: none !important; visibility: hidden !important; } body.bili-search-page .activity-game-list, body.bili-search-page .user-list, body.bili-search-page .activity-game-list-wrap { display: none !important; visibility: hidden !important; height: 0 !important; min-height: 0 !important; padding: 0 !important; margin: 0 !important; overflow: hidden !important; } html body.bili-search-page #app .video-list, html body.bili-search-page #app .video-list.row, html body.bili-search-page #app .search-video-list, html body.bili-search-page #app .card-list, html body.bili-search-page #app .search-result-list, html body.bili-search-page #app ul.video-list, html body.bili-search-page #app .search-page-video-list, html body.bili-search-page #app .search-all-list > .video-list, html body.bili-search-page #app .search-all-list > .video-list.row, html body.bili-search-page #app .video.i_wrapper.search-all-list > .video-list, html body.bili-search-page #app .video.i_wrapper.search-all-list > .video-list.row { display: grid !important; grid-template-columns: repeat(2, minmax(0, 1fr)) !important; grid-gap: 8px !important; gap: 8px !important; row-gap: 8px !important; column-gap: 8px !important; width: 100% !important; max-width: 100% !important; min-width: 100% !important; padding: 8px !important; margin: 0 !important; background-color: #f1f2f3 !important; box-sizing: border-box !important; list-style: none !important; align-items: start !important; align-content: start !important; grid-auto-rows: auto !important; float: none !important; position: static !important; } /* ===== 搜索结果番剧区:综合页 / 番剧垂搜页 统一边距 ===== 涉及两处,类名不同但结构同构,这里共用同一组规则: · 综合页(/all) :.bangumi-pgc-list.i_wrapper.search-all-list · 番剧垂搜页(/bangumi):.media-list.i_wrapper(卡内为 .col_6.mb_x40) 实测(360px 屏,综合页):容器 360 -> row 344 -> col/card 328, 即卡片左右各留 16px(8 容器 + 8 row),左右相等即居中; 垂搜页原本 row 仅 248、card 232,明显更窄,需拉到同一条边线。 同时解除 B站对该区域的固定高度(实测容器 685px、row 已占 684px), 并把卡片下边距 mb_x40(40px) 压到 8px,使「查看全部 N 部相关番剧作品」 不再被裁掉一半、无需再下滑。 卡片内部(左封面 148 + 右信息区)保持 B站原生排布,不改动。 */ /* 1) 容器:左右 8px + 上下 8px,解除官方高度限制 */ html body.bili-search-page #app .bangumi-pgc-list, html body.bili-search-page #app .bangumi-pgc-list.i_wrapper, html body.bili-search-page #app .media-list, html body.bili-search-page #app .media-list.i_wrapper, body.bili-search-page .bangumi-pgc-list, body.bili-search-page .media-list, body.bili-search-page .media-list.i_wrapper { display: block !important; width: 100% !important; max-width: 100% !important; min-width: 0 !important; padding-left: 8px !important; padding-right: 8px !important; padding-top: 8px !important; padding-bottom: 8px !important; margin-left: auto !important; margin-right: auto !important; margin-top: 0 !important; margin-bottom: 0 !important; height: auto !important; min-height: 0 !important; max-height: none !important; overflow: visible !important; box-sizing: border-box !important; float: none !important; } /* 2) 行容器:左右 8px(与容器叠加 = 16px),高度自适应、不裁剪 */ html body.bili-search-page #app .bangumi-pgc-list .row.media-item, html body.bili-search-page #app .media-list .row, html body.bili-search-page #app .media-list.i_wrapper > .row, body.bili-search-page .bangumi-pgc-list .row.media-item, body.bili-search-page .media-list .row, body.bili-search-page .media-list.i_wrapper > .row { display: block !important; width: 100% !important; max-width: 100% !important; min-width: 0 !important; padding-left: 8px !important; padding-right: 8px !important; padding-top: 0 !important; padding-bottom: 0 !important; margin-left: auto !important; margin-right: auto !important; margin-top: 0 !important; margin-bottom: 0 !important; height: auto !important; min-height: 0 !important; max-height: none !important; overflow: visible !important; box-sizing: border-box !important; float: none !important; } /* 3) 卡片栅格列:占满整行(单列)。 上下卡片间距 = 卡片距屏幕左右边缘的距离 = 16px (左右实测:容器 8 + row 8 = 卡片距屏幕 16px,两边相等即居中) */ html body.bili-search-page #app .bangumi-pgc-list .media-item-col, html body.bili-search-page #app .bangumi-pgc-list [class*="media-item-col"], html body.bili-search-page #app .media-list [class*="col_6"], html body.bili-search-page #app .media-list [class*="col_md_4"], html body.bili-search-page #app .media-list .mb_x40, body.bili-search-page .bangumi-pgc-list [class*="media-item-col"], body.bili-search-page .media-list [class*="col_6"], body.bili-search-page .media-list [class*="col_md_4"], body.bili-search-page .media-list .mb_x40 { display: block !important; width: 100% !important; max-width: 100% !important; min-width: 0 !important; padding-left: 0 !important; padding-right: 0 !important; padding-top: 0 !important; padding-bottom: 0 !important; margin-left: auto !important; margin-right: auto !important; margin-top: 0 !important; margin-bottom: 16px !important; height: auto !important; min-height: 0 !important; max-height: none !important; box-sizing: border-box !important; float: none !important; } /* 4) 卡片本体:满宽居中(综合页 232/328 -> 328,与综合页同一条边线) 【关键1】.media-card 原生就是 flex 行布局(左封面 148 + 右信息区), 上一版误写成 display:block,把封面和文字压成了上下排列(卡片 198 -> 647 高)。 这里显式写回 flex row:左封面固定 148,右信息区吃掉剩余宽度。 【关键2】改回 flex 后信息区变成 180(148+180=328)把间距吃没了, 原生是 封面148 + 间距16 + 信息区164 = 328, 所以用 column-gap:16px 把这段间距加回来(信息区自动回到 164)。 */ html body.bili-search-page #app .bangumi-pgc-list .media-card, html body.bili-search-page #app .media-list .media-card, body.bili-search-page .bangumi-pgc-list .media-card, body.bili-search-page .media-list .media-card, body.bili-search-page .media-card { display: flex !important; flex-direction: row !important; flex-wrap: nowrap !important; align-items: flex-start !important; column-gap: 16px !important; gap: 0 16px !important; width: 100% !important; max-width: 100% !important; min-width: 0 !important; margin-left: auto !important; margin-right: auto !important; margin-top: 0 !important; margin-bottom: 0 !important; height: auto !important; min-height: 0 !important; max-height: none !important; box-sizing: border-box !important; float: none !important; } /* 4-1) 左封面:固定 148px(与原生一致),不拉伸、不压缩 */ html body.bili-search-page #app .bangumi-pgc-list .media-card > .media-card-image, html body.bili-search-page #app .media-list .media-card > .media-card-image, body.bili-search-page .bangumi-pgc-list .media-card > .media-card-image, body.bili-search-page .media-list .media-card > .media-card-image { flex: 0 0 148px !important; width: 148px !important; min-width: 148px !important; max-width: 148px !important; height: auto !important; margin: 0 !important; padding: 0 !important; box-sizing: border-box !important; float: none !important; } html body.bili-search-page #app .media-card > .media-card-image picture, html body.bili-search-page #app .media-card > .media-card-image img, body.bili-search-page .media-card > .media-card-image picture, body.bili-search-page .media-card > .media-card-image img { width: 100% !important; height: auto !important; max-width: 100% !important; object-fit: cover !important; } /* 4-2) 右信息区:吃掉剩余宽度(垂搜页 68 -> 164,与综合页一致) */ html body.bili-search-page #app .bangumi-pgc-list .media-card > .media-card-content, html body.bili-search-page #app .media-list .media-card > .media-card-content, body.bili-search-page .bangumi-pgc-list .media-card > .media-card-content, body.bili-search-page .media-list .media-card > .media-card-content { flex: 1 1 auto !important; width: auto !important; min-width: 0 !important; max-width: 100% !important; height: auto !important; min-height: 0 !important; max-height: none !important; margin: 0 !important; padding: 0 !important; box-sizing: border-box !important; float: none !important; } /* 5) 「查看全部 N 部相关番剧作品」:解除裁剪 + 在长条容器内完全居中 【叠加的真因】按钮带 .p_center(原生靠 absolute + transform 居中), 脱出文档流后 .show-more-text 高度塌成 0,按钮就画在别的内容上面了。 这里把按钮和外框都改回 static,让按钮重新撑起高度、参与正常排版; 容器已解除固定高度 + overflow:visible,按钮得以完整显示且不再重叠。 【上下不居中的原因】外框是 block 长条,按钮是 inline-block, 只能靠 text-align 左右居中;垂直方向贴着 padding-top 走,天然偏上。 这里把外框改成 flex,align-items:center + justify-content:center, 按钮在长条容器内左右、上下都居中;外框保留最小高度,保证长条背景完整。 */ html body.bili-search-page #app .bangumi-pgc-list .show-more-text, html body.bili-search-page #app .media-list .show-more-text, body.bili-search-page .bangumi-pgc-list .show-more-text, body.bili-search-page .media-list .show-more-text { display: flex !important; flex-direction: row !important; flex-wrap: nowrap !important; align-items: center !important; justify-content: center !important; position: static !important; visibility: visible !important; opacity: 1 !important; width: 100% !important; max-width: 100% !important; height: auto !important; min-height: 40px !important; max-height: none !important; /* 上下 padding 必须对称,否则即使 flex 居中,按钮视觉上仍会偏上 */ padding: 6px 0 !important; margin: 8px auto 0 !important; overflow: visible !important; text-align: center !important; box-sizing: border-box !important; float: none !important; clear: both !important; } html body.bili-search-page #app .bangumi-pgc-list .show-more-text button, html body.bili-search-page #app .media-list .show-more-text button, body.bili-search-page .bangumi-pgc-list .show-more-text button, body.bili-search-page .media-list .show-more-text button, body.bili-search-page .show-more-text button { display: inline-flex !important; align-items: center !important; justify-content: center !important; position: static !important; top: auto !important; right: auto !important; bottom: auto !important; left: auto !important; transform: none !important; visibility: visible !important; opacity: 1 !important; flex: 0 0 auto !important; width: auto !important; max-width: 100% !important; height: auto !important; min-height: 0 !important; max-height: none !important; padding: 4px 8px !important; margin: 0 !important; line-height: normal !important; white-space: normal !important; overflow: visible !important; text-align: center !important; box-sizing: border-box !important; float: none !important; } body.bili-search-page .video-item + .video-item, body.bili-search-page .video-list > li + li, body.bili-search-page .search-result-list > li + li { border-top: none !important; padding-top: 0 !important; margin-top: 0 !important; } body.bili-search-page .video-item::before, body.bili-search-page .video-item::after, body.bili-search-page .bili-video-card::before, body.bili-search-page .bili-video-card::after, body.bili-search-page .video-list > li::before, body.bili-search-page .video-list > li::after { display: none !important; content: none !important; } html body.bili-search-page #app .video-list > *, html body.bili-search-page #app .search-video-list > *, html body.bili-search-page #app .card-list > *, html body.bili-search-page #app .search-result-list > *, html body.bili-search-page #app ul.video-list > *, html body.bili-search-page #app .search-page-video-list > *, html body.bili-search-page #app .search-all-list .video-list > *, html body.bili-search-page #app .video-list.row > div[class*="col_"], html body.bili-search-page #app .video-list.row > .col_3, html body.bili-search-page #app .video-list.row > .col_xs_1_5, html body.bili-search-page #app .video-list.row > .col_md_2, html body.bili-search-page #app .video-list.row > .to_hide_xs, html body.bili-search-page #app .video-list.row > .to_hide_md, html body.bili-search-page #app .video-list.row > .to_hide_xl { display: block !important; width: 100% !important; max-width: 100% !important; min-width: 0 !important; margin: 0 !important; padding: 0 !important; float: none !important; box-sizing: border-box !important; flex: 1 1 100% !important; position: static !important; } html body.bili-search-page #app .bili-video-card, html body.bili-search-page #app .bili-video-card.bili-video-card, html body.bili-search-page #app .bili-video-card.bili-video-card.bili-video-card, html body.bili-search-page #app .search-all-list .bili-video-card, html body.bili-search-page #app .video-list.row .bili-video-card { height: auto !important; max-height: none !important; min-height: 172px !important; width: 100% !important; max-width: 100% !important; min-width: 100% !important; margin: 0 !important; padding: 0 !important; display: block !important; align-self: start !important; background: #ffffff !important; border: none !important; border-radius: 8px !important; box-shadow: 0 1px 3px rgba(0,0,0,0.08) !important; overflow: hidden !important; box-sizing: border-box !important; position: relative !important; float: none !important; flex: 1 1 100% !important; } html body.bili-search-page #app .bili-video-card__skeleton, html body.bili-search-page #app .bili-video-card__skeleton--cover, html body.bili-search-page #app .bili-video-card__skeleton--info, html body.bili-search-page #app .bili-video-card__skeleton--right, html body.bili-search-page #app .bili-video-card__skeleton--text, html body.bili-search-page #app .bili-video-card__skeleton--light, html body.bili-search-page #app .bili-video-card__skeleton.hide, html body.bili-search-page #app .bili-video-card__skeleton--text.short { width: 100% !important; max-width: 100% !important; min-width: 0 !important; box-sizing: border-box !important; flex: none !important; display: block !important; } body.bili-search-page .bili-video-card__wrap, body.bili-search-page .bili-video-card__info, body.bili-search-page .bili-video-card__image--wrap { height: auto !important; max-height: none !important; min-height: 0 !important; width: 100% !important; max-width: 100% !important; box-sizing: border-box !important; } body.bili-search-page .flex_center.mt_x50, body.bili-search-page .flex_center.mb_x50, body.bili-search-page [class*="mt_x50"], body.bili-search-page [class*="mb_x50"] { margin-top: 8px !important; margin-bottom: 8px !important; } body.bili-search-page .vui_pagenation, body.bili-search-page .page-wrap, body.bili-search-page .pagination { display: flex !important; justify-content: center !important; width: 100% !important; max-width: 100% !important; padding: 8px 0 !important; margin: 0 !important; box-sizing: border-box !important; } body.bili-search-page .vui_pagenation--btns { display: flex !important; flex-wrap: nowrap !important; justify-content: flex-start !important; align-items: center !important; width: 100% !important; max-width: 100% !important; padding: 0 8px !important; margin: 0 !important; box-sizing: border-box !important; gap: 4px !important; overflow-x: auto !important; -webkit-overflow-scrolling: touch !important; } body.bili-search-page .vui_pagenation--btns::-webkit-scrollbar { display: none !important; width: 0 !important; height: 0 !important; } body.bili-search-page .vui_pagenation--btns { scrollbar-width: none !important; -ms-overflow-style: none !important; } body.bili-search-page .vui_pagenation--btn { flex-shrink: 0 !important; flex-grow: 0 !important; margin: 0 !important; min-width: 32px !important; padding: 0 6px !important; height: 34px !important; line-height: 34px !important; box-sizing: border-box !important; white-space: nowrap !important; font-size: 13px !important; text-align: center !important; border-radius: 4px !important; } body.bili-search-page .vui_pagenation--btn-side { min-width: 44px !important; padding: 0 10px !important; } /* ===== 视频页 ===== */ body.bili-video-page { background: #ffffff !important; overflow-x: hidden !important; min-height: 100vh !important; margin-top: 0 !important; padding-top: 0 !important; } body.bili-video-page { --video-equal-spacing: 36px; } body.bili-video-page, body.bili-video-page #app, body.bili-video-page #app > div, body.bili-video-page #mirror-vdcon.video-container-v1, body.bili-video-page .left-container, body.bili-video-page .left-container.scroll-sticky { width: 100vw !important; max-width: 100vw !important; min-width: 100vw !important; overflow-x: hidden !important; box-sizing: border-box !important; margin-left: 0 !important; margin-right: 0 !important; padding-left: 0 !important; padding-right: 0 !important; left: 0 !important; right: 0 !important; position: relative !important; } body.bili-video-page .left-container, body.bili-video-page .left-container.scroll-sticky { padding: 0 8px !important; } body.bili-video-page #app, body.bili-video-page #app > div, body.bili-video-page #mirror-vdcon.video-container-v1, body.bili-video-page #mirror-vdcon > *, body.bili-video-page .left-container, body.bili-video-page .left-container.scroll-sticky, body.bili-video-page .left-container > *, body.bili-video-page #viewbox_report, body.bili-video-page #viewbox_report > *, body.bili-video-page #viewbox_report .video-info-title, body.bili-video-page #viewbox_report .video-info-title-inner, body.bili-video-page #viewbox_report h1.video-title, body.bili-video-page #viewbox_report .video-info-meta, body.bili-video-page #viewbox_report .video-info-detail-list, body.bili-video-page #viewbox_report .pubdate-ip, body.bili-video-page #viewbox_report .pubdate-ip-text { margin-top: 0 !important; padding-top: 0 !important; border-top: 0 !important; top: 0 !important; bottom: auto !important; } body.bili-video-page #viewbox_report { margin-top: var(--video-equal-spacing) !important; margin-bottom: var(--video-equal-spacing) !important; padding-top: 0 !important; } body.bili-video-page #playerWrap { width: 100% !important; max-width: 100% !important; height: calc((100vw - 22px) * 9 / 16 + 6px) !important; max-height: calc((100vw - 22px) * 9 / 16 + 6px) !important; min-width: 0 !important; min-height: 0 !important; overflow: hidden !important; box-sizing: border-box !important; border: 3px solid #00aeec !important; border-radius: 12px !important; box-shadow: 0 4px 16px rgba(0, 174, 236, 0.25) !important; margin-top: 0 !important; margin-bottom: var(--video-equal-spacing) !important; position: relative !important; } body.bili-video-page #playerWrap #bilibili-player-placeholder, body.bili-video-page #playerWrap #bilibili-player, body.bili-video-page #playerWrap .bpx-docker, body.bili-video-page #playerWrap .bpx-player-container, body.bili-video-page #playerWrap .bpx-player-primary-area, body.bili-video-page #playerWrap .bpx-player-video-area, body.bili-video-page #playerWrap .bpx-player-video-wrap { width: 100% !important; max-width: 100% !important; min-width: 0 !important; height: 100% !important; max-height: 100% !important; min-height: 0 !important; padding: 0 !important; margin: 0 !important; box-sizing: border-box !important; transform: none !important; zoom: normal !important; border-radius: 0 !important; } body.bili-video-page #playerWrap video { width: 100% !important; height: 100% !important; object-fit: contain !important; display: block !important; margin: 0 !important; padding: 0 !important; background-color: #000 !important; } body.bili-video-page #v_desc { margin-top: 0 !important; margin-bottom: var(--video-equal-spacing) !important; } body.bili-video-page #commentapp { margin-top: 0 !important; padding-top: 0 !important; } body.bili-video-page #biliMainHeader, body.bili-video-page .bili-header, body.bili-video-page .international-header, body.bili-video-page .mini-header, body.bili-video-page .nav-menu, body.bili-video-page .fixed-sidenav-storage, body.bili-video-page .video-note-sidebar-panel, body.bili-video-page .video-note-sidebar-chapter-layer, body.bili-video-page .video-note-sidebar-chapter-portal, body.bili-video-page .go-top, body.bili-video-page .bili-footer, body.bili-video-page .footer, body.bili-video-page [class*="back-top"], body.bili-video-page [class*="to-top"] { display: none !important; visibility: hidden !important; height: 0 !important; overflow: hidden !important; } body.bili-video-page #arc_toolbar_report, body.bili-video-page .video-toolbar-container { display: none !important; visibility: hidden !important; height: 0 !important; overflow: hidden !important; } /* v131.19 视频页 UP 主信息区:移除「关注」前面的「充电」按钮 实测结构:.up-info__btn-panel > .upinfo-btn-panel > div.default-btn.old-charge-btn.not-follow-charge-btn ← 充电 > div.default-btn.follow-btn.b-gz.not-follow ← 关注 这里用 [class*="charge"] 覆盖全部版本(old / new / 已关注变体), 只写 display:none:flex 布局下被移除项不会占用 gap, 关注按钮会自动左移,不留空隙。 */ body.bili-video-page .up-info__btn-panel .new-charge-btn, body.bili-video-page .default-btn.new-charge-btn, body.bili-video-page .default-btn.old-charge-btn, body.bili-video-page .default-btn.not-follow-charge-btn, body.bili-video-page .default-btn.follow-charge-btn, body.bili-video-page .up-info__btn-panel [class*="charge"], body.bili-video-page .upinfo-btn-panel [class*="charge"] { display: none !important; visibility: hidden !important; } body.bili-video-page [class*="ad-"], body.bili-video-page [class*="ads-"], body.bili-video-page [class*="advertisement"], body.bili-video-page .video-card-ad-small, body.bili-video-page .video-card-ad, body.bili-video-page .slide-ad-exp, body.bili-video-page .slide-gg, body.bili-video-page .banner-ad, body.bili-video-page .ad-floor-exp, body.bili-video-page .ad-report, body.bili-video-page .popup-ad, body.bili-video-page .float-ad { display: none !important; visibility: hidden !important; height: 0 !important; width: 0 !important; padding: 0 !important; margin: 0 !important; overflow: hidden !important; } body.bili-video-page .video-resource-list, body.bili-video-page .activity-m-v1, body.bili-video-page [class*="video-resource-list"] { display: none !important; visibility: hidden !important; height: 0 !important; min-height: 0 !important; padding: 0 !important; margin: 0 !important; overflow: hidden !important; } body.bili-video-page .right-container .video-page-game-card-small, body.bili-video-page .right-container [class*="game-card-small"] { display: none !important; visibility: hidden !important; height: 0 !important; overflow: hidden !important; padding: 0 !important; margin: 0 !important; } body.bili-video-page .right-container #danmukuBox, body.bili-video-page .right-container .video-pod-above-modules, body.bili-video-page .right-container .danmaku-box, body.bili-video-page .right-container .bpx-player-auxiliary { display: none !important; visibility: hidden !important; height: 0 !important; overflow: hidden !important; margin: 0 !important; padding: 0 !important; } body.bili-video-page .bpx-player-sending-area, body.bili-video-page .bpx-player-sending-bar, body.bili-video-page .bpx-player-dm-root, body.bili-video-page .bpx-player-video-inputbar { display: none !important; visibility: hidden !important; height: 0 !important; min-height: 0 !important; max-height: 0 !important; padding: 0 !important; margin: 0 !important; overflow: hidden !important; } body.bili-video-page .bpx-player-ctrl-pip, body.bili-video-page .bpx-player-ctrl-wide, body.bili-video-page .bpx-player-ctrl-time, body.bili-video-page .bpx-player-ctrl-eplist { display: none !important; } @media screen and (orientation: landscape) { body.bili-video-page .bpx-player-ctrl-time { display: block !important; } } @media screen and (width >= 750px) { body.bili-video-page .bpx-player-container[data-screen=full] .bpx-player-ctrl-quality-result { height: unset !important; font-size: 16px !important; } body.bili-video-page .bpx-player-container[data-screen=full] .bpx-player-control-wrap { height: 43px !important; } body.bili-video-page .bpx-player-container[data-screen=full] .bpx-player-control-top { bottom: 43px !important; } } body.bili-video-page div.bpx-player-control-bottom { height: 29px !important; margin-top: 7px !important; padding: 0 7px !important; } body.bili-video-page div.bpx-player-control-top { transition: none; bottom: 36px; } body.bili-video-page .bpx-player-pbp .bpx-player-pbp-pin-tip { display: none !important; } body.bili-video-page .bpx-player-control-bottom-left, body.bili-video-page .bpx-player-control-bottom-right { flex: unset !important; } body.bili-video-page .bpx-player-container .bpx-player-control-bottom-left, body.bili-video-page .bpx-player-container .bpx-player-control-bottom-right { min-width: 0 !important; } body.bili-video-page .bpx-player-ctrl-quality { min-width: 0; flex: auto !important; margin-right: 0 !important; } body.bili-video-page .bpx-player-ctrl-quality-result, body.bili-video-page .bpx-player-ctrl-playbackrate { font-size: 12px !important; } body.bili-video-page .bpx-player-ctrl-quality-result { height: 22px; overflow: hidden; } body.bili-video-page .bpx-player-ctrl-playbackrate { text-wrap: nowrap; } body.bili-video-page .bpx-player-progress-wrap { height: 7px !important; padding-bottom: 3px !important; } body.bili-video-page .bpx-player-control-mask { background: linear-gradient(rgba(0,0,0,0) 0%, rgba(0,0,0,0.5) 100%) !important; } body.bili-video-page .bpx-player-ctrl-quality-menu-wrap { bottom: 22px !important; } body.bili-video-page .bpx-player-ctrl-quality-menu-item { max-width: 95px; max-height: 36px; height: 7.7vw !important; padding: 0 8px 0 12px !important; } body.bili-video-page .bpx-player-ctrl-quality-badge-bigvip { color: #fff; background-color: #f25d8e; width: 16px; overflow: hidden; right: 8px !important; } body.bili-video-page .bpx-player-ctrl-quality-badge-bigvip:before { color: #fff; content: "V"; background-color: #f25d8e; padding: 0 4px; position: absolute; left: 0; } body.bili-video-page .bpx-player-ctrl-playbackrate-menu { bottom: 22px !important; } body.bili-video-page .bpx-player-ctrl-playbackrate-menu-item { justify-content: center; align-items: center; max-height: 36px; display: flex; height: 7.7vw !important; } body.bili-video-page div.bpx-player-ctrl-subtitle-box { bottom: 0; right: 0; transform: scale(.8); } body.bili-video-page .bpx-player-ctrl-setting-box { bottom: 0 !important; right: 0 !important; } body.bili-video-page .bpx-player-ctrl-setting-menu-right { padding: 5px !important; } body.bili-video-page .bpx-player-ctrl-setting-menu-right > div { justify-content: center; align-items: center; max-height: 40px; display: flex; height: 10vw !important; } body.bili-video-page .bpx-player-ctrl-setting-menu-right .bui-radio { width: 77%; margin: 0 0 8px 7px; } body.bili-video-page .bpx-player-ctrl-setting-others-content { margin-left: 7px; width: 77% !important; } body.bili-video-page .bpx-player-ctrl-setting-highenergy .bui-checkbox-name { white-space: nowrap; width: 48px; overflow: hidden; } body.bili-video-page .bpx-player-dm-setting-wrap { top: 0; left: 50%; transform: translate(-50%); bottom: unset !important; position: fixed !important; } body.bili-video-page .bpx-player-control-bottom-center .bpx-player-sending-bar { height: 24px !important; padding-right: 6px !important; } body.bili-video-page .bpx-player-ctrl-viewpoint { flex-shrink: 1 !important; width: 45px !important; min-width: 0 !important; margin: 0 !important; } body.bili-video-page .bpx-player-ctrl-viewpoint-text { flex: none; font-size: 12px; width: 24px !important; text-overflow: unset !important; } body.bili-video-page .bpx-player-control-wrap:not(.new) { display: none; } body.bili-video-page .bpx-player-control-entity, body.bili-video-page .bpx-player-control-mask { display: block !important; } body.bili-video-page .bpx-player-container[data-ctrl-hidden=true] .bpx-player-control-bottom { display: none; } body.bili-video-page .bpx-player-container[ctrl-shown=false] .bpx-player-control-wrap .bpx-player-control-mask { opacity: 0; transition: opacity .2s ease-in; } body.bili-video-page .bpx-player-container[ctrl-shown=true] .bpx-player-control-wrap .bpx-player-control-mask { opacity: 1; } body.bili-video-page .bpx-player-container[ctrl-shown=true] .bpx-player-control-entity .bpx-player-control-bottom { opacity: 1; display: flex; } body.bili-video-page .bpx-player-container[ctrl-shown=false] .bpx-player-control-entity .bpx-player-control-bottom { display: none; } body.bili-video-page .bpx-player-container[ctrl-shown=true] .bpx-player-control-entity .bpx-player-control-top, body.bili-video-page .bpx-player-container[ctrl-shown=false] .bpx-player-control-entity .bpx-player-shadow-progress-area { opacity: 1; visibility: visible; } body.bili-video-page .bpx-player-container[ctrl-shown=false] .bpx-player-control-entity .bpx-player-control-top, body.bili-video-page .bpx-player-container[ctrl-shown=true] .bpx-player-control-entity .bpx-player-shadow-progress-area { opacity: 0; visibility: hidden; } body.bili-video-page .bpx-player-container[ctrl-shown=true] .bpx-player-control-entity .bpx-player-pbp { opacity: 1; width: 100%; bottom: calc(100% + 6px); left: 0; } body.bili-video-page div.bpx-player-control-entity .bpx-player-pbp { opacity: 0; width: calc(100% + 24px); bottom: 1px; left: -12px; } body.bili-video-page div.bpx-player-control-entity .bpx-player-pbp.pin { opacity: 1; } body.bili-video-page .bpx-player-pbp-pin { display: none; opacity: 1 !important; } body.bili-video-page .bpx-player-container[ctrl-shown=true] .bpx-player-control-entity .bpx-player-pbp-pin { display: block; } body.bili-video-page .bpx-player-video-perch { max-height: 0; } body.bili-video-page .bpx-player-top-wrap, body.bili-video-page .bpx-player-state-wrap { display: none !important; } body.bili-video-page .bpx-player-container, body.bili-video-page #bilibili-player-placeholder { box-shadow: none !important; } body.video-fullscreen { overflow: hidden !important; } body.video-fullscreen #mirror-vdcon, body.video-fullscreen .left-container { width: 100vw !important; max-width: 100vw !important; min-width: 100vw !important; height: 100vh !important; min-height: 0 !important; padding: 0 !important; margin: 0 !important; overflow: hidden !important; } body.video-fullscreen #playerWrap { width: 100vw !important; max-width: 100vw !important; height: 100vh !important; max-height: 100vh !important; min-height: 100vh !important; border: none !important; border-radius: 0 !important; box-shadow: none !important; overflow: hidden !important; margin: 0 !important; } body.video-fullscreen #playerWrap #bilibili-player-placeholder, body.video-fullscreen #playerWrap #bilibili-player, body.video-fullscreen #playerWrap .bpx-docker, body.video-fullscreen #playerWrap .bpx-player-container, body.video-fullscreen #playerWrap .bpx-player-primary-area, body.video-fullscreen #playerWrap .bpx-player-video-area, body.video-fullscreen #playerWrap .bpx-player-video-wrap { width: 100% !important; height: 100% !important; max-width: 100% !important; max-height: 100% !important; min-width: 0 !important; min-height: 0 !important; } body.video-fullscreen .bpx-player-video-wrap video { object-fit: contain !important; } /* ★ 侧边栏通用(视频页 / 番剧页):仅保留通用的 fixed + GPU 合成,不加 padding ★ */ body.bili-video-page .right-container, body.bili-bangumi-page .plp-r-wrap { position: fixed !important; top: 0 !important; right: 0 !important; bottom: 0 !important; left: auto !important; width: 85vw !important; max-width: 420px !important; height: 100vh !important; max-height: 100vh !important; overflow-y: auto !important; overflow-x: hidden !important; background: #ffffff !important; z-index: 99999 !important; transform: translate3d(100%, 0, 0) !important; transition: transform 0.3s cubic-bezier(0.4, 0, 0.2, 1) !important; will-change: transform; backface-visibility: hidden; -webkit-backface-visibility: hidden; box-shadow: -4px 0 16px rgba(0, 0, 0, 0.15) !important; box-sizing: border-box !important; -webkit-overflow-scrolling: touch !important; display: block !important; } body.bili-video-page .right-container.show, body.bili-bangumi-page .plp-r-wrap.show { transform: translate3d(0, 0, 0) !important; } /* ★ 番剧侧边栏:pad + 内部 plp-r 归位 ★ */ body.bili-bangumi-page .plp-r-wrap { padding: 12px !important; } body.bili-bangumi-page .plp-r.sticky { position: static !important; top: auto !important; width: 100% !important; max-width: 100% !important; min-width: 0 !important; height: auto !important; padding: 0 !important; margin: 0 !important; box-sizing: border-box !important; display: block !important; } body.bili-bangumi-page .plp-r-wrap .PaginatedEpList_root__67C7p, body.bili-bangumi-page .plp-r-wrap .recommend_wrap__PccwM { width: 100% !important; max-width: 100% !important; min-width: 0 !important; box-sizing: border-box !important; } body.bili-bangumi-page .plp-r-wrap img { max-width: 100% !important; height: auto !important; } body.bili-bangumi-page .EpisodeVirtualList_scroll__62SmN { width: 100% !important; max-width: 100% !important; overflow-x: hidden !important; } body.bili-bangumi-page .EpisodeVirtualList_virtualCanvas__0AC8_ { width: 100% !important; max-width: 100% !important; min-width: 0 !important; } body.bili-bangumi-page .EpisodeVirtualList_gridRow__czcgd { display: flex !important; flex-wrap: nowrap !important; justify-content: center !important; align-items: center !important; gap: 8px !important; width: 100% !important; max-width: 100% !important; box-sizing: border-box !important; padding: 0 6px !important; } body.bili-bangumi-page .EpisodeVirtualList_numberItem__GLWgO { width: 46px !important; height: 46px !important; min-width: 46px !important; min-height: 46px !important; flex-shrink: 0 !important; border-radius: 8px !important; font-size: 14px !important; display: flex !important; flex-direction: column !important; align-items: center !important; justify-content: center !important; box-sizing: border-box !important; margin: 0 !important; padding: 0 !important; } body.bili-bangumi-page .EpisodeVirtualList_numberItem__GLWgO * { font-size: 10px !important; transform: scale(0.9) !important; } body.bili-bangumi-page #danmukuBox { display: none !important; visibility: hidden !important; height: 0 !important; overflow: hidden !important; margin: 0 !important; padding: 0 !important; } body.bili-video-page .right-container .right-container-inner { position: static !important; top: auto !important; height: auto !important; padding: 12px !important; width: 100% !important; max-width: 100% !important; min-width: 0 !important; box-sizing: border-box !important; } body.bili-video-page .right-container .up-info--right, body.bili-video-page .right-container .up-info__btn-panel, body.bili-video-page .right-container .upinfo-btn-panel, body.bili-video-page .right-container .follow-btn, body.bili-video-page .right-container .interactions { overflow: visible !important; position: relative !important; } body.bili-video-page .right-container .follow-btn .menu-popover, body.bili-video-page .right-container .follow-btn-wrapper { position: absolute !important; top: 100% !important; right: 0 !important; left: auto !important; z-index: 9999999 !important; transform: none !important; margin-top: 4px !important; background: #fff !important; border-radius: 4px !important; box-shadow: 0 2px 8px rgba(0,0,0,0.15) !important; } body.bili-video-page .van-popover, body.bili-video-page .bili-popover, body.bili-video-page [class*="popover"] { z-index: 9999999 !important; } body.bili-video-page .right-container > *, body.bili-video-page .right-container .up-panel-container, body.bili-video-page .right-container .up-info-container, body.bili-video-page .right-container .video-pod-above-modules, body.bili-video-page .right-container .video-pod-above-modules__inner, body.bili-video-page .right-container .rcmd-tab, body.bili-video-page .right-container .recommend-list-v1, body.bili-video-page .right-container .rec-list, body.bili-video-page .right-container .video-page-card-small, body.bili-video-page .right-container .bpx-player-wraplist, body.bili-video-page .right-container .slide-ad-exp, body.bili-video-page .right-container .slide-gg, body.bili-video-page .right-container .ad-report, body.bili-video-page .right-container .ad-floor-cover { width: 100% !important; max-width: 100% !important; min-width: 0 !important; box-sizing: border-box !important; position: static !important; left: auto !important; right: auto !important; } body.bili-video-page .right-container .ad-report.ad-floor-exp.right-bottom-banner, body.bili-video-page .right-container .ad-floor-cover, body.bili-video-page .right-container .video-card-ad-small { display: none !important; visibility: hidden !important; height: 0 !important; overflow: hidden !important; margin: 0 !important; padding: 0 !important; } body.bili-video-page .right-container img, body.bili-video-page .right-container video, body.bili-video-page .right-container picture { max-width: 100% !important; height: auto !important; } body.bili-video-page .right-container .send-msg, body.bili-video-page .right-container a.send-msg, body.bili-video-page .right-container .up-detail-top > a.send-msg { display: none !important; visibility: hidden !important; } body.bili-video-page .right-container .up-info--right { flex: 1 1 auto !important; min-width: 0 !important; width: auto !important; max-width: 100% !important; display: flex !important; flex-direction: column !important; } body.bili-video-page .right-container .up-info__detail, body.bili-video-page .right-container .up-detail, body.bili-video-page .right-container .upinfo-sign, body.bili-video-page .right-container .upinfo-sign__text { width: 100% !important; max-width: 100% !important; min-width: 0 !important; word-break: break-all !important; white-space: normal !important; overflow-wrap: break-word !important; box-sizing: border-box !important; overflow: hidden !important; } body.bili-video-page .right-container .up-detail-top { display: flex !important; align-items: center !important; justify-content: flex-start !important; width: 100% !important; max-width: 100% !important; min-width: 0 !important; gap: 8px !important; } body.bili-video-page .right-container .up-name { white-space: nowrap !important; word-break: keep-all !important; text-overflow: ellipsis !important; overflow: hidden !important; flex-shrink: 1 !important; width: auto !important; max-width: 100% !important; min-width: 0 !important; display: block !important; } body.bili-video-page #viewbox_report, body.bili-video-page .video-info-title, body.bili-video-page .video-info-title-inner, body.bili-video-page .video-title, body.bili-video-page #v_desc, body.bili-video-page .basic-desc-info, body.bili-video-page .desc-info-text { text-align: center !important; justify-content: center !important; align-items: center !important; float: none !important; } body.bili-video-page h1.video-title { width: 100% !important; display: block !important; text-align: center !important; } body.bili-video-page #viewbox_report .show-more, body.bili-video-page #viewbox_report .show-more-btn { display: none !important; visibility: hidden !important; height: 0 !important; width: 0 !important; overflow: hidden !important; } body.bili-video-page #viewbox_report .video-info-detail-list > .item:not(.pubdate-ip) { display: none !important; visibility: hidden !important; } body.bili-video-page #viewbox_report .video-info-title, body.bili-video-page #viewbox_report .video-info-title-inner, body.bili-video-page h1.video-title { height: auto !important; max-height: none !important; overflow: visible !important; -webkit-line-clamp: unset !important; -webkit-box-orient: unset !important; text-overflow: clip !important; white-space: normal !important; word-break: break-all !important; padding: 0 !important; } body.bili-video-page #v_desc, body.bili-video-page #viewbox_report, body.bili-video-page .video-info-container, body.bili-video-page .left-container, body.bili-video-page #mirror-vdcon.video-container-v1, body.bili-video-page #app { height: auto !important; min-height: auto !important; max-height: none !important; overflow: visible !important; } body.bili-video-page #v_desc .basic-desc-info { height: auto !important; max-height: none !important; overflow: visible !important; } body.bili-video-page #v_desc .desc-info-text { display: block !important; height: auto !important; -webkit-line-clamp: unset !important; -webkit-box-orient: unset !important; overflow: visible !important; text-overflow: clip !important; max-height: none !important; white-space: pre-wrap !important; } body.bili-video-page #v_desc .toggle-btn, body.bili-video-page #v_desc .toggle-btn-text { display: none !important; visibility: hidden !important; height: 0 !important; padding: 0 !important; margin: 0 !important; } body.bili-video-page #viewbox_report .video-info-meta, body.bili-video-page #viewbox_report .video-info-detail-list { display: flex !important; justify-content: center !important; align-items: center !important; width: 100% !important; text-align: center !important; margin: 0 auto !important; padding: 0 !important; float: none !important; } body.bili-video-page #viewbox_report .video-info-detail-list .item { float: none !important; display: inline-flex !important; align-items: center !important; justify-content: center !important; } body.bili-video-page .video-tag-container, body.bili-video-page .tag-panel, body.bili-video-page #mirror-vdcon > .left-container > .video-tag-container { display: none !important; visibility: hidden !important; height: 0 !important; min-height: 0 !important; padding: 0 !important; margin: 0 !important; overflow: hidden !important; } body.bili-video-page #commentapp .bili-comment-box, body.bili-video-page #commentapp .bili-comment-input-wrap, body.bili-video-page #commentapp .comment-send-box, body.bili-video-page #commentapp .comment-box, body.bili-video-page #commentapp .reply-box, body.bili-video-page #commentapp .bili-comment-container > .bili-comment-box, body.bili-video-page #commentapp .comment-container .comment-box, body.bili-video-page #commentapp .bili-comment-editor, body.bili-video-page #commentapp .bili-comment-editor-wrap { display: none !important; visibility: hidden !important; height: 0 !important; min-height: 0 !important; padding: 0 !important; margin: 0 !important; overflow: hidden !important; } body.bili-video-page #commentapp, body.bili-video-page #commentapp bili-comments, body.bili-video-page #commentapp .bili-comment-container, body.bili-video-page #commentapp .comment-container, body.bili-video-page #commentapp .comment-box, body.bili-video-page #commentapp .reply-box, body.bili-video-page #commentapp .bili-comment-box, body.bili-video-page #commentapp .bili-comment-input-wrap, body.bili-video-page #commentapp .comment-send-box { width: 100% !important; max-width: 100% !important; min-width: 0 !important; box-sizing: border-box !important; padding-left: 8px !important; padding-right: 8px !important; overflow: hidden !important; } body.bili-video-page #commentapp textarea, body.bili-video-page #commentapp input[type="text"], body.bili-video-page #commentapp .comment-textarea, body.bili-video-page #commentapp .bili-comment-textarea, body.bili-video-page #commentapp .reply-textarea, body.bili-video-page #commentapp [contenteditable="true"] { width: 100% !important; max-width: 100% !important; min-width: 0 !important; box-sizing: border-box !important; resize: none !important; word-break: break-all !important; white-space: pre-wrap !important; overflow-wrap: break-word !important; height: auto !important; min-height: 40px !important; padding: 8px !important; margin: 0 !important; overflow: hidden !important; } #my-bili-right-mask { position: fixed !important; top: 0 !important; left: 0 !important; right: 0 !important; bottom: 0 !important; width: 100vw !important; height: 100vh !important; background: rgba(0, 0, 0, 0.35) !important; z-index: 99998 !important; opacity: 0 !important; visibility: hidden !important; pointer-events: none !important; transition: opacity 0.3s ease, visibility 0.3s ease !important; will-change: opacity; display: block !important; } #my-bili-right-mask.show { opacity: 1 !important; visibility: visible !important; pointer-events: auto !important; } /* ============================================================ ========== 播放列表页(/list/):完整复用视频页优化 ========== ============================================================ */ body.bili-list-page { background: #ffffff !important; overflow-x: hidden !important; margin-top: 0 !important; padding-top: 0 !important; } /* 取消左右分栏:左栏独占整宽 */ body.bili-list-page #app.playlist-app, body.bili-list-page #mirror-vdcon.playlist-container { display: block !important; width: 100vw !important; max-width: 100vw !important; min-width: 0 !important; padding: 0 !important; margin: 0 !important; overflow-x: hidden !important; box-sizing: border-box !important; } body.bili-list-page #mirror-vdcon .playlist-container--left { width: 100% !important; max-width: 100% !important; min-width: 0 !important; padding: 0 8px !important; margin: 0 !important; float: none !important; overflow-x: hidden !important; box-sizing: border-box !important; } body.bili-list-page .playlist-container--left > * { max-width: 100% !important; } /* 标题 / 播放信息:与视频页完全一致的居中与等距 */ body.bili-list-page .video-info-container { margin-top: var(--video-equal-spacing) !important; margin-bottom: var(--video-equal-spacing) !important; padding: 0 !important; text-align: center !important; width: 100% !important; max-width: 100% !important; height: auto !important; min-height: 0 !important; max-height: none !important; overflow: visible !important; box-sizing: border-box !important; } body.bili-list-page .video-info-container .video-info-meta, body.bili-list-page .video-info-container .video-info-detail-list { display: flex !important; justify-content: center !important; align-items: center !important; width: 100% !important; text-align: center !important; margin: 0 auto !important; padding: 0 !important; float: none !important; } body.bili-list-page .video-info-container .video-info-detail-list .item { float: none !important; display: inline-flex !important; align-items: center !important; justify-content: center !important; } body.bili-list-page .video-info-container .video-info-detail-list > .item:not(.pubdate-ip) { display: none !important; visibility: hidden !important; } /* 标题:解除 B站原生行数/高度限制(video-info-title 系列 + special-text-indent), 与视频页 #viewbox_report 下的标题处理保持一致,完整多行显示 */ body.bili-list-page .video-info-container .video-info-title, body.bili-list-page .video-info-container .video-info-title-inner, body.bili-list-page .video-info-container .video-title, body.bili-list-page .video-info-container h1.video-title, body.bili-list-page .video-info-container h1.video-title > a, body.bili-list-page .video-info-container .video-title-href, body.bili-list-page .video-info-container .video-info-title * { display: block !important; width: 100% !important; max-width: 100% !important; min-width: 0 !important; height: auto !important; min-height: 0 !important; max-height: none !important; overflow: visible !important; -webkit-line-clamp: unset !important; line-clamp: unset !important; -webkit-box-orient: horizontal !important; text-overflow: clip !important; white-space: normal !important; word-break: break-word !important; overflow-wrap: break-word !important; text-indent: 0 !important; line-height: normal !important; letter-spacing: normal !important; padding: 0 !important; margin: 0 !important; float: none !important; text-align: center !important; box-sizing: border-box !important; } body.bili-list-page .video-info-container .video-info-title::after, body.bili-list-page .video-info-container .video-info-title-inner::after, body.bili-list-page .video-info-container .video-title::after, body.bili-list-page .video-info-container .video-title::before, body.bili-list-page .video-info-container .video-info-title .show-more, body.bili-list-page .video-info-container .video-info-title .show-more-btn, body.bili-list-page .video-info-container .video-info-title .expand-btn { display: none !important; visibility: hidden !important; width: 0 !important; height: 0 !important; padding: 0 !important; margin: 0 !important; overflow: hidden !important; content: none !important; } /* 简介:始终完全展开(等价视频页 #v_desc) */ body.bili-list-page .video-desc-container { margin: 0 0 var(--video-equal-spacing) !important; width: 100% !important; max-width: 100% !important; text-align: center !important; box-sizing: border-box !important; } body.bili-list-page .video-desc-container .basic-desc-info { height: auto !important; max-height: none !important; overflow: visible !important; } body.bili-list-page .video-desc-container .desc-info-text { display: block !important; height: auto !important; max-height: none !important; -webkit-line-clamp: unset !important; -webkit-box-orient: unset !important; overflow: visible !important; text-overflow: clip !important; white-space: pre-wrap !important; word-break: break-all !important; } body.bili-list-page .video-desc-container .toggle-btn, body.bili-list-page .video-desc-container .toggle-btn-text { display: none !important; visibility: hidden !important; height: 0 !important; padding: 0 !important; margin: 0 !important; } /* 右栏(UP主 + 播放列表 + 推荐):与视频页 right-container 相同的浮动抽屉 */ body.bili-video-page #mirror-vdcon .playlist-container--right { position: fixed !important; top: 0 !important; right: 0 !important; bottom: 0 !important; left: auto !important; width: 85vw !important; max-width: 420px !important; height: 100vh !important; max-height: 100vh !important; overflow-y: auto !important; overflow-x: hidden !important; background: #ffffff !important; z-index: 99999 !important; transform: translate3d(100%, 0, 0) !important; transition: transform 0.3s cubic-bezier(0.4, 0, 0.2, 1) !important; will-change: transform; backface-visibility: hidden; -webkit-backface-visibility: hidden; box-shadow: -4px 0 16px rgba(0, 0, 0, 0.15) !important; box-sizing: border-box !important; -webkit-overflow-scrolling: touch !important; display: block !important; padding: 12px !important; margin: 0 !important; float: none !important; } body.bili-video-page #mirror-vdcon .playlist-container--right.show { transform: translate3d(0, 0, 0) !important; } /* 抽屉内容:全部撑满宽度 */ body.bili-video-page .playlist-container--right > *, body.bili-video-page .playlist-container--right .up-panel-container, body.bili-video-page .playlist-container--right .up-info-container, body.bili-video-page .playlist-container--right .action-list-container, body.bili-video-page .playlist-container--right .action-list-header, body.bili-video-page .playlist-container--right .action-list-body, body.bili-video-page .playlist-container--right .action-list-body-top, body.bili-video-page .playlist-container--right .action-list-body-bottom, body.bili-video-page .playlist-container--right .action-list, body.bili-video-page .playlist-container--right .action-list-inner, body.bili-video-page .playlist-container--right .action-list-content, body.bili-video-page .playlist-container--right .action-list-item-wrap, body.bili-video-page .playlist-container--right .action-list-item, body.bili-video-page .playlist-container--right .singlep-list-item-inner, body.bili-video-page .playlist-container--right .multip-list-item-inner, body.bili-video-page .playlist-container--right .multip-list, body.bili-video-page .playlist-container--right .multip-list-item, body.bili-video-page .playlist-container--right .recommend-list-container { width: 100% !important; max-width: 100% !important; min-width: 0 !important; box-sizing: border-box !important; } body.bili-video-page .playlist-container--right img, body.bili-video-page .playlist-container--right video, body.bili-video-page .playlist-container--right picture { max-width: 100% !important; height: auto !important; } body.bili-video-page .playlist-container--right .action-list-header { display: flex !important; flex-wrap: wrap !important; align-items: center !important; gap: 8px !important; } body.bili-video-page .playlist-container--right .action-list-item .title, body.bili-video-page .playlist-container--right .multip-list-item .title, body.bili-video-page .playlist-container--right .list-display-name { white-space: normal !important; word-break: break-all !important; overflow-wrap: break-word !important; } /* ============================================================ 默认收藏夹 / 播放列表:内容在容器内"居中" —— 左右间距天然相等 思路:不再逐层算 padding(B站原生各层左右留白本就不等,容易一侧偏多), 改为「容器统一给一圈 gutter + 内部所有块级层 margin-inline: auto 居中」。 居中后,无论某一层残留多少单边留白,都会被均分到两侧,左右必然相等。 唯一可调变量:--fav-gutter(默认 8px),改一处、两侧同步。 滚动条按你的要求忽略(不额外预留 scrollbar-gutter)。 ============================================================ */ /* 1) 抽屉本体:左右内边距 12px -> 8px(与推荐卡片、UP 头像同一条起始线) */ body.bili-video-page #mirror-vdcon .playlist-container--right { --fav-gutter: 8px; padding-left: 8px !important; padding-right: 8px !important; } /* 2) 收藏夹容器:左右同为 --fav-gutter,这是容器内部唯一的留白来源 */ body.bili-video-page .playlist-container--right .action-list-container { padding-left: var(--fav-gutter, 8px) !important; padding-right: var(--fav-gutter, 8px) !important; margin-left: auto !important; margin-right: auto !important; } /* 3) 容器内所有块级层:清掉自身单边留白,改为左右 auto 居中 */ body.bili-video-page .playlist-container--right .action-list-header, body.bili-video-page .playlist-container--right .action-list-body, body.bili-video-page .playlist-container--right .action-list-body-top, body.bili-video-page .playlist-container--right .action-list-body-bottom, body.bili-video-page .playlist-container--right .action-list, body.bili-video-page .playlist-container--right .action-list-inner, body.bili-video-page .playlist-container--right .action-list-content, body.bili-video-page .playlist-container--right .action-list-item-wrap, body.bili-video-page .playlist-container--right .action-list-item, body.bili-video-page .playlist-container--right .singlep-list-item-inner, body.bili-video-page .playlist-container--right .multip-list-item-inner { padding-left: 0 !important; padding-right: 0 !important; margin-left: auto !important; margin-right: auto !important; width: 100% !important; max-width: 100% !important; min-width: 0 !important; box-sizing: border-box !important; } /* 标题行 / 创建者行:内部元素必须按内容取宽(不能 width:100%), 否则会把右侧的 "^" 按钮和"收藏"按钮挤到下一行(实测 header 48px -> 72px)。 这里让它们恢复 auto,并由父行用 space-between 把按钮送回最右侧。 */ body.bili-video-page .playlist-container--right .header-left, body.bili-video-page .playlist-container--right .list-display-name, body.bili-video-page .playlist-container--right .fav-btn, body.bili-video-page .playlist-container--right .list-title, body.bili-video-page .playlist-container--right .list-playorder-btn, body.bili-video-page .playlist-container--right .list-playway-btn { width: auto !important; max-width: 100% !important; min-width: 0 !important; padding-left: 0 !important; padding-right: 0 !important; margin-left: 0 !important; margin-right: 0 !important; box-sizing: border-box !important; } /* 这两行强制单行:左文案 + 右按钮,不再换行 */ body.bili-video-page .playlist-container--right .action-list-header, body.bili-video-page .playlist-container--right .action-list-body-top { display: flex !important; flex-direction: row !important; flex-wrap: nowrap !important; align-items: center !important; justify-content: space-between !important; gap: 8px !important; height: auto !important; min-height: 0 !important; } body.bili-video-page .playlist-container--right .header-left { flex: 1 1 auto !important; display: flex !important; flex-direction: row !important; flex-wrap: nowrap !important; align-items: center !important; gap: 6px !important; } /* 4) 列表滚动区:滚动条改为"零占位"模式 实测:action-list 274 -> action-list-inner 270,被滚动条吃掉 4px, 这 4px 只扣在右侧,正是"右边距比左边距大"的根源。 滚动条本来就不显示,这里直接让它不占宽度,左右两侧才可能真正相等。 (滚动手势与滚轮均不受影响) */ body.bili-video-page .playlist-container--right .action-list-body, body.bili-video-page .playlist-container--right .action-list-body-bottom, body.bili-video-page .playlist-container--right .action-list, body.bili-video-page .playlist-container--right .action-list-inner, body.bili-video-page .playlist-container--right .action-list-content { padding-left: 0 !important; padding-right: 0 !important; margin-left: auto !important; margin-right: auto !important; width: 100% !important; max-width: 100% !important; min-width: 0 !important; box-sizing: border-box !important; } body.bili-video-page .playlist-container--right .action-list { scrollbar-width: none !important; -ms-overflow-style: none !important; scrollbar-gutter: auto !important; overflow-y: auto !important; } body.bili-video-page .playlist-container--right .action-list::-webkit-scrollbar { width: 0 !important; height: 0 !important; display: none !important; background: transparent !important; } body.bili-video-page .playlist-container--right .action-list::-webkit-scrollbar-track, body.bili-video-page .playlist-container--right .action-list::-webkit-scrollbar-thumb { width: 0 !important; display: none !important; background: transparent !important; } /* 5) 列表项:三层内边距(wrap / item / inner)各 10px 全部归零并居中 */ body.bili-video-page .playlist-container--right .action-list-item-wrap, body.bili-video-page .playlist-container--right .action-list-item, body.bili-video-page .playlist-container--right .singlep-list-item-inner, body.bili-video-page .playlist-container--right .multip-list-item-inner { padding-left: 0 !important; padding-right: 0 !important; margin-left: auto !important; margin-right: auto !important; } /* 5) 列表项主体:flex 布局,封面固定 106x60,文字区吃掉剩余宽度,间距 10->8 */ body.bili-video-page .playlist-container--right .action-list-item .main, body.bili-video-page .playlist-container--right .multip-list-item .main, body.bili-video-page .playlist-container--right .singlep-list-item-inner .main, body.bili-video-page .playlist-container--right .multip-list-item-inner .main { display: flex !important; flex-direction: row !important; align-items: center !important; gap: 8px !important; width: 100% !important; max-width: 100% !important; padding: 0 !important; margin: 0 !important; box-sizing: border-box !important; } body.bili-video-page .playlist-container--right .action-list-item .main > .cover, body.bili-video-page .playlist-container--right .multip-list-item .main > .cover { flex: 0 0 106px !important; width: 106px !important; min-width: 106px !important; max-width: 106px !important; height: 60px !important; margin: 0 !important; box-sizing: border-box !important; } body.bili-video-page .playlist-container--right .action-list-item .main > .cover .cover-img, body.bili-video-page .playlist-container--right .action-list-item .main > .cover img, body.bili-video-page .playlist-container--right .multip-list-item .main > .cover .cover-img, body.bili-video-page .playlist-container--right .multip-list-item .main > .cover img { width: 100% !important; height: 100% !important; object-fit: cover !important; border-radius: 4px !important; } body.bili-video-page .playlist-container--right .action-list-item .main > .info, body.bili-video-page .playlist-container--right .multip-list-item .main > .info { flex: 1 1 auto !important; width: auto !important; min-width: 0 !important; max-width: 100% !important; height: auto !important; padding: 0 !important; margin: 0 !important; box-sizing: border-box !important; overflow: visible !important; } /* 6) 标题:吃满文字区宽度(保留原生两行截断,只解决"过早换行") */ body.bili-video-page .playlist-container--right .action-list-item .info .title, body.bili-video-page .playlist-container--right .multip-list-item .info .title { width: 100% !important; max-width: 100% !important; min-width: 0 !important; padding: 0 !important; margin: 0 !important; white-space: normal !important; word-break: break-all !important; overflow-wrap: break-word !important; box-sizing: border-box !important; } /* 7) 多P / 分集列表("第X话 …… 40:33"): 「按键本身」居中(整块在容器内居中),「按键内文字」维持 B站官方排布 —— 即标题靠左、时长靠右(space-between),不再强行居中。 结构:.multip-list > .multip-list-item > (.left-part + .duration.right-part) 【重要】这里绝不能写 display: xxx !important: B 站"展开/收起选集"正是通过切换 .multip-list / .multip-list-item 的 display(none <-> block/flex)实现的。一旦用 !important 钉死 display, 收起时元素就藏不住 —— 表现为"箭头会转、列表却不动"。 所以本组只改「布局内部分配」类属性(justify-content / gap / flex 等), 它们在 display:none 时自动失效,不会干扰展开收起。 另外绝不能用 [class*="multip-list"] > * 这种写法—— "multip-list-item" 也含 "multip-list",会被一起选中, 导致 left-part / right-part 各被撑成 100% 宽并换行,文字顶出按钮。 */ /* 选集整块:按键本体居中(块级居中 + 左右 auto) */ body.bili-video-page .playlist-container--right .multip-list, .multip-list { width: 100% !important; max-width: 100% !important; min-width: 0 !important; padding-left: 0 !important; padding-right: 0 !important; margin-left: auto !important; margin-right: auto !important; box-sizing: border-box !important; } /* 每一行的按键本体:居中于容器;内部文字回到官方的「左标题 / 右时长」 */ body.bili-video-page .playlist-container--right .multip-list > .multip-list-item, .multip-list > .multip-list-item { flex-wrap: nowrap !important; align-items: center !important; justify-content: space-between !important; gap: 8px !important; width: 100% !important; max-width: 100% !important; min-width: 0 !important; height: auto !important; padding-left: 0 !important; padding-right: 0 !important; margin-left: auto !important; margin-right: auto !important; overflow: hidden !important; box-sizing: border-box !important; } /* 左段(第X话 标题):靠左;右段(时长):靠右 —— 官方排布 */ body.bili-video-page .playlist-container--right .multip-list-item > .left-part, body.bili-video-page .playlist-container--right .multip-list-item > .right-part, .multip-list-item > .left-part, .multip-list-item > .right-part { flex: 0 1 auto !important; width: auto !important; min-width: 0 !important; max-width: 100% !important; height: auto !important; padding: 0 !important; margin: 0 !important; overflow: hidden !important; white-space: nowrap !important; text-overflow: ellipsis !important; box-sizing: border-box !important; } body.bili-video-page .playlist-container--right .multip-list-item > .left-part, .multip-list-item > .left-part { text-align: left !important; margin-right: auto !important; } /* 时长段不参与收缩,保证 "40:33" 完整显示,并贴右 */ body.bili-video-page .playlist-container--right .multip-list-item > .right-part, .multip-list-item > .right-part { flex: 0 0 auto !important; text-align: right !important; margin-left: auto !important; } body.bili-video-page .playlist-container--right .multip-list-item .title, .multip-list-item .title { width: auto !important; max-width: 100% !important; min-width: 0 !important; padding: 0 !important; margin: 0 !important; overflow: hidden !important; white-space: nowrap !important; text-overflow: ellipsis !important; text-align: left !important; box-sizing: border-box !important; } /* 与视频页一致:隐藏弹幕框、私信、充电、广告 */ body.bili-video-page .playlist-container--right #danmukuBox, body.bili-video-page .playlist-container--right .danmaku-box, body.bili-video-page .playlist-container--right .send-msg, body.bili-video-page .playlist-container--right a.send-msg, body.bili-video-page .playlist-container--right .new-charge-btn, body.bili-video-page .playlist-container--right [class*="ad-"], body.bili-video-page .playlist-container--right [class*="ads-"], body.bili-video-page .playlist-container--right .video-card-ad-small { display: none !important; visibility: hidden !important; height: 0 !important; width: 0 !important; padding: 0 !important; margin: 0 !important; overflow: hidden !important; } /* UP 主信息:与视频页 right-container 保持一致 */ body.bili-video-page .playlist-container--right .up-info-container { display: flex !important; align-items: center !important; width: 100% !important; gap: 8px !important; } body.bili-video-page .playlist-container--right .up-info--right { flex: 1 1 auto !important; min-width: 0 !important; width: auto !important; max-width: 100% !important; display: flex !important; flex-direction: column !important; } body.bili-video-page .playlist-container--right .up-info__detail, body.bili-video-page .playlist-container--right .up-detail, body.bili-video-page .playlist-container--right .up-description { width: 100% !important; max-width: 100% !important; min-width: 0 !important; word-break: break-all !important; white-space: normal !important; overflow-wrap: break-word !important; box-sizing: border-box !important; } body.bili-video-page .playlist-container--right .up-detail-top { display: flex !important; align-items: center !important; justify-content: flex-start !important; width: 100% !important; gap: 8px !important; } body.bili-video-page .playlist-container--right .up-name { white-space: nowrap !important; text-overflow: ellipsis !important; overflow: hidden !important; flex-shrink: 1 !important; min-width: 0 !important; max-width: 100% !important; } body.bili-video-page .playlist-container--right .follow-btn .menu-popover, body.bili-video-page .playlist-container--right .follow-btn-wrapper { position: absolute !important; top: 100% !important; right: 0 !important; left: auto !important; z-index: 9999999 !important; transform: none !important; margin-top: 4px !important; background: #fff !important; border-radius: 4px !important; box-shadow: 0 2px 8px rgba(0,0,0,0.15) !important; } /* 全屏时左栏铺满(与视频页 left-container 一致) */ body.video-fullscreen .playlist-container--left { width: 100vw !important; max-width: 100vw !important; min-width: 100vw !important; height: 100vh !important; min-height: 0 !important; padding: 0 !important; margin: 0 !important; overflow: hidden !important; } /* ============================================================ ========== 番剧播放页 ========== ============================================================ */ html:has(body.bili-bangumi-page), body.bili-bangumi-page { background: #ffffff !important; width: 100% !important; max-width: 100vw !important; min-width: 0 !important; overflow-x: hidden !important; padding-top: 0 !important; margin: 0 !important; position: relative !important; } body.bili-bangumi-page #__next, body.bili-bangumi-page .home-container { width: 100% !important; max-width: 100vw !important; min-width: 0 !important; overflow-x: hidden !important; box-sizing: border-box !important; margin: 0 !important; padding: 0 !important; display: block !important; position: relative !important; } body.bili-bangumi-page .main-container, body.bili-bangumi-page .plp-layout, body.bili-bangumi-page .plp-left-wrap, body.bili-bangumi-page .plp-l, body.bili-bangumi-page .player-left-components { width: 100% !important; max-width: 100% !important; min-width: 0 !important; overflow-x: hidden !important; box-sizing: border-box !important; margin: 0 !important; padding: 0 !important; display: contents !important; position: static !important; left: auto !important; right: auto !important; float: none !important; } /* ★★★ 番剧页播放器顶部间距:36px;宽屏下收窄并居中 ★★★ */ body.bili-bangumi-page .plp-player { width: 100% !important; max-width: 100% !important; padding: 0 8px !important; margin: 36px auto !important; box-sizing: border-box !important; height: auto !important; min-height: 0 !important; } /* 番剧页正文容器(播放器 + 信息区)宽屏下居中显示 */ body.bili-bangumi-page .plp-layout, body.bili-bangumi-page .plp-left-wrap, body.bili-bangumi-page .plp-l { max-width: 820px !important; margin-left: auto !important; margin-right: auto !important; } body.bili-bangumi-page .plp-left-wrap { padding: 0 8px !important; } body.bili-bangumi-page [class*="mediainfo_mediaInfoWrap"] { margin-top: 0 !important; } /* ===== 番剧播放页:禁止点标题 / 简介跳转(v131.61) ===== 探针 09-29_11-25-18 实测(视口 360): .mediainfo_mediaRight__SDOq4[320x385] left=20 > **a.mediainfo_mediaTitle__Zyiqh[320x25]** ← 标题,是 > **a.mediainfo_media_desc_section__Vkt2t[320x276]** ← 简介,也是 > div.mediainfo_display_area__ggRQT > p.mediainfo_content__rexOq[320x270] 两者都是真链接(),手机上手指点标题或简介正文都会整页跳走, 而本站已经在播这一集,跳走纯属误触。 改法(纯 CSS,不动任何 JS): pointer-events: none —— 元素彻底不参与命中测试, 点击/长按/悬停一律落到父容器上,链接的默认跳转行为根本不会被触发。 比 JS 里 addEventListener('click', e => e.preventDefault()) 更干净: · 不依赖节点是否已渲染(CSS 对后插入的节点自动生效) · 不受站内 React 事件委托 / 冒泡顺序影响 · 不需要 MutationObserver 反复重挂 · pointer-events 是**可继承**属性,子节点一并失效, 简介里的

正文、

容器都不用逐个点名。 配套两点小修: · cursor: default —— 不再是"手型",视觉上不像链接; · text-decoration: none —— 去掉链接下划线(若有)。 ⚠ 刻意不改 color:标题/简介的颜色保持站内原样,只改交互不改外观。 ⚠ 文字选中不受影响:pointer-events:none 只拦指针事件, 长按拖选仍会命中父容器并在 DOM 上选中这段文字。 选择器用 [class*=] 前缀匹配 —— tailwind 式哈希后缀(__Zyiqh) 会随版本变,前缀匹配才不会被站内更新打断。---- */ body.bili-bangumi-page [class*="mediainfo_mediaTitle"], body.bili-bangumi-page [class*="mediainfo_media_desc_section"], body.bili-video-page [class*="mediainfo_mediaTitle"], body.bili-video-page [class*="mediainfo_media_desc_section"] { pointer-events: none !important; cursor: default !important; text-decoration: none !important; } /* 子节点显式再压一层:防站内给

/

单独写了 pointer-events:auto */ body.bili-bangumi-page [class*="mediainfo_media_desc_section"] *, body.bili-video-page [class*="mediainfo_media_desc_section"] * { pointer-events: none !important; } body.bili-bangumi-page #bilibili-player-wrap { position: relative !important; width: 100% !important; max-width: 100% !important; height: calc((100vw - 22px) * 9 / 16 + 6px) !important; max-height: calc((100vw - 22px) * 9 / 16 + 6px) !important; padding: 0 !important; border: 3px solid #00aeec !important; border-radius: 12px !important; box-shadow: 0 4px 16px rgba(0, 174, 236, 0.25) !important; overflow: hidden !important; box-sizing: border-box !important; margin: 0 auto !important; } body.bili-bangumi-page #bilibili-player-wrap .video_playerInner__ox52b, body.bili-bangumi-page #bilibili-player-wrap #bilibili-player, body.bili-bangumi-page #bilibili-player-wrap .big-nano-player, body.bili-bangumi-page #bilibili-player-wrap .bpx-docker, body.bili-bangumi-page #bilibili-player-wrap .bpx-player-container, body.bili-bangumi-page #bilibili-player-wrap .bpx-player-primary-area, body.bili-bangumi-page #bilibili-player-wrap .bpx-player-video-area, body.bili-bangumi-page #bilibili-player-wrap .bpx-player-video-wrap { position: absolute !important; top: 0 !important; left: 0 !important; width: 100% !important; height: 100% !important; max-width: 100% !important; max-height: 100% !important; margin: 0 !important; padding: 0 !important; box-sizing: border-box !important; transform: none !important; border-radius: 0 !important; } body.bili-bangumi-page #bilibili-player-wrap video { position: absolute !important; top: 0 !important; left: 0 !important; width: 100% !important; height: 100% !important; object-fit: contain !important; background-color: #000 !important; } body.bili-bangumi-page .bpx-player-sending-area { display: none !important; } /* ★ 修复简介完全展开后叠加到评论区的问题 ★ 根因:plp-l.sticky 原始为 position: sticky, 简介展开后高度溢出,sticky 定位导致内容叠在评论区上方。 同时 plp-left-wrap / plp-l 需高度自适应, player-left-components 为 display: contents 已不占位。 */ body.bili-bangumi-page .plp-left-wrap { padding: 0 8px !important; display: block !important; height: auto !important; min-height: auto !important; max-height: none !important; overflow: visible !important; position: static !important; } body.bili-bangumi-page .plp-l, body.bili-bangumi-page .plp-l.sticky { padding: 0 !important; display: block !important; position: static !important; top: auto !important; bottom: auto !important; height: auto !important; min-height: auto !important; max-height: none !important; overflow: visible !important; } body.bili-bangumi-page .player-left-components { padding: 0 !important; display: contents !important; } body.bili-bangumi-page .toolbar, body.bili-bangumi-page #like_info, body.bili-bangumi-page #ogv_weslie_tool_coin_info, body.bili-bangumi-page #ogv_weslie_tool_favorite_info, body.bili-bangumi-page #share-container-id, body.bili-bangumi-page #watch_together_tab, body.bili-bangumi-page #tool-bar-more, body.bili-bangumi-page .toolbar-right { display: none !important; visibility: hidden !important; height: 0 !important; padding: 0 !important; margin: 0 !important; overflow: hidden !important; } body.bili-bangumi-page .mediainfo_mediaToolbar__8Q7bn { display: none !important; visibility: hidden !important; height: 0 !important; padding: 0 !important; margin: 0 !important; overflow: hidden !important; } body.bili-bangumi-page .mediainfo_bottomBar__uBfeO { display: none !important; visibility: hidden !important; height: 0 !important; padding: 0 !important; margin: 0 !important; overflow: hidden !important; } body.bili-bangumi-page [class*="navTools_floatNavExp"], body.bili-bangumi-page [class*="navTools_navMenu"] { display: none !important; visibility: hidden !important; height: 0 !important; width: 0 !important; padding: 0 !important; margin: 0 !important; overflow: hidden !important; } body.bili-bangumi-page [class*="mediainfo_mediaInfoWrap"] { display: flex !important; flex-direction: column !important; align-items: stretch !important; justify-content: flex-start !important; flex-wrap: nowrap !important; width: 100% !important; max-width: 100% !important; min-width: 0 !important; padding: 10px 12px !important; margin: 0 !important; box-sizing: border-box !important; height: auto !important; min-height: auto !important; max-height: none !important; overflow: visible !important; } /* 确保 mediaInfoWrap 的 flex 子元素正常排列,不被压缩 */ body.bili-bangumi-page [class*="mediainfo_mediaInfoWrap"] > * { flex: 0 0 auto !important; min-height: auto !important; max-height: none !important; } body.bili-bangumi-page [class*="mediainfo_mediaInfoWrap"] [class*="mediainfo_display_area"] { flex: 1 1 auto !important; } /* ★★★ 番剧页:隐藏封面图区域(图中红框部分) ★★★ 仅作用于 mediainfo_mediaCover 内部,避免误伤侧边栏推荐/选集封面 */ body.bili-bangumi-page [class*="mediainfo_mediaCover"], body.bili-bangumi-page a[class*="mediainfo_mediaCover"], body.bili-bangumi-page [class*="mediainfo_mediaCover"] picture, body.bili-bangumi-page [class*="mediainfo_mediaCover"] img, body.bili-bangumi-page [class*="mediainfo_mediaCover"] svg { display: none !important; visibility: hidden !important; width: 0 !important; max-width: 0 !important; min-width: 0 !important; height: 0 !important; max-height: 0 !important; min-height: 0 !important; padding: 0 !important; margin: 0 !important; border: 0 !important; opacity: 0 !important; overflow: hidden !important; position: absolute !important; left: -9999px !important; top: -9999px !important; pointer-events: none !important; flex: 0 0 0 !important; } body.bili-bangumi-page [class*="mediainfo_mediaRight"] { width: 100% !important; max-width: 100% !important; min-width: 0 !important; display: flex !important; flex-direction: column !important; align-items: center !important; justify-content: flex-start !important; text-align: center !important; padding: 0 !important; margin: 0 !important; box-sizing: border-box !important; float: none !important; position: static !important; height: auto !important; min-height: auto !important; max-height: none !important; overflow: visible !important; } body.bili-bangumi-page [class*="mediainfo_mediaTitle"] { font-size: 16px !important; font-weight: bold !important; margin: 0 0 6px 0 !important; padding: 0 !important; text-align: center !important; width: 100% !important; display: block !important; height: auto !important; max-height: none !important; overflow: visible !important; -webkit-line-clamp: unset !important; word-break: break-word !important; } /* ★ 番剧简介:始终完全展开,隐藏"展开/收起"按钮 ★ B站原生机制:收起态 display_area 用 -webkit-line-clamp 限高, ellipsis 是末行渐变遮罩+"展开"按钮;展开态切换为纯 p 标签。 实测无论多少字,展开后也只多显示约一行,按钮意义不明。 方案:强制解除所有高度/行数限制,隐藏 ellipsis/placeholder/按钮, 让简介始终完整显示(纯 CSS,无 JS)。 两套 DOM 结构: 收起态 a[class*="mediainfo_media_desc_section"] -> div.display_area > div.placeholder(hidden) + p.content + div.ellipsis("展开") -> p.content_placeholder(hidden) 展开态 a[class*="mediainfo_media_desc"] -> p > span("简介:") + i("收起") */ body.bili-bangumi-page [class*="mediainfo_media_desc"] p, body.bili-bangumi-page [class*="mediainfo_media_desc"] p *, body.bili-bangumi-page [class*="mediainfo_display_area"], body.bili-bangumi-page [class*="mediainfo_display_area"] *, body.bili-bangumi-page [class*="mediainfo_content"], body.bili-bangumi-page [class*="mediainfo_content"] * { color: #61666d !important; font-size: 13px !important; font-weight: 400 !important; line-height: 1.6 !important; letter-spacing: normal !important; font-style: normal !important; text-transform: none !important; text-align: center !important; } body.bili-bangumi-page [class*="mediainfo_media_desc"] { width: 100% !important; max-width: 100% !important; display: block !important; padding: 6px 0 0 0 !important; margin: 0 !important; box-sizing: border-box !important; height: auto !important; min-height: auto !important; max-height: none !important; overflow: visible !important; -webkit-line-clamp: unset !important; -webkit-box-orient: unset !important; text-overflow: clip !important; white-space: normal !important; word-break: break-word !important; } body.bili-bangumi-page [class*="mediainfo_media_desc"] p { width: 100% !important; max-width: 100% !important; margin: 0 !important; padding: 0 !important; box-sizing: border-box !important; height: auto !important; min-height: auto !important; max-height: none !important; overflow: visible !important; -webkit-line-clamp: unset !important; -webkit-box-orient: unset !important; text-overflow: clip !important; white-space: pre-wrap !important; word-break: break-word !important; } /* ★ 关键:解除 display_area 的高度与行数限制,让收起态也能完整展开 ★ 同时强制 position: static,防止 B站原始 absolute 定位导致 简介脱离文档流、叠加到评论区上方 */ body.bili-bangumi-page [class*="mediainfo_display_area"] { position: static !important; top: auto !important; left: auto !important; right: auto !important; bottom: auto !important; width: 100% !important; max-width: 100% !important; min-width: 0 !important; display: block !important; margin: 0 !important; padding: 0 !important; box-sizing: border-box !important; height: auto !important; min-height: auto !important; max-height: none !important; overflow: visible !important; -webkit-line-clamp: unset !important; -webkit-box-orient: unset !important; text-overflow: clip !important; white-space: normal !important; word-break: break-word !important; float: none !important; z-index: auto !important; } body.bili-bangumi-page [class*="mediainfo_content"] { width: 100% !important; max-width: 100% !important; min-width: 0 !important; display: block !important; margin: 0 !important; padding: 0 !important; box-sizing: border-box !important; height: auto !important; min-height: auto !important; max-height: none !important; overflow: visible !important; -webkit-line-clamp: unset !important; -webkit-box-orient: unset !important; text-overflow: clip !important; white-space: pre-wrap !important; word-break: break-word !important; } /* ★ 隐藏"展开/收起"按钮、渐变遮罩、占位测量元素 ★ */ body.bili-bangumi-page [class*="mediainfo_ellipsis"], body.bili-bangumi-page [class*="mediainfo_placeholder"], body.bili-bangumi-page [class*="mediainfo_expand"], body.bili-bangumi-page [class*="mediainfo_expandBtn"], body.bili-bangumi-page [class*="mediainfo_moreBtn"], body.bili-bangumi-page [class*="mediainfo_toggleBtn"], body.bili-bangumi-page [class*="mediainfo_content_placeholder"] { display: none !important; visibility: hidden !important; width: 0 !important; height: 0 !important; max-height: 0 !important; padding: 0 !important; margin: 0 !important; overflow: hidden !important; } /* ★ 隐藏展开态 p 里的 收起 按钮文字 ★ */ body.bili-bangumi-page [class*="mediainfo_media_desc"] p > i, body.bili-bangumi-page [class*="mediainfo_content"] i { display: none !important; visibility: hidden !important; } body.bili-bangumi-page [class*="mediainfo_mediaRating"] { display: inline-flex !important; justify-content: center !important; align-items: center !important; margin: 0 auto !important; } body.bili-bangumi-page [class*="upinfo_upInfoCard"] { display: inline-flex !important; justify-content: center !important; align-items: center !important; margin: 0 auto !important; } body.bili-bangumi-page #comment-module { width: 100% !important; max-width: 100% !important; min-width: 0 !important; padding: 12px 0 0 0 !important; margin: 0 !important; box-sizing: border-box !important; overflow: hidden !important; display: block !important; position: static !important; clear: both !important; } body.bili-bangumi-page #comment-module * { max-width: 100% !important; box-sizing: border-box !important; } body.bili-bangumi-page #comment-body { width: 100% !important; max-width: 100% !important; min-width: 0 !important; padding: 0 8px !important; margin: 0 !important; box-sizing: border-box !important; overflow: hidden !important; display: block !important; } body.bili-bangumi-page #comment-body bili-comments { display: block !important; width: 100% !important; max-width: 100% !important; min-width: 0 !important; padding: 0 !important; margin: 0 !important; box-sizing: border-box !important; overflow: hidden !important; position: static !important; } /* ============================================================ ========== 番剧页播放器控制栏 ========== ============================================================ */ body.bili-bangumi-page .bpx-player-ctrl-pip, body.bili-bangumi-page .bpx-player-ctrl-wide, body.bili-bangumi-page .bpx-player-ctrl-time, body.bili-bangumi-page .bpx-player-ctrl-eplist { display: none !important; } @media screen and (orientation: landscape) { body.bili-bangumi-page .bpx-player-ctrl-time { display: block !important; } } @media screen and (width >= 750px) { body.bili-bangumi-page .bpx-player-container[data-screen=full] .bpx-player-ctrl-quality-result { height: unset !important; font-size: 16px !important; } body.bili-bangumi-page .bpx-player-container[data-screen=full] .bpx-player-control-wrap { height: 43px !important; } body.bili-bangumi-page .bpx-player-container[data-screen=full] .bpx-player-control-top { bottom: 43px !important; } } body.bili-bangumi-page div.bpx-player-control-bottom { height: 29px !important; margin-top: 7px !important; padding: 0 7px !important; } body.bili-bangumi-page div.bpx-player-control-top { transition: none; bottom: 36px; } body.bili-bangumi-page .bpx-player-pbp .bpx-player-pbp-pin-tip { display: none !important; } body.bili-bangumi-page .bpx-player-control-bottom-left, body.bili-bangumi-page .bpx-player-control-bottom-right { flex: unset !important; } body.bili-bangumi-page .bpx-player-container .bpx-player-control-bottom-left, body.bili-bangumi-page .bpx-player-container .bpx-player-control-bottom-right { min-width: 0 !important; } body.bili-bangumi-page .bpx-player-ctrl-quality { min-width: 0; flex: auto !important; margin-right: 0 !important; } body.bili-bangumi-page .bpx-player-ctrl-quality-result, body.bili-bangumi-page .bpx-player-ctrl-playbackrate { font-size: 12px !important; } body.bili-bangumi-page .bpx-player-ctrl-quality-result { height: 22px; overflow: hidden; } body.bili-bangumi-page .bpx-player-ctrl-playbackrate { text-wrap: nowrap; } body.bili-bangumi-page .bpx-player-progress-wrap { height: 7px !important; padding-bottom: 3px !important; } body.bili-bangumi-page .bpx-player-control-mask { background: linear-gradient(rgba(0,0,0,0) 0%, rgba(0,0,0,0.5) 100%) !important; } body.bili-bangumi-page .bpx-player-ctrl-quality-menu-wrap { bottom: 22px !important; } body.bili-bangumi-page .bpx-player-ctrl-quality-menu-item { max-width: 95px; max-height: 36px; height: 7.7vw !important; padding: 0 8px 0 12px !important; } body.bili-bangumi-page .bpx-player-ctrl-quality-badge-bigvip { color: #fff; background-color: #f25d8e; width: 16px; overflow: hidden; right: 8px !important; } body.bili-bangumi-page .bpx-player-ctrl-quality-badge-bigvip:before { color: #fff; content: "V"; background-color: #f25d8e; padding: 0 4px; position: absolute; left: 0; } body.bili-bangumi-page .bpx-player-ctrl-playbackrate-menu { bottom: 22px !important; } body.bili-bangumi-page .bpx-player-ctrl-playbackrate-menu-item { justify-content: center; align-items: center; max-height: 36px; display: flex; height: 7.7vw !important; } body.bili-bangumi-page div.bpx-player-ctrl-subtitle-box { bottom: 0; right: 0; transform: scale(.8); } body.bili-bangumi-page .bpx-player-ctrl-setting-box { bottom: 0 !important; right: 0 !important; } body.bili-bangumi-page .bpx-player-ctrl-setting-menu-right { padding: 5px !important; } body.bili-bangumi-page .bpx-player-ctrl-setting-menu-right > div { justify-content: center; align-items: center; max-height: 40px; display: flex; height: 10vw !important; } body.bili-bangumi-page .bpx-player-ctrl-setting-menu-right .bui-radio { width: 77%; margin: 0 0 8px 7px; } body.bili-bangumi-page .bpx-player-ctrl-setting-others-content { margin-left: 7px; width: 77% !important; } body.bili-bangumi-page .bpx-player-ctrl-setting-highenergy .bui-checkbox-name { white-space: nowrap; width: 48px; overflow: hidden; } body.bili-bangumi-page .bpx-player-dm-setting-wrap { top: 0; left: 50%; transform: translate(-50%); bottom: unset !important; position: fixed !important; } body.bili-bangumi-page .bpx-player-control-bottom-center .bpx-player-sending-bar { height: 24px !important; padding-right: 6px !important; } body.bili-bangumi-page .bpx-player-ctrl-viewpoint { flex-shrink: 1 !important; width: 45px !important; min-width: 0 !important; margin: 0 !important; } body.bili-bangumi-page .bpx-player-ctrl-viewpoint-text { flex: none; font-size: 12px; width: 24px !important; text-overflow: unset !important; } body.bili-bangumi-page .bpx-player-control-wrap:not(.new) { display: none; } body.bili-bangumi-page .bpx-player-control-entity, body.bili-bangumi-page .bpx-player-control-mask { display: block !important; } body.bili-bangumi-page .bpx-player-container[data-ctrl-hidden=true] .bpx-player-control-bottom { display: none; } body.bili-bangumi-page .bpx-player-container[ctrl-shown=false] .bpx-player-control-wrap .bpx-player-control-mask { opacity: 0; transition: opacity .2s ease-in; } body.bili-bangumi-page .bpx-player-container[ctrl-shown=true] .bpx-player-control-wrap .bpx-player-control-mask { opacity: 1; } body.bili-bangumi-page .bpx-player-container[ctrl-shown=true] .bpx-player-control-entity .bpx-player-control-bottom { opacity: 1; display: flex; } body.bili-bangumi-page .bpx-player-container[ctrl-shown=false] .bpx-player-control-entity .bpx-player-control-bottom { display: none; } body.bili-bangumi-page .bpx-player-container[ctrl-shown=true] .bpx-player-control-entity .bpx-player-control-top, body.bili-bangumi-page .bpx-player-container[ctrl-shown=false] .bpx-player-control-entity .bpx-player-shadow-progress-area { opacity: 1; visibility: visible; } body.bili-bangumi-page .bpx-player-container[ctrl-shown=false] .bpx-player-control-entity .bpx-player-control-top, body.bili-bangumi-page .bpx-player-container[ctrl-shown=true] .bpx-player-control-entity .bpx-player-shadow-progress-area { opacity: 0; visibility: hidden; } body.bili-bangumi-page .bpx-player-container[ctrl-shown=true] .bpx-player-control-entity .bpx-player-pbp { opacity: 1; width: 100%; bottom: calc(100% + 6px); left: 0; } body.bili-bangumi-page div.bpx-player-control-entity .bpx-player-pbp { opacity: 0; width: calc(100% + 24px); bottom: 1px; left: -12px; } body.bili-bangumi-page div.bpx-player-control-entity .bpx-player-pbp.pin { opacity: 1; } body.bili-bangumi-page .bpx-player-pbp-pin { display: none; opacity: 1 !important; } body.bili-bangumi-page .bpx-player-container[ctrl-shown=true] .bpx-player-control-entity .bpx-player-pbp-pin { display: block; } body.bili-bangumi-page .bpx-player-video-perch { max-height: 0; } body.bili-bangumi-page .bpx-player-top-wrap, body.bili-bangumi-page .bpx-player-state-wrap { display: none !important; } body.bili-bangumi-page .bpx-player-container, body.bili-bangumi-page #bilibili-player-placeholder { box-shadow: none !important; } /* ===== 动态页 ===== */ body.bili-dynamic-page { background: #f4f5f7 !important; } body.bili-dynamic-page .bili-header, body.bili-dynamic-page .international-header, body.bili-dynamic-page .mini-header, body.bili-dynamic-page .bili-header__bar, body.bili-dynamic-page .bili-header__menu, body.bili-dynamic-page #bili-header-container { display: none !important; visibility: hidden !important; height: 0 !important; overflow: hidden !important; } body.bili-dynamic-page .bgc, body.bili-dynamic-page .bg { display: none !important; } body.bili-dynamic-page .bili-dyn-home--member > .left, body.bili-dynamic-page .bili-dyn-home--member > aside.left, body.bili-dynamic-page .bili-dyn-home--member > .right, body.bili-dynamic-page .bili-dyn-home--member > aside.right, body.bili-dynamic-page .bili-dyn-sidebar, body.bili-dynamic-page .bili-dyn-sidebar__btn { display: none !important; visibility: hidden !important; width: 0 !important; height: 0 !important; overflow: hidden !important; } body.bili-dynamic-page #app, body.bili-dynamic-page #app > div, body.bili-dynamic-page .bili-dyn-home--member, body.bili-dynamic-page .bili-dyn-home--member > main, body.bili-dynamic-page .bili-dyn-list, body.bili-dynamic-page .bili-dyn-list__item, body.bili-dynamic-page .bili-dyn-item { width: 100% !important; max-width: 100% !important; min-width: 0 !important; padding-left: 0 !important; padding-right: 0 !important; margin-left: 0 !important; margin-right: 0 !important; box-sizing: border-box !important; float: none !important; } body.bili-dynamic-page .bili-dyn-list__items { padding: 8px 0 8px 0 !important; margin: 0 !important; box-sizing: border-box !important; } body.bili-dynamic-page .bili-dyn-list__item { padding: 0 8px 8px 8px !important; margin: 0 !important; box-sizing: border-box !important; } body.bili-dynamic-page .bili-dyn-item { position: relative !important; background: #ffffff !important; border: 1px solid #e3e5e7 !important; border-radius: 8px !important; padding: 12px 8px 0 8px !important; margin: 0 !important; box-sizing: border-box !important; overflow: hidden !important; width: 100% !important; max-width: 100% !important; min-width: 0 !important; display: block !important; float: none !important; } body.bili-dynamic-page .bili-dyn-item * { max-width: 100% !important; box-sizing: border-box !important; } body.bili-dynamic-page .bili-dyn-item img, body.bili-dynamic-page .bili-dyn-item video, body.bili-dynamic-page .bili-dyn-item picture { max-width: 100% !important; height: auto !important; } body.bili-dynamic-page .bili-dyn-item__main { position: relative !important; padding-left: 0 !important; padding-right: 0 !important; box-sizing: border-box !important; width: 100% !important; max-width: 100% !important; min-width: 0 !important; float: none !important; } body.bili-dynamic-page .bili-dyn-item__avatar { position: absolute !important; left: 0 !important; top: 0 !important; width: 56px !important; max-width: 56px !important; min-width: 0 !important; padding: 0 !important; margin: 0 !important; box-sizing: border-box !important; } body.bili-dynamic-page .bili-dyn-item__avatar .bili-dyn-avatar, body.bili-dynamic-page .bili-dyn-item__avatar .b-avatar, body.bili-dynamic-page .bili-dyn-item__avatar img { width: 48px !important; height: 48px !important; max-width: 100% !important; border-radius: 50% !important; } body.bili-dynamic-page .bili-dyn-item__header { margin-left: 0 !important; margin-right: 0 !important; padding-left: 64px !important; padding-right: 8px !important; width: auto !important; max-width: 100% !important; min-width: 0 !important; box-sizing: border-box !important; } body.bili-dynamic-page .bili-dyn-item__more, body.bili-dynamic-page .bili-dyn-more, body.bili-dynamic-page .bili-dyn-more__btn, body.bili-dynamic-page .bili-dyn-more__cascader { display: none !important; visibility: hidden !important; } body.bili-dynamic-page .bili-dyn-content, body.bili-dynamic-page .bili-dyn-content__orig, body.bili-dynamic-page .bili-dyn-content__orig__major { width: 100% !important; max-width: 100% !important; min-width: 0 !important; box-sizing: border-box !important; } body.bili-dynamic-page .bili-dyn-card-video { display: flex !important; flex-direction: column !important; width: 100% !important; max-width: 100% !important; min-width: 0 !important; height: auto !important; box-sizing: border-box !important; } body.bili-dynamic-page .bili-dyn-card-video__header { width: 100% !important; max-width: 100% !important; height: auto !important; flex: 0 0 auto !important; box-sizing: border-box !important; } body.bili-dynamic-page .bili-dyn-card-video__cover { width: 100% !important; max-width: 100% !important; height: auto !important; aspect-ratio: 16 / 9 !important; box-sizing: border-box !important; } body.bili-dynamic-page .bili-dyn-card-video__cover .b-img, body.bili-dynamic-page .bili-dyn-card-video__cover .b-img__inner, body.bili-dynamic-page .bili-dyn-card-video__cover img, body.bili-dynamic-page .bili-dyn-card-video__cover picture { width: 100% !important; max-width: 100% !important; height: auto !important; aspect-ratio: 16 / 9 !important; object-fit: cover !important; display: block !important; } body.bili-dynamic-page .bili-dyn-card-video__body { width: 100% !important; max-width: 100% !important; height: auto !important; flex: 1 1 auto !important; padding: 8px 0 0 0 !important; box-sizing: border-box !important; } /* 投稿了视频:隐藏视频封面下方「框住标题/简介文字」的那条左侧半开口边框 */ body.bili-dynamic-page .bili-dyn-card-video__body, body.bili-dynamic-page .bili-dyn-card-video__title, body.bili-dynamic-page .bili-dyn-card-video__desc { border: none !important; border-top: none !important; border-right: none !important; border-bottom: none !important; border-left: none !important; border-width: 0 !important; border-style: none !important; box-shadow: none !important; outline: none !important; } /* 该边框也可能是 ::before / ::after 画的竖条,一并清掉 */ body.bili-dynamic-page .bili-dyn-card-video__body::before, body.bili-dynamic-page .bili-dyn-card-video__body::after, body.bili-dynamic-page .bili-dyn-card-video__desc::before, body.bili-dynamic-page .bili-dyn-card-video__desc::after { content: none !important; display: none !important; border: none !important; background: none !important; box-shadow: none !important; } body.bili-dynamic-page .bili-dyn-card-video__title, body.bili-dynamic-page .bili-dyn-card-video__desc, body.bili-dynamic-page .bili-dyn-card-video__title .bili-ellipsis, body.bili-dynamic-page .bili-dyn-card-video__desc .bili-ellipsis { text-align: center !important; } body.bili-dynamic-page .bili-dyn-card-video__stat, body.bili-dynamic-page .bili-dyn-card-video__stat__item, body.bili-dynamic-page .bili-dyn-card-video__stat__item.danmaku { display: none !important; visibility: hidden !important; height: 0 !important; overflow: hidden !important; margin: 0 !important; padding: 0 !important; } body.bili-dynamic-page .bili-dyn-item, body.bili-dynamic-page .bili-dyn-item * { text-align: center !important; } /* 正文容器:只做内边距约束,绝不能隐藏(正文 .bili-dyn-content 就在它里面) */ body.bili-dynamic-page .bili-dyn-item__body { margin-left: 0 !important; margin-right: 0 !important; padding-left: 8px !important; padding-right: 8px !important; width: 100% !important; max-width: 100% !important; box-sizing: border-box !important; } /* 去掉卡片内的「转发 / 评论 / 点赞」数量行(整行隐藏) */ body.bili-dynamic-page .bili-dyn-item__footer, body.bili-dynamic-page .bili-dyn-item__action, body.bili-dynamic-page .bili-dyn-action, body.bili-dynamic-page .bili-dyn-action.forward, body.bili-dynamic-page .bili-dyn-action.comment, body.bili-dynamic-page .bili-dyn-action.like { display: none !important; visibility: hidden !important; height: 0 !important; min-height: 0 !important; max-height: 0 !important; padding: 0 !important; margin: 0 !important; border: none !important; overflow: hidden !important; } /* 隐藏该行后,卡片底部补回一点留白,避免内容紧贴卡片下边缘 */ body.bili-dynamic-page .bili-dyn-item { padding-bottom: 12px !important; } body.bili-dynamic-page .bili-dyn-content__orig__major img, body.bili-dynamic-page .bili-dyn-content__orig__major picture, body.bili-dynamic-page .bili-dyn-content__orig__major .b-img { margin-left: auto !important; margin-right: auto !important; display: block !important; } body.bili-dynamic-page .bili-dyn-content__orig__major [class*="grid"], body.bili-dynamic-page .bili-dyn-content__orig__major [class*="pics"], body.bili-dynamic-page .bili-dyn-content__orig__major [class*="gallery"], body.bili-dynamic-page .bili-dyn-content__orig__major [class*="goods"], body.bili-dynamic-page .bili-dyn-content__orig__major [class*="commodity"], body.bili-dynamic-page .bili-dyn-content__orig__major [class*="card"] { margin-left: auto !important; margin-right: auto !important; justify-content: center !important; } body.bili-dynamic-page .bili-dyn-item__action { flex: 1 1 0 !important; width: auto !important; max-width: none !important; min-width: 0 !important; box-sizing: border-box !important; display: flex !important; align-items: center !important; justify-content: center !important; } body.bili-dynamic-page .bili-dyn-action { display: flex !important; align-items: center !important; justify-content: center !important; width: 100% !important; gap: 4px !important; } body.bili-dynamic-page .bili-dyn-list-tabs, body.bili-dynamic-page .bili-dyn-list-tabs__list, body.bili-dynamic-page .bili-dyn-list-tabs__item { display: none !important; visibility: hidden !important; height: 0 !important; overflow: hidden !important; } body.bili-dynamic-page .bili-dyn-home--member > main > section:nth-of-type(1), body.bili-dynamic-page .bili-dyn-home--member > main > section:nth-of-type(2) { display: none !important; visibility: hidden !important; height: 0 !important; overflow: hidden !important; } body.bili-dynamic-page .bili-dyn-search-trendings, body.bili-dynamic-page .trending-list, body.bili-dynamic-page .sticky { display: none !important; } /* ============================================================ 动态详情页(t.bilibili.com/xxx 单条动态展开):评论区与视频页一致 结构:#app > .content > .card > .bili-tabs.dyn-tabs > .bili-tabs__content > .bili-tab-pane > .comment-wrap > .bili-comment-container > bili-comments(shadow DOM) 实测:bili-comments 仅 312 宽(360 屏),左右各 24px;视频页为 8px。 这里按视频页 #commentapp 的同一套外框规则拉齐, shadow 内部(输入框/点赞/回复按钮等)由 installShadowRootPatch 统一处理。 ============================================================ */ body.bili-dynamic-page .bili-tabs.dyn-tabs, body.bili-dynamic-page .bili-tabs__content, body.bili-dynamic-page .bili-tab-pane, body.bili-dynamic-page .comment-wrap, body.bili-dynamic-page .bili-comment-container { width: 100% !important; max-width: 100% !important; min-width: 0 !important; box-sizing: border-box !important; padding-left: 8px !important; padding-right: 8px !important; margin-left: 0 !important; margin-right: 0 !important; overflow: hidden !important; float: none !important; position: static !important; } body.bili-dynamic-page bili-comments, body.bili-dynamic-page .bili-comment-container bili-comments { width: 100% !important; max-width: 100% !important; min-width: 0 !important; box-sizing: border-box !important; display: block !important; } /* 与视频页一致:外部的输入框/编辑器容器一并隐藏(shadow 内由 patch 处理) */ body.bili-dynamic-page .bili-comment-box, body.bili-dynamic-page .bili-comment-input-wrap, body.bili-dynamic-page .comment-send-box, body.bili-dynamic-page .bili-comment-editor, body.bili-dynamic-page .bili-comment-editor-wrap { display: none !important; visibility: hidden !important; height: 0 !important; min-height: 0 !important; padding: 0 !important; margin: 0 !important; overflow: hidden !important; } /* 「评论 N」下面的那条分割线:恢复显示(v131.10) 不再清空 tabs 头部/导航的下边框与伪元素, 并显式补一条 1px 灰线,原生无边框时也能保证有线。 */ body.bili-dynamic-page .bili-tabs.dyn-tabs > .bili-tabs__header, body.bili-dynamic-page .bili-tabs.dyn-tabs .bili-tabs__header { border-top: 0 !important; border-left: 0 !important; border-right: 0 !important; border-bottom: 1px solid #e3e5e7 !important; box-shadow: none !important; background-image: none !important; } /* 若出现两条线(原生伪元素 + 上面补的边框), 把下面这段的 border-bottom 改回 none 即可 */ body.bili-dynamic-page .bili-tabs__nav, body.bili-dynamic-page .bili-tabs__nav__items, body.bili-dynamic-page .bili-tabs__nav__item { box-shadow: none !important; background-image: none !important; } /* 只隐藏「赞与转发」这一个 tab 项,保留「评论 N」—— 视频页评论区本来就有「评论 N」(shadow 内 #title),两边才一致。 探针:nav__items 中 nth-of-type(2) 为「评论 N」(.is-active), nth-of-type(3) 为「赞与转发」。 */ body.bili-dynamic-page .bili-tabs__nav__item:nth-of-type(3), body.bili-dynamic-page .bili-tabs__nav__items > .bili-tabs__nav__item:nth-of-type(3) { display: none !important; visibility: hidden !important; width: 0 !important; height: 0 !important; min-height: 0 !important; padding: 0 !important; margin: 0 !important; overflow: hidden !important; } /* 右侧悬浮工具栏(417 / 0 / 7 / 顶部):视频页没有,隐藏 */ body.bili-dynamic-page .sidebar-wrap, body.bili-dynamic-page .side-toolbar, body.bili-dynamic-page .side-toolbar__box, body.bili-dynamic-page .side-toolbar__bottom { display: none !important; visibility: hidden !important; width: 0 !important; height: 0 !important; min-height: 0 !important; padding: 0 !important; margin: 0 !important; overflow: hidden !important; } /* ============================================================ ===== 话题页(点标签/话题进来:/v/topic/detail/?topic_id=)===== 卡片 DOM 与动态页同源:.list__topic-card > .bili-dyn-item, 内部同样是 __avatar / __header / __body / a.bili-dyn-card-video, 所以版式照抄动态页: 白底圆角卡 + 头像左浮 48px + 封面拉全宽 16:9 + 正文居中 + 隐藏「关注 / 更多 / 热评 / 转发评论点赞 / 播放弹幕数」。 作用域全走 body:has(.topic-detail):纯 CSS,不新增 JS、不加页面 class。 ⚠ 踩过的坑一(v131.64 修复):本页列表是 B站 list-view 虚拟滚动, 首屏数据由底部哨兵 .list-view__shim 进视口触发加载。 上一版把 shim 给 display:none 了 → 永远不触发 → 一条都不显示 (实测 .topic-list 只剩 switch-tab 的 40px,flow-list 不在 DOM)。 所以:虚拟列表内部节点(shim / state / flow-list > div)一律不碰, 并显式保 shim 可见,防止被别处规则误伤。 ⚠ 踩过的坑二(v131.66 修复):「热门/最新」行的间距不是它自己给的。 上间距来自 .topic-detail__header 的 margin-bottom, 而中间夹了一张 .active-card(margin-bottom 16px)把它顶成 16px, 所以必须把活动卡隐藏,上间距才会回到 8px。 ⚠ 踩过的坑三(v131.65 修复):absolute 定位的 .bili-dyn-item__avatar 包含块是 .bili-dyn-item__main,不是 .bili-dyn-item。__main 已经是 item 的内容盒(padding 已算进去),所以只能 left/top = 0, 照抄动态页参数即可,不要再加 8/12 的内边距补偿。 ============================================================ */ body:has(.topic-detail) { padding: 8px 0 0 0 !important; background: #f4f5f7 !important; } /* 只收横向溢出,放在 .topic-detail 上;不动 html/body 的 overflow, 避免改变滚动容器让虚拟列表的滚动监听失效 */ body:has(.topic-detail) .topic-detail { overflow-x: hidden !important; background: #f4f5f7 !important; } /* ---- 1. 把 PC 定宽 632 / left:-140 的容器链拉回满宽 ---- 注意:不包含 .topic-list__flow-list 及其子级,避免误伤虚拟列表 */ body:has(.topic-detail) #app, body:has(.topic-detail) .topic-detail, body:has(.topic-detail) .topic-nav__main, body:has(.topic-detail) .topic-detail__header, body:has(.topic-detail) .topic-detail__content, body:has(.topic-detail) .topic-detail__header > .main-part, body:has(.topic-detail) .topic-detail__content > .main-part, body:has(.topic-detail) .topic-list, body:has(.topic-detail) .topic-list__flow-list, body:has(.topic-detail) .list__topic-card, body:has(.topic-detail) .bili-dyn-item, body:has(.topic-detail) .bili-dyn-item__main { width: 100% !important; max-width: 100% !important; min-width: 0 !important; margin-left: 0 !important; margin-right: 0 !important; padding-left: 0 !important; padding-right: 0 !important; box-sizing: border-box !important; float: none !important; } /* 整页左右各留 8px:与动态页 .bili-dyn-list__item 的 8px 边距一致 */ body:has(.topic-detail) .topic-detail { padding: 0 8px 8px 8px !important; box-sizing: border-box !important; } /* ---- 1b. flow-list 原生带 80px margin-top(PC 留白)。 不归零的话会与 switch-tab 的下间距 margin-collapse 成 80px ---- */ body:has(.topic-detail) .topic-list__flow-list { margin-top: 0 !important; margin-bottom: 0 !important; } /* ---- 1c. 保命:虚拟滚动的底部哨兵必须可见可布局 ---- */ body:has(.topic-detail) .list-view__shim, body:has(.topic-detail) .topic-list__flow-list > .list-view__shim { display: block !important; visibility: visible !important; width: 100% !important; min-height: 1px !important; height: auto !important; opacity: 0 !important; } /* ---- 2. 只隐藏纯装饰:顶部 PC 导航条(实测 0 高,含重复「参与话题」) 与分享弹层。发布面板 / list-view 内部节点一律不碰。 ---- */ body:has(.topic-detail) .topic-nav, body:has(.topic-detail) .share-popover, /* 活动运营卡(「崩坏星穹铁道4.6创作者激励计划 … 立即参与」): 实测 344x59、margin-bottom 16px,正是它把「热门/最新」行顶下去的元凶 */ body:has(.topic-detail) .active-card, body:has(.topic-detail) .active-content, body:has(.topic-detail) .active-button, /* 「参与话题 / 点赞 / 收藏 / 分享」整行:动态页没有,隐藏 */ body:has(.topic-detail) .interaction-container { display: none !important; visibility: hidden !important; width: 0 !important; height: 0 !important; min-height: 0 !important; padding: 0 !important; margin: 0 !important; overflow: hidden !important; } /* ---- 3. 话题头部(发起者 / 标题 / 简介 / 参与话题):白卡 + 居中 ---- */ body:has(.topic-detail) .topic-detail__header { height: auto !important; background: #ffffff !important; border: 1px solid #e3e5e7 !important; border-radius: 8px !important; margin: 0 0 8px 0 !important; padding: 12px !important; box-sizing: border-box !important; text-align: center !important; } /* 原生 main-part 带 28px margin-top(给被隐藏的 topic-nav 留位),归零 */ body:has(.topic-detail) .topic-detail__header > .main-part { margin-top: 0 !important; padding-top: 0 !important; } body:has(.topic-detail) .topic-detail__header * { text-align: center !important; } /* 头里那个 88x93 的大电视图标:PC 装饰,隐藏 */ body:has(.topic-detail) .topic-tv-icon { display: none !important; visibility: hidden !important; width: 0 !important; height: 0 !important; margin: 0 !important; padding: 0 !important; overflow: hidden !important; } body:has(.topic-detail) .launch-user, body:has(.topic-detail) .topic-title, body:has(.topic-detail) .topic-desc { width: 100% !important; max-width: 100% !important; margin-left: auto !important; margin-right: auto !important; justify-content: center !important; box-sizing: border-box !important; } body:has(.topic-detail) .topic-title h1 { font-size: 17px !important; line-height: 24px !important; } body:has(.topic-detail) .topic-desc__text, body:has(.topic-detail) .topic-desc { font-size: 13px !important; line-height: 20px !important; } /* ---- 4. 热门 / 最新 切换条:保留并居中(话题页排序靠它) ---- */ body:has(.topic-detail) .switch-tab { display: flex !important; align-items: center !important; justify-content: center !important; width: 100% !important; max-width: 100% !important; height: auto !important; min-height: 48px !important; gap: 24px !important; /* 实测:上方 header 自带 8px 下边距,这里再补 8px 下边距, 上下就都等于卡片之间的 8px 间距(.list__topic-card 的下留白)。 上一版把高度压成 40px,而里面的 tab 文字是 48px 高, 结果文字溢出 8px 直接压在下方卡片上。 */ margin: 0 0 8px 0 !important; padding: 0 !important; box-sizing: border-box !important; background: transparent !important; } /* 上间距 = header 的 margin-bottom 8px(下面这条), 下间距 = switch-tab 自己的 margin-bottom 8px, 两边都与卡片之间的 8px 一致。 ⚠ content 原生自带 margin-top 8px,会与 header 的 8px margin-collapse 成 8px(取大值),实测正常,显式写死防回归。 ⚠ topic-list 自身 margin 必须归零,否则会再叠一层。 */ body:has(.topic-detail) .topic-detail__header { margin-bottom: 8px !important; } body:has(.topic-detail) .topic-detail__content { margin-top: 8px !important; } body:has(.topic-detail) .topic-list { margin-top: 0 !important; margin-bottom: 0 !important; } body:has(.topic-detail) .switch-tab__tab { width: auto !important; height: auto !important; margin: 0 !important; padding: 0 !important; } /* 原生那条 56x2 的下划线指示器是绝对定位的,隐藏后改用选中色区分 */ body:has(.topic-detail) .switch-tab__line { display: none !important; visibility: hidden !important; width: 0 !important; height: 0 !important; } body:has(.topic-detail) .switch-tab__tab-text { font-size: 15px !important; color: #61666d !important; } body:has(.topic-detail) .switch-tab__tab-text.selected { color: #00aeec !important; font-weight: 600 !important; } /* ---- 5. 卡片:与动态页 .bili-dyn-item 同一张皮 ---- */ body:has(.topic-detail) .list__topic-card { padding: 0 0 8px 0 !important; margin: 0 !important; box-sizing: border-box !important; } body:has(.topic-detail) .bili-dyn-item { position: relative !important; display: block !important; background: #ffffff !important; border: 1px solid #e3e5e7 !important; border-radius: 8px !important; padding: 12px 8px 12px 8px !important; margin: 0 !important; overflow: hidden !important; box-sizing: border-box !important; float: none !important; } body:has(.topic-detail) .bili-dyn-item * { max-width: 100% !important; box-sizing: border-box !important; } body:has(.topic-detail) .bili-dyn-item img, body:has(.topic-detail) .bili-dyn-item video, body:has(.topic-detail) .bili-dyn-item picture { max-width: 100% !important; height: auto !important; } body:has(.topic-detail) .bili-dyn-item, body:has(.topic-detail) .bili-dyn-item * { text-align: center !important; } /* ---- 6. 头像左浮 + 头部让位 64px(与动态页同参数) ---- */ /* ⚠ 与动态页同参数。absolute 的包含块是 .bili-dyn-item__main, 而 __main 本身就是 item 的内容盒(左边 +9、上边 +13 的 padding 已经 算进去了),所以这里必须 left/top = 0。 上一版写成 8/12 等于把内边距又叠了一遍 → 头像整体下移 12px 压住正文。 实测(修复前):头像 top=293,用户名 top=279,差 14px; 动态页是头像 56 / 用户名 54,只差 2px。 */ body:has(.topic-detail) .bili-dyn-item__avatar { position: absolute !important; left: 0 !important; top: 0 !important; width: 56px !important; max-width: 56px !important; min-width: 0 !important; padding: 0 !important; margin: 0 !important; box-sizing: border-box !important; } body:has(.topic-detail) .bili-dyn-item__avatar .bili-dyn-avatar, body:has(.topic-detail) .bili-dyn-item__avatar .b-avatar, body:has(.topic-detail) .bili-dyn-item__avatar img { width: 48px !important; height: 48px !important; max-width: 100% !important; border-radius: 50% !important; } body:has(.topic-detail) .bili-dyn-item__header { width: auto !important; max-width: 100% !important; min-width: 0 !important; /* 8px:与动态页 header→body 的间隔一致。话题页原生这里是 0, 而头像在容器内偏下 19px、高 48px,底部会压住正文第一行。 */ margin: 0 0 8px 0 !important; padding-left: 64px !important; padding-right: 8px !important; box-sizing: border-box !important; } body:has(.topic-detail) .bili-dyn-item__body { width: 100% !important; max-width: 100% !important; margin: 0 !important; padding: 0 8px 0 8px !important; box-sizing: border-box !important; } /* ---- 7. 动态页没有的行:关注按钮 / 三点更多 / 热评 / 底部互动栏 / 播放弹幕数 ---- */ body:has(.topic-detail) .bili-dyn-item__following, body:has(.topic-detail) .bili-dyn-follow-btn, body:has(.topic-detail) .bili-dyn-item__more, body:has(.topic-detail) .bili-dyn-more, body:has(.topic-detail) .bili-dyn-more__btn, body:has(.topic-detail) .bili-dyn-item__interaction, body:has(.topic-detail) .bili-dyn-interaction, body:has(.topic-detail) .bili-dyn-item__footer, body:has(.topic-detail) .bili-dyn-item__action, body:has(.topic-detail) .bili-dyn-action, body:has(.topic-detail) .bili-dyn-card-video__stat { display: none !important; visibility: hidden !important; width: 0 !important; height: 0 !important; min-height: 0 !important; max-height: 0 !important; padding: 0 !important; margin: 0 !important; border: none !important; overflow: hidden !important; } /* ---- 8. 视频卡:PC 是「左封面 236 + 右文字 288」横排, 改成动态页那种「上封面(全宽 16:9)+ 下标题」竖排 ---- */ body:has(.topic-detail) .bili-dyn-content, body:has(.topic-detail) .bili-dyn-content__orig, body:has(.topic-detail) .bili-dyn-content__orig__major { width: 100% !important; max-width: 100% !important; min-width: 0 !important; box-sizing: border-box !important; } body:has(.topic-detail) .bili-dyn-card-video { display: flex !important; flex-direction: column !important; width: 100% !important; max-width: 100% !important; height: auto !important; padding: 0 !important; margin: 0 !important; box-sizing: border-box !important; } body:has(.topic-detail) .bili-dyn-card-video__header { width: 100% !important; max-width: 100% !important; height: auto !important; flex: 0 0 auto !important; } body:has(.topic-detail) .bili-dyn-card-video__cover { width: 100% !important; max-width: 100% !important; height: auto !important; aspect-ratio: 16 / 9 !important; box-sizing: border-box !important; } body:has(.topic-detail) .bili-dyn-card-video__cover .b-img, body:has(.topic-detail) .bili-dyn-card-video__cover .b-img__inner, body:has(.topic-detail) .bili-dyn-card-video__cover img, body:has(.topic-detail) .bili-dyn-card-video__cover picture { width: 100% !important; max-width: 100% !important; height: auto !important; aspect-ratio: 16 / 9 !important; object-fit: cover !important; display: block !important; } body:has(.topic-detail) .bili-dyn-card-video__body { width: 100% !important; max-width: 100% !important; height: auto !important; flex: 1 1 auto !important; padding: 8px 0 0 0 !important; border: none !important; border-width: 0 !important; border-style: none !important; box-shadow: none !important; outline: none !important; } /* 封面右侧那条半开口边框(原生可能是 ::before/::after 画的竖条)一并清掉 */ body:has(.topic-detail) .bili-dyn-card-video__body::before, body:has(.topic-detail) .bili-dyn-card-video__body::after, body:has(.topic-detail) .bili-dyn-card-video__desc::before, body:has(.topic-detail) .bili-dyn-card-video__desc::after { content: none !important; display: none !important; border: none !important; background: none !important; box-shadow: none !important; } body:has(.topic-detail) .bili-dyn-card-video__title { font-size: 14px !important; line-height: 20px !important; } body:has(.topic-detail) .bili-dyn-card-video__desc { font-size: 12px !important; line-height: 18px !important; color: #9499a0 !important; } /* 封面/图册居中 */ body:has(.topic-detail) .bili-dyn-content__orig__major .b-img, body:has(.topic-detail) .bili-dyn-content__orig__major picture { margin-left: auto !important; margin-right: auto !important; } /* ============================================================ opus 详情页(www.bilibili.com/opus/xxx)评论区:同样对齐视频页 实测链路:opus-detail 344 -> .bili-tabs.opus-tabs 328 -> .bili-tabs__content 312 -> .comment-wrap 296 -> .bili-comment-container 280 -> bili-comments 264 每层各吃 16px,层层嵌套后只剩 264,比视频页的 328 窄了 64。 目标:344 - 8(容器) - 8(容器) = 328,与视频页 bili-comments 完全一致。 做法:中间各层水平内边距归零,只由 .bili-comment-container 提供 8px, bili-comments 满宽且自身不留白。 (下面选择器比既有 opus 规则更具体,确保覆盖生效) ============================================================ */ body.bili-opus-page .bili-tabs.opus-tabs, body.bili-opus-page .bili-tabs.opus-tabs > .bili-tabs__content, body.bili-opus-page .bili-tabs.opus-tabs > .bili-tabs__content > .bili-tab-pane, body.bili-opus-page .bili-tabs.opus-tabs .comment-wrap { width: 100% !important; max-width: 100% !important; min-width: 0 !important; padding-left: 0 !important; padding-right: 0 !important; margin-left: 0 !important; margin-right: 0 !important; box-sizing: border-box !important; float: none !important; position: static !important; } body.bili-opus-page .bili-tabs.opus-tabs .comment-wrap > .bili-comment-container { width: 100% !important; max-width: 100% !important; min-width: 0 !important; padding-left: 8px !important; padding-right: 8px !important; margin-left: 0 !important; margin-right: 0 !important; box-sizing: border-box !important; } body.bili-opus-page .bili-comment-container bili-comments, body.bili-opus-page .comment-wrap bili-comments { display: block !important; width: 100% !important; max-width: 100% !important; min-width: 0 !important; padding-left: 0 !important; padding-right: 0 !important; box-sizing: border-box !important; } /* 与视频页一致:外部输入框/编辑器容器隐藏(shadow 内由 patch 处理) */ body.bili-opus-page .bili-comment-box, body.bili-opus-page .bili-comment-input-wrap, body.bili-opus-page .comment-send-box, body.bili-opus-page .bili-comment-editor, body.bili-opus-page .bili-comment-editor-wrap { display: none !important; visibility: hidden !important; height: 0 !important; min-height: 0 !important; padding: 0 !important; margin: 0 !important; overflow: hidden !important; } /* 只隐藏「赞与转发」tab,保留「评论 177」 */ body.bili-opus-page .bili-tabs__nav__item:nth-of-type(3), body.bili-opus-page .bili-tabs__nav__items > .bili-tabs__nav__item:nth-of-type(3) { display: none !important; visibility: hidden !important; width: 0 !important; height: 0 !important; min-height: 0 !important; padding: 0 !important; margin: 0 !important; overflow: hidden !important; } /* 右侧悬浮工具栏(417 / 2 / 0 / 8 / 177 / 顶部) */ body.bili-opus-page .sidebar-wrap, body.bili-opus-page .side-toolbar, body.bili-opus-page .side-toolbar__box, body.bili-opus-page .side-toolbar__bottom { display: none !important; visibility: hidden !important; width: 0 !important; height: 0 !important; min-height: 0 !important; padding: 0 !important; margin: 0 !important; overflow: hidden !important; } /* ===== opus 详情页 ===== */ body.bili-opus-page { background: #f4f5f7 !important; overflow-x: hidden !important; padding-top: 8px !important; } body.bili-opus-page .opus-module-content, body.bili-opus-page .opus-module-content p, body.bili-opus-page .opus-module-content span, body.bili-opus-page .opus-module-title { text-align: center !important; } body.bili-opus-page .opus-para-pic, body.bili-opus-page .bili-album, body.bili-opus-page .bili-album__preview.grid2, body.bili-opus-page .opus-para-link-card, body.bili-opus-page .bili-dyn-card-goods, body.bili-opus-page .bili-dyn-card-goods__wrap, body.bili-opus-page .bili-dyn-card-goods__one { margin-left: auto !important; margin-right: auto !important; text-align: center !important; } body.bili-opus-page #bili-header-container, body.bili-opus-page .bili-header, body.bili-opus-page .bili-header--mini, body.bili-opus-page .bili-header--fixed, body.bili-opus-page .bili-header__bar, body.bili-opus-page .bili-header__menu, body.bili-opus-page .international-header, body.bili-opus-page .mini-header { display: none !important; visibility: hidden !important; height: 0 !important; overflow: hidden !important; } body.bili-opus-page .bgc, body.bili-opus-page .bg { display: none !important; } body.bili-opus-page .right-sidebar-wrap, body.bili-opus-page .side-toolbar, body.bili-opus-page .go-top, body.bili-opus-page [class*="back-top"], body.bili-opus-page [class*="to-top"] { display: none !important; visibility: hidden !important; } body.bili-opus-page #app, body.bili-opus-page #opus-detail-app, body.bili-opus-page .opus-detail, body.bili-opus-page .bili-opus-view, body.bili-opus-page .opus-module-top, body.bili-opus-page .opus-module-title, body.bili-opus-page .opus-module-author, body.bili-opus-page .opus-module-content, body.bili-opus-page .opus-module-copyright, body.bili-opus-page .opus-module-bottom, body.bili-opus-page .bili-tabs.opus-tabs, body.bili-opus-page .bili-tabs__header, body.bili-opus-page .bili-tabs__content, body.bili-opus-page .comment-wrap, body.bili-opus-page .bili-comment-container { width: 100% !important; max-width: 100% !important; min-width: 0 !important; padding-left: 8px !important; padding-right: 8px !important; margin-left: 0 !important; margin-right: 0 !important; box-sizing: border-box !important; float: none !important; position: static !important; left: auto !important; right: auto !important; } body.bili-opus-page img, body.bili-opus-page video, body.bili-opus-page picture, body.bili-opus-page .b-img, body.bili-opus-page .b-img__inner { max-width: 100% !important; height: auto !important; display: block !important; } body.bili-opus-page .opus-module-top__album__cover, body.bili-opus-page .opus-module-top__display, body.bili-opus-page .opus-module-top__album { width: 100% !important; max-width: 100% !important; height: auto !important; box-sizing: border-box !important; } /* ===== opus 详情页:隐藏三处模块 ===== 实测:.opus-module-top [312x187](标题上方的封面图) .opus-module-copyright [312x54](cv53172768) .opus-module-bottom [312x96](分享至 / 投诉或建议) 注意:上面已有的宽度规则里包含了这三个选择器,但只设了宽高/内边距, 这里单独用 display:none 隐藏;选择器更具体,优先级覆盖无冲突。 */ body.bili-opus-page .bili-opus-view > .opus-module-top, body.bili-opus-page .opus-detail .opus-module-top, body.bili-opus-page .opus-module-top { display: none !important; visibility: hidden !important; width: 0 !important; height: 0 !important; min-height: 0 !important; max-height: 0 !important; padding: 0 !important; margin: 0 !important; border: none !important; overflow: hidden !important; } body.bili-opus-page .bili-opus-view > .opus-module-copyright, body.bili-opus-page .opus-detail .opus-module-copyright, body.bili-opus-page .opus-module-copyright { display: none !important; visibility: hidden !important; width: 0 !important; height: 0 !important; min-height: 0 !important; max-height: 0 !important; padding: 0 !important; margin: 0 !important; border: none !important; overflow: hidden !important; } body.bili-opus-page .bili-opus-view > .opus-module-bottom, body.bili-opus-page .opus-detail .opus-module-bottom, body.bili-opus-page .opus-module-bottom, body.bili-opus-page .opus-module-bottom__share, body.bili-opus-page .opus-module-bottom__share__list { display: none !important; visibility: hidden !important; width: 0 !important; height: 0 !important; min-height: 0 !important; max-height: 0 !important; padding: 0 !important; margin: 0 !important; border: none !important; overflow: hidden !important; } /* ===== opus 详情页:UP 主行右侧竖排「⋯」更多按钮 ===== 探针 09-29_11-17-15 实测(视口 360): .opus-module-author[312x90] left=24 pt=12 pb=12 > .__left[66x66] left=32 (头像 66 + 挂件) > .__center[88x62] left=98 (昵称 / 发布时间) > .__right[142x48] left=186 > .opus-module-author__more[24x24] **left=304** ← 目标 > .opus-more > .opus-more__container.opus-more__btn > svg[24x24] > .opus-module-author__decorate[110x33] left=186(装扮卡片,保留) 竖排三个点就是 .opus-module-author__more —— 整块 24x24, 点开是举报/关注之类的浮层,手机端这一列本来就挤(昵称只有 72 宽), 收掉它还能让 .__right 少占 24px。 只隐藏 __more,**不动 __decorate**(装扮卡片是 UP 主的展示信息)。 ------------------------------------------------------------ */ body.bili-opus-page .opus-module-author__more, body.bili-opus-page .opus-module-author__more > .opus-more, body.bili-opus-page .opus-module-author__more .opus-more__container, body.bili-opus-page .opus-module-author__more .opus-more__btn, body.bili-opus-page .opus-module-author__right > .opus-more { display: none !important; visibility: hidden !important; width: 0 !important; height: 0 !important; min-width: 0 !important; min-height: 0 !important; max-height: 0 !important; padding: 0 !important; margin: 0 !important; border: none !important; overflow: hidden !important; } /* 高特异性兜底(v131.36 套路):完整链路压过去 */ body.bili-opus-page .bili-opus-view > .opus-module-author > .opus-module-author__right > .opus-module-author__more { display: none !important; width: 0 !important; height: 0 !important; padding: 0 !important; margin: 0 !important; overflow: hidden !important; } body.bili-opus-page .opus-para-pic, body.bili-opus-page .opus-pic-view, body.bili-opus-page .bili-dyn-pic, body.bili-opus-page .bili-dyn-pic__img { width: 100% !important; max-width: 100% !important; height: auto !important; margin-left: auto !important; margin-right: auto !important; box-sizing: border-box !important; } body.bili-opus-page * { max-width: 100% !important; box-sizing: border-box !important; } /* ============================================================ v131.28 长按头像弹出的「UP 主信息卡片」固定在屏幕内显示 探针实测(三份都已抓到,挂在 body 直下): 空间搜索页 body > div.bili-user-profile:nth-of-type(5) [360x261] 空间动态页 body > div.bili-user-profile:nth-of-type(5) [360x261] 动态详情页 body > div.bili-user-profile:nth-of-type(10) [360x266] 卡片本身已经是满宽 360,问题出在定位:站内 JS 按 PC 布局算出的 left/top(或 transform)把它推到了视口之外。探针只记录尺寸不记录坐标, 无法确定是被横向推出还是纵向推出,所以这里采用"强制钉在视口内"的 做法,两种情形一并覆盖: · position: fixed —— 相对视口定位,不再受文档坐标影响 · left/right 双写 0 + width 100% —— 横向必定铺满视口 · top: auto + bottom: 0 —— 纵向必定贴底(手机上的 bottom-sheet) · transform: none —— 压掉站内用 translate 做的偏移 !important 的作者样式优先级高于站内写在 style 属性里的普通声明。 注意:不写 display / visibility,显示与隐藏仍交给站内 JS 控制。 ============================================================ */ body .bili-user-profile { position: fixed !important; left: 0 !important; right: 0 !important; /* v131.29:改为距屏幕顶部 36px(原来是贴底 bottom:0) */ top: 36px !important; bottom: auto !important; width: 100% !important; max-width: 100% !important; min-width: 0 !important; height: auto !important; max-height: 90vh !important; margin: 0 !important; padding: 0 !important; box-sizing: border-box !important; transform: none !important; translate: none !important; scale: none !important; overflow-x: hidden !important; overflow-y: auto !important; -webkit-overflow-scrolling: touch !important; border-radius: 12px 12px 0 0 !important; box-shadow: 0 -2px 12px rgba(0,0,0,0.12) !important; z-index: 2147483647 !important; } /* 内部两层:满宽 + 裁掉溢出(背景图原生 366 宽,比视口宽 6px) */ body .bili-user-profile__content, body .bili-user-profile-view, body .bili-user-profile-view__background, body .bili-user-profile-view__info { width: 100% !important; max-width: 100% !important; min-width: 0 !important; margin: 0 !important; box-sizing: border-box !important; overflow: hidden !important; transform: none !important; } /* v131.29 隐藏「发消息」按键(保留「关注/已关注」)。 只写 display:none:footer 是 flex,移除后关注按钮会自动铺满,不留空隙。 */ body .bili-user-profile-view__info__button.chat { display: none !important; visibility: hidden !important; width: 0 !important; min-width: 0 !important; height: 0 !important; padding: 0 !important; margin: 0 !important; border: none !important; overflow: hidden !important; } /* ============================================================ ========== UP 主空间页 ========== ============================================================ */ html:has(body.bili-space-page), body.bili-space-page { width: 100% !important; max-width: 100% !important; min-width: 0 !important; /* v131.33:hidden 会让 body 变成滚动容器,导致内部 sticky 全部失效 (胶囊栏吸不住、一滚就钻到搜索框底下 -> 间距看起来是 0)。 clip 同样能裁掉横向溢出,但不会创建滚动容器,sticky 正常工作。 两条都写:老浏览器吃 hidden,新版吃 clip。 */ overflow-x: hidden !important; overflow-x: clip !important; margin: 0 !important; padding: 0 !important; background: #f1f2f3 !important; } /* v131.37 顶部 52px 占位改为「唯一来源」。 原写法只给 body 加 padding-top: 52px,一旦它被站内样式或其它规则 覆盖,整个空间页内容就会顶到 y=0: 胶囊栏(pill) 8..42 完全落进固定搜索栏 0..52 里 -> 胶囊栏看不见 第一行卡片顶 50,被搜索栏压掉 2px -> 顶部裁剪显示不全 正好对应你反馈的两个现象。 改法:body 的 padding 归零,改由 #app 提供这 52px。 两者效果等价(都是把 #app 内容整体下移 52),但来源唯一、 不再依赖 body 那条容易被盖掉的规则。 放在 #app 上也同时保证 nav-bar(投稿页)初始位置就是 52, 与它自己的 sticky top:52 一致,不会先被搜索栏盖住再跳下来。 */ body.bili-space-page { padding-top: 0 !important; } body.bili-space-page > #app, body.bili-space-page > div#app { padding-top: 52px !important; box-sizing: border-box !important; /* v131.39 真凶(探针 14-15-15 实证):#app 带站内原生的 margin-top: -64px,而且它与 body 的 margin 发生了外边距合并, 把 body 本身也顶到了 top=-64: html top=0 / body top=-64 / #app top=-64 (pt=52 mt=-64) → main top=-12 → 胶囊栏 top=-4 → 卡片顶 38 于是胶囊栏 8..50 整体落进固定搜索栏 0..52 里被完全盖住, 第一行卡片顶 38 也被切掉 —— 正好是你看到的两个现象。 这个 -64 原本是站内给 PC 头部留的负补偿,脚本已隐藏 PC 头部, 它就必须归零。 */ margin-top: 0 !important; } /* 顺带断掉 body 与 #app 的外边距合并,避免再被负边距带偏 */ body.bili-space-page > #app::before { content: '' !important; display: block !important; height: 0 !important; overflow: hidden !important; } /* v131.38 加固:.space-theme-bg 是站内绝对定位的背景层(360x800), 脚本从未处理过它。若它层级高于普通流内容,就会把 main 顶部 (含胶囊栏)整块盖住 —— 表现就是"胶囊栏凭空消失"。 这里把它压到最底层并禁用命中,彻底排除遮挡可能。 */ body.bili-space-page .space-theme-bg, body.bili-space-page #app > .space-theme-bg { position: absolute !important; top: 0 !important; left: 0 !important; z-index: 0 !important; pointer-events: none !important; } /* main 与胶囊栏显式抬到背景层之上 */ body.bili-space-page #app > main.space-main { position: relative !important; z-index: 2 !important; } body.bili-space-page .search-sidebar, body.bili-space-page .upload-sidenav { z-index: 3 !important; } body.bili-space-page .bili-header, body.bili-space-page .international-header, body.bili-space-page .mini-header, body.bili-space-page #biliMainHeader, body.bili-space-page #bili-header-container, body.bili-space-page .bili-header--mini, body.bili-space-page .bili-header--fixed, body.bili-space-page .bili-header__bar, body.bili-space-page .bili-header__menu, body.bili-space-page .footer, body.bili-space-page .bili-footer, body.bili-space-page .international-footer, body.bili-space-page .mini-footer, body.bili-space-page .space-footer, body.bili-space-page .go-top, body.bili-space-page .bili-go-top, body.bili-space-page [class*="back-top"], body.bili-space-page [class*="goto-top"], body.bili-space-page [class*="to-top"], body.bili-space-page .fixed-sidebar, body.bili-space-page .bili-fixed-sidebar, body.bili-space-page .side-toolbar, body.bili-space-page .right-sidebar-wrap, body.bili-space-page .space-float { display: none !important; visibility: hidden !important; height: 0 !important; overflow: hidden !important; } body.bili-space-page .toutu.header-toutu { display: none !important; visibility: hidden !important; height: 0 !important; min-height: 0 !important; max-height: 0 !important; padding: 0 !important; margin: 0 !important; overflow: hidden !important; } body.bili-space-page .header.space-header { width: 100% !important; max-width: 100% !important; min-width: 0 !important; height: auto !important; min-height: 0 !important; max-height: none !important; padding: 0 !important; margin: 0 !important; box-sizing: border-box !important; overflow: hidden !important; } body.bili-space-page .upinfo-detail__top .level, body.bili-space-page .upinfo-detail__top a.level, body.bili-space-page .upinfo-detail__top .vip, body.bili-space-page .upinfo-detail__top .img-label, body.bili-space-page .upinfo-detail__bottom, body.bili-space-page .upinfo-sign, body.bili-space-page .upinfo-sign__text, body.bili-space-page .interactions > a.message-btn, body.bili-space-page .interactions > .more-actions, body.bili-space-page .interactions > .menu-popover.message, body.bili-space-page .interactions > .v-popover-wrap.message-entry { display: none !important; visibility: hidden !important; } body.bili-space-page .nav-search.nav-bar-search, body.bili-space-page label.nav-search, body.bili-space-page input.nav-search-input, body.bili-space-page .nav-bar__main-right, body.bili-space-page .nav-statistics { display: none !important; visibility: hidden !important; } /* v131.26 导航条高度 64 → 52,与顶部自建搜索栏 #my-bili-searchbar 等高。 实测:#my-bili-searchbar 360x52;.nav-bar.space-navbar 360x64 (内部 .nav-bar__main / .nav-tab / a.nav-tab__item 都是 64,被 flex 拉伸)。 只压外层 + 内层容器的 height,icon(20x21) 与文字本身没变, 所以视觉上只是上下留白收紧 12px(各 6px),图标文字不受影响。 */ body.bili-space-page .nav-bar.space-navbar { width: 100% !important; max-width: 100% !important; min-width: 0 !important; height: 52px !important; max-height: 52px !important; overflow: hidden !important; box-sizing: border-box !important; margin-left: 0 !important; margin-right: 0 !important; margin-top: 0 !important; margin-bottom: 0 !important; padding: 0 8px !important; /* v131.33:吸顶位置定死在自建搜索栏正下方(搜索栏高 52), 否则站内 PC 的 top 值会让它在手机上错位、把胶囊栏顶到搜索框底下。 */ position: sticky !important; top: 52px !important; z-index: 1000 !important; background: #ffffff !important; } /* ------------------------------------------------------------ v131.25 UP主空间页→搜索页:隐藏「主页 动态 投稿 合集和系列」这一行 结构:#app > div.nav-bar.space-navbar[360x64](main 的前置兄弟节点) #app > main.space-main.route_search CSS 没有"选前面的兄弟"的选择器,所以用 :has() 从父级反查: #app:has(> main.route_search) > .nav-bar.space-navbar nav-bar 原生是 sticky,这里只写 display:none(不动 position), 收掉后它不再占位,下方内容自然顶上来,不留 64px 空隙。 ------------------------------------------------------------ */ body.bili-space-page #app:has(> main.space-main.route_search) > .nav-bar.space-navbar, body.bili-space-page #app:has(> main.space-main.route_search) > .header.space-header ~ .nav-bar.space-navbar, body.bili-space-page:has(main.space-main.route_search) .nav-bar.space-navbar { display: none !important; visibility: hidden !important; width: 0 !important; max-width: 0 !important; height: 0 !important; min-height: 0 !important; max-height: 0 !important; padding: 0 !important; margin: 0 !important; border: none !important; overflow: hidden !important; } /* v131.36 UP主空间页→搜索页:隐藏 .header.space-header。 探针里它是 360x56(原为头像+昵称+关注),但脚本早已把内部内容 (头像/昵称/等级/签名/按钮等)逐个隐藏,只剩一个 56px 的空壳 —— 用户 截图确认"这一部分就是不存在"。 它的存在把胶囊栏整体推高了 56px: 搜索框底 52 → 空壳 52..108 → 胶囊栏 108..158 于是无论把间距放在胶囊栏的 padding 还是 margin 上, 白色胶囊 pill 的位置都是 116,肉眼看起来始终"紧贴搜索框"。 收掉空壳后:搜索框底 52 → 胶囊栏 60..110 → pill 顶 60,间距正好 8。 v131.40 这行改为「全部 UP主空间页都隐藏」(原先只对搜索页生效)。 原因是 v131.39 修掉了 #app 的 margin-top:-64px 之后,这行才第一次 真正露出来 —— 之前它被那 -64 顶到 top=-12..44,几乎整块压在固定 搜索栏(0..52)底下,所以你一直"看不到它"(v131.36 时你说得没错)。 现在归位到 52..108 就完整显示了,而里面的头像 .space-avatar 是 68x68、top=35,会往上戳进搜索栏区域被切掉一截 —— 正是你看到的 "被搜索栏遮挡了一部分"。 用户要求:这一行整体隐藏。于是直接收掉,不做显示。 */ body.bili-space-page .header.space-header, body.bili-space-page #app > .header.space-header, body.bili-space-page #app:has(> main.space-main.route_search) > .header.space-header, body.bili-space-page:has(main.space-main.route_search) .header.space-header { display: none !important; visibility: hidden !important; width: 0 !important; max-width: 0 !important; height: 0 !important; min-height: 0 !important; max-height: 0 !important; padding: 0 !important; margin: 0 !important; border: none !important; overflow: hidden !important; } body.bili-space-page .nav-bar__main { display: flex !important; align-items: center !important; justify-content: center !important; flex-wrap: nowrap !important; gap: 0 !important; width: 100% !important; max-width: 100% !important; min-width: 0 !important; height: 52px !important; max-height: 52px !important; margin: 0 !important; padding: 0 !important; box-sizing: border-box !important; } /* .nav-tab / .nav-bar__main-left / 各 tab 项同压到 52(v131.26) */ body.bili-space-page .nav-bar__main-left, body.bili-space-page .nav-tab { height: 52px !important; max-height: 52px !important; margin: 0 !important; padding: 0 !important; box-sizing: border-box !important; } /* v131.27 按键组占满一整行,且「按键间距 = 左右距屏幕边缘」 实测(09-04-40 探针):.nav-bar__main[344] > .nav-bar__main-left[274] > .nav-tab[274] ← 只到 274,右侧空 70 原因是 main-left 为 flex:0 1 auto / width:auto、nav-tab 也是 width:auto, 两者都只按内容宽度收缩,于是整组按键缩在中间。 改法:main-left 与 nav-tab 全部撑满 100%,tab 项改 flex:1 1 auto 均分余量。 算下来:内容区 344(nav-bar 左右各 8)− gap 8×3 = 24 − 按键自然宽 (52+52+52+94=250) = 70,4 个按键各增 17.5 → 69.5/69.5/69.5/111.5, 合计 320 + 24 = 344 正好满行;左右各留 8、按键间距 8,三者相等。 */ body.bili-space-page .nav-tab > a.nav-tab__item { height: 52px !important; max-height: 52px !important; min-height: 0 !important; margin: 0 !important; padding: 0 !important; box-sizing: border-box !important; display: flex !important; align-items: center !important; justify-content: center !important; flex: 1 1 auto !important; width: auto !important; min-width: 0 !important; max-width: none !important; } body.bili-space-page .nav-bar__main-left { display: flex !important; align-items: center !important; justify-content: center !important; flex: 1 1 auto !important; width: 100% !important; max-width: 100% !important; min-width: 0 !important; box-sizing: border-box !important; overflow: visible !important; } body.bili-space-page .nav-tab { display: flex !important; align-items: center !important; justify-content: flex-start !important; gap: 8px !important; white-space: nowrap !important; width: 100% !important; max-width: 100% !important; min-width: 0 !important; box-sizing: border-box !important; } body.bili-space-page .radio-filter { display: none !important; visibility: hidden !important; width: 0 !important; height: 0 !important; overflow: hidden !important; padding: 0 !important; margin: 0 !important; } body.bili-space-page button.playall-btn, body.bili-space-page .vui_button.playall-btn, body.bili-space-page .action-btn.playall-btn, body.bili-space-page [class*="playall"] { display: none !important; visibility: hidden !important; width: 0 !important; height: 0 !important; overflow: hidden !important; padding: 0 !important; margin: 0 !important; } body.bili-space-page #app, body.bili-space-page main.space-main, body.bili-space-page .space-home { width: 100% !important; max-width: 100% !important; min-width: 0 !important; padding-left: 0 !important; padding-right: 0 !important; margin-left: 0 !important; margin-right: 0 !important; box-sizing: border-box !important; display: block !important; } body.bili-space-page .space-home > .aside, body.bili-space-page .space-home > aside.aside, body.bili-space-page main.space-main .aside { display: none !important; visibility: hidden !important; width: 0 !important; max-width: 0 !important; min-width: 0 !important; height: 0 !important; padding: 0 !important; margin: 0 !important; overflow: hidden !important; flex: 0 0 0 !important; position: absolute !important; left: -9999px !important; } body.bili-space-page .space-home > .content { display: block !important; width: 100% !important; max-width: 100% !important; min-width: 0 !important; flex: 1 1 100% !important; /* v131.41:底部 padding 16 -> 0(原为给页脚留的,页脚已隐藏) */ padding: 0 8px 0 8px !important; margin: 0 !important; box-sizing: border-box !important; } /* ------------------------------------------------------------ v131.45 首页「视频 ·N 查看更多」标题行:上间距改为与下间距一致 探针(14-37-19)实测坐标: 上一区块(代表作)bottom = -6624 .section-wrap__header top = -6600 ← 上间距 = 24 .section-wrap__header bottom = -6566 .section-wrap__content top = -6550 ← 下间距 = 16(卡片顶) 即:上 24 / 下 16,不一致。 上间距 24 来自区块之间的 margin-bottom(24); 下间距 16 来自 header 与 content 之间的原生留白。 改法:给整个 video-section 区块加 margin-top: -8px, 把整块上提 8px(header 与 content 的相对位置不变,仍是 16), 于是上间距 24-8 = 16 = 下间距 16,两边一致。 用 :has() 定位而不写 nth-of-type,区块顺序变了也不会错位。 ------------------------------------------------------------ */ body.bili-space-page .route_home .home-section:has(> .section-wrap.video-section) { margin-top: -8px !important; } /* ------------------------------------------------------------ v131.41 首页滑到最底部:去掉那条没用的分割线及其下方的空白 探针(14-37-19,已滚到底)实测: 最后一张专栏卡 bottom = 735 最后一个 section-wrap bottom = 760 ← 分割线在这一带 .content bottom = 800 ← 文档底 即分割线下方还有 40px 空白,构成为: 最后一个 home-section 的 margin-bottom 24(区块间距,底部不需要) + .content 的 padding-bottom 16(页脚占位,页脚已隐藏) 用户要求:分割线去掉、分割线下方的高度去掉、分割线上方的高度保留。 故这里只清「分割线本身 + 下方 40px」, section-wrap 内部那 25px(分割线上方)原样保留。 ------------------------------------------------------------ */ body.bili-space-page .route_home .home-section:last-of-type, body.bili-space-page .route_home .content > .home-section:last-child { margin-bottom: 0 !important; border-bottom: none !important; } body.bili-space-page .route_home .home-section:last-of-type .section-wrap, body.bili-space-page .route_home .content > .home-section:last-child .section-wrap { margin-bottom: 0 !important; border-bottom: none !important; box-shadow: none !important; } /* 分割线本身:清掉最后一个区块的伪元素与背景线 */ body.bili-space-page .route_home .home-section:last-of-type .section-wrap::after, body.bili-space-page .route_home .home-section:last-of-type .section-wrap::before, body.bili-space-page .route_home .content > .home-section:last-child .section-wrap::after, body.bili-space-page .route_home .content > .home-section:last-child .section-wrap::before { content: none !important; display: none !important; border: none !important; background: none !important; box-shadow: none !important; } /* .content / .space-home 底部若还挂着一条线,一并清掉 */ body.bili-space-page .route_home .content, body.bili-space-page .route_home .space-home { border-bottom: none !important; box-shadow: none !important; background-image: none !important; } body.bili-space-page .route_home .content::after, body.bili-space-page .route_home .space-home::after, body.bili-space-page .route_home .content::before, body.bili-space-page .route_home .space-home::before { content: none !important; display: none !important; border: none !important; background: none !important; box-shadow: none !important; } body.bili-space-page img, body.bili-space-page video, body.bili-space-page picture { max-width: 100% !important; height: auto !important; } body.bili-space-page .masterpiece-block, body.bili-space-page .items, body.bili-space-page .video-list__content, body.bili-space-page .article-list { display: grid !important; grid-template-columns: repeat(2, minmax(0, 1fr)) !important; grid-gap: 8px !important; gap: 8px !important; row-gap: 8px !important; column-gap: 8px !important; padding: 0 !important; margin: 0 !important; width: 100% !important; max-width: 100% !important; box-sizing: border-box !important; list-style: none !important; align-items: start !important; align-content: start !important; background: transparent !important; height: auto !important; min-height: 0 !important; max-height: none !important; overflow: visible !important; grid-auto-rows: auto !important; } body.bili-space-page .items > .items__item, body.bili-space-page .masterpiece-block > .masterpiece-block__item, body.bili-space-page .video-list__content > .video-list__item, body.bili-space-page .article-list > .article-list__item { display: contents !important; } /* ------------------------------------------------------------ 主页「合集·xxx / 系列·xxx」区块:标题行与视频卡片之间固定 20px 上面把 .video-list__content 的 margin/padding 全部归零, 刚进主页时站内那条原生顶部间距还没补上,文字就会紧贴卡片; 点一次「合集和系列」再切回来,站内样式补上了才恢复正常。 这里把间距统一交给 content 的 margin-top, 并清掉 header 的下边距与容器的 gap,避免两处叠加成双倍。 实测:修复前 .video-list 高 589(34+531+24), 正常态 609(多出的 20 就是这条间距)。 ------------------------------------------------------------ */ body.bili-space-page .route_home .lists-section .video-list { display: block !important; gap: 0 !important; row-gap: 0 !important; column-gap: 0 !important; padding-top: 0 !important; padding-bottom: 0 !important; } body.bili-space-page .route_home .lists-section .video-list__header { margin-top: 0 !important; margin-bottom: 0 !important; padding-bottom: 0 !important; } body.bili-space-page .route_home .lists-section .video-list__content { margin-top: 20px !important; padding-top: 0 !important; } /* ------------------------------------------------------------ v131.20 UP主空间内搜索页(route_search,空间右上角搜索进来的结果页) 原结构:.space-search[360] 是 flex-row > .search-sidebar[150 宽,纵向侧栏] > .side-nav > .side-nav__item[150x52] > .search-content[736(PC 定宽)] > .video > .video-body > .video-list.grid-mode[736] > .upload-video-card[364x282] 改法:sidebar 从左侧纵向栏改成顶部横向胶囊(同投稿页 .upload-sidenav / 动态页 .space-dynamic__left),content 满宽后卡片自然回到 168x172。 ------------------------------------------------------------ */ body.bili-space-page .space-search { display: flex !important; flex-direction: column !important; align-items: stretch !important; width: 100% !important; max-width: 100% !important; min-width: 0 !important; padding: 0 !important; margin: 0 !important; box-sizing: border-box !important; gap: 0 !important; } /* 「视频 328 / 动态 357」移到「主页 动态 投稿 合集和系列」下方,横向胶囊 */ body.bili-space-page .search-sidebar { order: 1 !important; display: block !important; width: 100% !important; max-width: 100% !important; min-width: 0 !important; height: auto !important; max-height: none !important; /* v131.35:同投稿页,间距改用容器外 margin-top 8, padding-top 归零。搜索页紧贴胶囊栏上方的是 .header.space-header (头像+昵称+已关注,56px),它底边 108 → 容器顶 116 → 胶囊顶 116, 容器间距与视觉间距都是 8。 */ padding: 0 8px 8px 8px !important; margin: 8px 0 0 0 !important; box-sizing: border-box !important; /* v131.34:不吸顶,随页面滚走,不遮挡最上面的卡片 v131.37:改用 relative 并给低层级—— relative 不改变文档流位置(仍随页面滚动), 但能确保它参与正常的层叠顺序,不会被背景层压住。 */ position: relative !important; top: auto !important; left: auto !important; right: auto !important; bottom: auto !important; z-index: 1 !important; flex: 0 0 auto !important; overflow: visible !important; background: #f1f2f3 !important; } body.bili-space-page .search-sidebar .side-nav { display: flex !important; flex-direction: row !important; justify-content: center !important; align-items: center !important; gap: 8px !important; width: 100% !important; max-width: 100% !important; padding: 0 !important; margin: 0 auto !important; box-sizing: border-box !important; flex-wrap: wrap !important; position: static !important; } body.bili-space-page .search-sidebar .side-nav__item { display: flex !important; flex-direction: row !important; align-items: center !important; justify-content: center !important; flex: 0 0 auto !important; width: auto !important; min-width: 64px !important; max-width: 100% !important; height: 34px !important; padding: 0 16px !important; margin: 0 !important; box-sizing: border-box !important; border-radius: 17px !important; background: #ffffff !important; color: #18191c !important; font-size: 13px !important; white-space: nowrap !important; position: static !important; } body.bili-space-page .search-sidebar .side-nav__item.active { background: #00aeec !important; color: #ffffff !important; } body.bili-space-page .search-sidebar .side-nav__item__main, body.bili-space-page .search-sidebar .side-nav__item__sub { display: flex !important; flex-direction: row !important; align-items: center !important; justify-content: center !important; gap: 4px !important; width: auto !important; height: auto !important; padding: 0 !important; margin: 0 !important; background: transparent !important; } body.bili-space-page .search-sidebar .side-nav__item__main-text { color: inherit !important; font-size: 13px !important; font-weight: 500 !important; line-height: 34px !important; } body.bili-space-page .search-sidebar .side-nav__item__sub-text { color: inherit !important; font-size: 13px !important; font-weight: 400 !important; line-height: 34px !important; opacity: 0.8 !important; } body.bili-space-page .search-content { order: 2 !important; display: block !important; width: 100% !important; max-width: 100% !important; min-width: 0 !important; flex: 1 1 100% !important; padding: 0 8px 16px 8px !important; margin: 0 !important; box-sizing: border-box !important; overflow: visible !important; position: static !important; } /* 视频结果:容器满宽 + 两列网格,卡片回到 168x172(同投稿页) */ body.bili-space-page .space-search .video, body.bili-space-page .space-search .video-header, body.bili-space-page .space-search .video-header__top, body.bili-space-page .space-search .video-header .title, body.bili-space-page .space-search .video-header .sub-title, body.bili-space-page .space-search .video-body { width: 100% !important; max-width: 100% !important; min-width: 0 !important; padding-left: 0 !important; padding-right: 0 !important; margin-left: 0 !important; margin-right: 0 !important; box-sizing: border-box !important; } /* v131.33 搜索页:整行移除「共找到关于"宝可梦"的 N 个视频 / 条动态」 (v131.31/32 只收了 .title,sub-title 保留;这版连 header 整块收掉) 实测:.video-header[344x20] / .dynamic-header[344x70]。 收掉后胶囊与卡片之间只剩 sidenav 自带的 padding-bottom 8 → 正好 8px。 */ body.bili-space-page .space-search .video-header, body.bili-space-page .space-search .video-header__top, body.bili-space-page .space-search .video-header .title, body.bili-space-page .space-search .video-header .sub-title, body.bili-space-page .space-search .dynamic-header, body.bili-space-page .space-search .dynamic-header__top, body.bili-space-page .space-search .dynamic-header .title, body.bili-space-page .space-search .dynamic-header .sub-title { display: none !important; visibility: hidden !important; width: 0 !important; height: 0 !important; min-height: 0 !important; max-height: 0 !important; padding: 0 !important; margin: 0 !important; border: none !important; overflow: hidden !important; } /* 胶囊底 → 卡片顶 = sidenav padding-bottom 8 + 0 = 8 */ body.bili-space-page .space-search .video-body, body.bili-space-page .space-search .dynamic-content { width: 100% !important; max-width: 100% !important; min-width: 0 !important; margin-top: 0 !important; margin-bottom: 0 !important; margin-left: 0 !important; margin-right: 0 !important; padding: 0 !important; box-sizing: border-box !important; } body.bili-space-page .space-search .video-list, body.bili-space-page .space-search .video-list.grid-mode, body.bili-space-page .space-search .video-list.hide-stat { display: grid !important; grid-template-columns: repeat(2, minmax(0, 1fr)) !important; grid-gap: 8px !important; gap: 8px !important; row-gap: 8px !important; column-gap: 8px !important; align-items: start !important; align-content: start !important; width: 100% !important; max-width: 100% !important; min-width: 0 !important; height: auto !important; min-height: 0 !important; max-height: none !important; padding: 0 !important; margin: 0 !important; box-sizing: border-box !important; overflow: visible !important; } body.bili-space-page .space-search .upload-video-card, body.bili-space-page .space-search .upload-video-card.grid-mode, body.bili-space-page .space-search .upload-video-card__left, body.bili-space-page .space-search .upload-video-card__main { width: 100% !important; max-width: 100% !important; min-width: 0 !important; margin: 0 !important; padding: 0 !important; box-sizing: border-box !important; } /* 动态结果:与动态页一致(.search-content 已有 8px 边距, 这里把 item 的左右内边距归零,避免叠加成 16px) v131.21 修正:搜索页动态用的是 .dynamic-list(不是动态页的 .bili-dyn-list), 而且是 PC 定宽 720(.dynamic-list[720] > .dynamic-list__item[720x670]), 在 360 屏上直接溢出。这里把整条链压回 100%。 */ body.bili-space-page .space-search .dynamic, body.bili-space-page .space-search .dynamic-header, body.bili-space-page .space-search .dynamic-content, body.bili-space-page .space-search .dynamic-list, body.bili-space-page .space-search .dynamic-list__item, body.bili-space-page .space-search .bili-dyn-list, body.bili-space-page .space-search .bili-dyn-list__items, body.bili-space-page .space-search .bili-dyn-item, body.bili-space-page .space-search .bili-dyn-item__main { width: 100% !important; max-width: 100% !important; min-width: 0 !important; box-sizing: border-box !important; } body.bili-space-page .space-search .dynamic-list__item, body.bili-space-page .space-search .bili-dyn-list__item { width: 100% !important; max-width: 100% !important; min-width: 0 !important; padding: 0 0 8px 0 !important; margin: 0 !important; box-sizing: border-box !important; } /* 720 定宽带来的横向滚动也要掐掉,否则 360 屏会被撑开 */ body.bili-space-page .space-search .dynamic-content, body.bili-space-page .space-search .dynamic-list { display: block !important; overflow-x: hidden !important; padding-left: 0 !important; padding-right: 0 !important; margin-left: 0 !important; margin-right: 0 !important; } body.bili-space-page .space-search .dynamic-list__item .bili-dyn-item, body.bili-space-page .space-search .dynamic-list__item .bili-dyn-item__main, body.bili-space-page .space-search .dynamic-list__item .bili-dyn-item__header, body.bili-space-page .space-search .dynamic-list__item .bili-dyn-item__body, body.bili-space-page .space-search .dynamic-list__item .bili-dyn-item__footer { width: 100% !important; max-width: 100% !important; min-width: 0 !important; box-sizing: border-box !important; margin-left: 0 !important; margin-right: 0 !important; } /* ------------------------------------------------------------ v131.23 底部分页器(投稿→视频 / 空间搜索→视频)对齐主搜索页 两者对比(都在第 1 页): 主搜索页 .vui_pagenation[360x50] > .vui_pagenation--btns[360x34] 上一页 61x34 | 数字 32x34 | 下一页 61x34 | 无跳转区 空间页 .vui_pagenation--jump.video-pagination[736x34] ← PC 定宽溢出 > .vui_pagenation--btns[478x34] 数字 34x34 | 下一页 100x34 > .vui_pagenation-go[214x34] 「共 16 页 / 618 个,跳至 __ 页」 改法:容器压回 100% 并居中,按钮套用主搜索页同一组尺寸, 跳转区整块隐藏(.vui_pagenation-go)。 v131.24 补:上下间距对齐主搜索页。 主搜索页实测:外层 .flex_center.mt_x50.mb_x50[360x50], 脚本 870 行已把它的 margin 上下压成 8px;分页器 padding 8 0 + btns 34 = 50。 父容器 div[360x3854] = 列表 3788 + 50 + 8 + 8,正好相等 → 父容器没有额外的 padding-bottom。 所以主搜索页的视觉间距是:卡片底 → 8+8 = 16 → 按钮 → 8+8 = 16 → 容器底。 空间页:.video-footer 原生 154 高(= 分页器 34 + 上下各 60), 且父容器 .upload-content / .search-content 自带 padding-bottom 16 (实测 .upload-content[360x3758] − .video[344x3742] = 16)。 若不抵消,底部会变成 8 + 8 + 16 = 24,比主搜索页多 8px。 故 .video-footer 取 margin: 8px 0 -8px(下边 -8 抵消父容器多出的 8), 分页器保持 padding: 8px 0 → 上下视觉间距各 16px,与主搜索页一致。 ------------------------------------------------------------ */ /* 外层:上 8 / 下 -8(抵消父容器底部 padding 多出的 8) */ body.bili-space-page .video-footer { display: flex !important; flex-direction: row !important; justify-content: center !important; align-items: center !important; width: 100% !important; max-width: 100% !important; min-width: 0 !important; height: auto !important; min-height: 0 !important; padding: 0 !important; margin: 8px 0 -8px 0 !important; box-sizing: border-box !important; overflow: visible !important; background: transparent !important; } /* v131.49 「合集和系列」页底部分页器:上下间距与「投稿→视频」页完全一致 两份探针同批实测(09-28_17-45-47 = 投稿→视频,09-28_17-45-34 = 合集和系列): 投稿→视频(基准,已达标) .video-body bottom=3736 ← 最后一张卡片底 .video-footer top=3744 h=50 pt=0 pb=0 mt=8 mb=-8 .video-pagination pt=8 pb=8 .vui_pagenation--btns 3752 → 3786 .upload-content pb=16 → main bottom=3802 ⇒ 卡片底→按钮顶 = 3752-3736 = 16 ⇒ 按钮底→页面底 = 3802-3786 = 16 合集和系列(改前) .lists-content bottom=11891 ← 最后一张卡片底 .lists-footer top=11891 h=110 **pt=60** pb=0 mt=0 mb=0 .audio-list-paginaion pt=8 pb=8(已被上面 .vui_pagenation 通配规则压好) .vui_pagenation--btns 11959 → 11993 .space-lists pb=16 → main bottom=12017 ⇒ 卡片底→按钮顶 = 11959-11891 = 68(多 52,全来自 pt=60) ⇒ 按钮底→页面底 = 12017-11993 = 24(多 8,因为没有 mb=-8 抵消) 两页的分页器本体、父容器 padding-bottom 16 都已经相同, 差异 100% 出在 footer 这一层。所以直接照抄 .video-footer 那组已验证过的参数(padding 0 + margin 8px 0 -8px): 上 = mt 8 + pagination pt 8 = 16 ✓ 下 = pagination pb 8 + mb(-8) + space-lists pb 16 = 16 ✓ ------------------------------------------------------------ */ body.bili-space-page .lists-footer { display: flex !important; flex-direction: row !important; justify-content: center !important; align-items: center !important; width: 100% !important; max-width: 100% !important; min-width: 0 !important; height: auto !important; min-height: 0 !important; max-height: none !important; padding: 0 !important; margin: 8px 0 -8px 0 !important; box-sizing: border-box !important; overflow: visible !important; background: transparent !important; } /* 高特异性兜底(v131.36 套路),防站内晚加载的同权重 !important */ body.bili-space-page main.space-main.route_listsIndex > .space-lists > .lists-footer { padding: 0 !important; margin: 8px 0 -8px 0 !important; } /* 分页器本体:与主搜索页同款 padding 8px 0 */ body.bili-space-page .vui_pagenation, body.bili-space-page .vui_pagenation--jump, body.bili-space-page .vui_pagenation--jump.video-pagination { display: flex !important; flex-direction: row !important; justify-content: center !important; align-items: center !important; width: 100% !important; max-width: 100% !important; min-width: 0 !important; height: auto !important; min-height: 0 !important; padding: 8px 0 !important; margin: 0 !important; box-sizing: border-box !important; overflow: visible !important; background: transparent !important; } /* 「共 N 页 / N 个,跳至 __ 页」整块隐藏 */ body.bili-space-page .vui_pagenation-go, body.bili-space-page .vui_pagenation--jump .vui_pagenation-go, body.bili-space-page .vui_pagenation .vui_input { display: none !important; visibility: hidden !important; width: 0 !important; height: 0 !important; min-width: 0 !important; min-height: 0 !important; max-height: 0 !important; padding: 0 !important; margin: 0 !important; border: none !important; overflow: hidden !important; } /* 按钮行:与主搜索页同款(全宽、gap 4、可横向滚动、隐藏滚动条) */ body.bili-space-page .vui_pagenation--btns { display: flex !important; flex-direction: row !important; flex-wrap: nowrap !important; justify-content: flex-start !important; align-items: center !important; width: 100% !important; max-width: 100% !important; min-width: 0 !important; padding: 0 8px !important; margin: 0 !important; box-sizing: border-box !important; gap: 4px !important; overflow-x: auto !important; overflow-y: hidden !important; -webkit-overflow-scrolling: touch !important; scrollbar-width: none !important; -ms-overflow-style: none !important; } body.bili-space-page .vui_pagenation--btns::-webkit-scrollbar { display: none !important; width: 0 !important; height: 0 !important; } /* 单个按钮:数字 32x34、字号 13、圆角 4,与主搜索页一致 */ body.bili-space-page .vui_pagenation--btn { display: inline-flex !important; align-items: center !important; justify-content: center !important; flex-shrink: 0 !important; flex-grow: 0 !important; width: auto !important; min-width: 32px !important; height: 34px !important; line-height: 34px !important; padding: 0 6px !important; margin: 0 !important; box-sizing: border-box !important; white-space: nowrap !important; font-size: 13px !important; text-align: center !important; border-radius: 4px !important; } /* 上一页 / 下一页:空间页原生 100x34,压回主搜索页的 61 宽 */ body.bili-space-page .vui_pagenation--btn-side { min-width: 44px !important; padding: 0 10px !important; font-size: 13px !important; } body.bili-space-page .space-dynamic { display: flex !important; flex-direction: column !important; align-items: stretch !important; width: 100% !important; max-width: 100% !important; min-width: 0 !important; padding: 0 !important; margin: 0 !important; box-sizing: border-box !important; gap: 0 !important; } body.bili-space-page .space-dynamic__left { order: 1 !important; display: block !important; width: 100% !important; max-width: 100% !important; min-width: 0 !important; height: auto !important; max-height: none !important; padding: 8px !important; margin: 0 !important; box-sizing: border-box !important; position: static !important; top: auto !important; left: auto !important; bottom: auto !important; right: auto !important; background: #f1f2f3 !important; flex: 0 0 auto !important; overflow: visible !important; } body.bili-space-page .space-dynamic__left .side-nav { display: flex !important; flex-direction: row !important; justify-content: center !important; align-items: center !important; gap: 8px !important; width: 100% !important; max-width: 100% !important; padding: 0 !important; margin: 0 auto !important; box-sizing: border-box !important; flex-wrap: wrap !important; position: static !important; } body.bili-space-page .space-dynamic__left .side-nav__item { display: flex !important; align-items: center !important; justify-content: center !important; flex: 0 0 auto !important; width: auto !important; min-width: 64px !important; max-width: 100% !important; height: 34px !important; padding: 0 16px !important; margin: 0 !important; box-sizing: border-box !important; border-radius: 17px !important; background: #ffffff !important; color: #18191c !important; font-size: 13px !important; cursor: pointer !important; user-select: none !important; white-space: nowrap !important; position: static !important; } body.bili-space-page .space-dynamic__left .side-nav__item.active { background: #00aeec !important; color: #ffffff !important; } body.bili-space-page .space-dynamic__left .side-nav__item__main { display: flex !important; align-items: center !important; justify-content: center !important; gap: 4px !important; width: auto !important; height: auto !important; padding: 0 !important; margin: 0 !important; background: transparent !important; } body.bili-space-page .space-dynamic__left .side-nav__item__main-text { color: inherit !important; font-size: 13px !important; font-weight: 500 !important; line-height: 34px !important; } body.bili-space-page .space-dynamic__content { order: 2 !important; display: block !important; width: 100% !important; max-width: 100% !important; min-width: 0 !important; flex: 1 1 100% !important; padding: 0 !important; margin: 0 !important; box-sizing: border-box !important; overflow: visible !important; } body.bili-space-page .space-dynamic__right { display: none !important; visibility: hidden !important; width: 0 !important; max-width: 0 !important; height: 0 !important; padding: 0 !important; margin: 0 !important; overflow: hidden !important; flex: 0 0 0 !important; position: absolute !important; left: -9999px !important; } body.bili-space-page .space-dynamic-inner, body.bili-space-page .space-dynamic-inner > .content, body.bili-space-page .bili-dyn-list, body.bili-space-page .bili-dyn-list__items { width: 100% !important; max-width: 100% !important; min-width: 0 !important; padding: 0 !important; margin: 0 !important; box-sizing: border-box !important; } body.bili-space-page .bili-dyn-list__item { padding: 0 8px 8px 8px !important; margin: 0 !important; box-sizing: border-box !important; width: 100% !important; max-width: 100% !important; min-width: 0 !important; float: none !important; } body.bili-space-page .bili-dyn-item { position: relative !important; background: #ffffff !important; border: 1px solid #e3e5e7 !important; border-radius: 8px !important; padding: 12px 8px 0 8px !important; margin: 0 !important; box-sizing: border-box !important; overflow: hidden !important; width: 100% !important; max-width: 100% !important; min-width: 0 !important; display: block !important; float: none !important; } body.bili-space-page .bili-dyn-item * { max-width: 100% !important; box-sizing: border-box !important; } body.bili-space-page .bili-dyn-item img, body.bili-space-page .bili-dyn-item video, body.bili-space-page .bili-dyn-item picture { max-width: 100% !important; height: auto !important; } body.bili-space-page .bili-dyn-item__main { position: relative !important; padding-left: 0 !important; padding-right: 0 !important; box-sizing: border-box !important; width: 100% !important; max-width: 100% !important; min-width: 0 !important; float: none !important; } body.bili-space-page .bili-dyn-item__avatar { position: absolute !important; left: 0 !important; top: 0 !important; width: 56px !important; max-width: 56px !important; min-width: 0 !important; padding: 0 !important; margin: 0 !important; box-sizing: border-box !important; } body.bili-space-page .bili-dyn-item__avatar .bili-dyn-avatar, body.bili-space-page .bili-dyn-item__avatar .b-avatar, body.bili-space-page .bili-dyn-item__avatar img { width: 48px !important; height: 48px !important; max-width: 100% !important; border-radius: 50% !important; } body.bili-space-page .bili-dyn-item__header { margin-left: 0 !important; margin-right: 0 !important; padding-left: 64px !important; padding-right: 8px !important; width: auto !important; max-width: 100% !important; min-width: 0 !important; box-sizing: border-box !important; } body.bili-space-page .bili-dyn-item__more, body.bili-space-page .bili-dyn-more, body.bili-space-page .bili-dyn-more__btn, body.bili-space-page .bili-dyn-more__cascader { display: none !important; visibility: hidden !important; } body.bili-space-page .bili-dyn-content, body.bili-space-page .bili-dyn-content__orig, body.bili-space-page .bili-dyn-content__orig__major { width: 100% !important; max-width: 100% !important; min-width: 0 !important; box-sizing: border-box !important; } body.bili-space-page .bili-dyn-card-video { display: flex !important; flex-direction: column !important; width: 100% !important; max-width: 100% !important; min-width: 0 !important; height: auto !important; box-sizing: border-box !important; } body.bili-space-page .bili-dyn-card-video__header { width: 100% !important; max-width: 100% !important; height: auto !important; flex: 0 0 auto !important; box-sizing: border-box !important; } body.bili-space-page .bili-dyn-card-video__cover { width: 100% !important; max-width: 100% !important; height: auto !important; aspect-ratio: 16 / 9 !important; box-sizing: border-box !important; } body.bili-space-page .bili-dyn-card-video__cover .b-img, body.bili-space-page .bili-dyn-card-video__cover .b-img__inner, body.bili-space-page .bili-dyn-card-video__cover img, body.bili-space-page .bili-dyn-card-video__cover picture { width: 100% !important; max-width: 100% !important; height: auto !important; aspect-ratio: 16 / 9 !important; object-fit: cover !important; display: block !important; } body.bili-space-page .bili-dyn-card-video__body { width: 100% !important; max-width: 100% !important; height: auto !important; flex: 1 1 auto !important; padding: 8px 0 0 0 !important; box-sizing: border-box !important; } /* 投稿了视频:隐藏视频封面下方「框住标题/简介文字」的那条左侧半开口边框 */ body.bili-space-page .bili-dyn-card-video__body, body.bili-space-page .bili-dyn-card-video__title, body.bili-space-page .bili-dyn-card-video__desc { border: none !important; border-top: none !important; border-right: none !important; border-bottom: none !important; border-left: none !important; border-width: 0 !important; border-style: none !important; box-shadow: none !important; outline: none !important; } /* 该边框也可能是 ::before / ::after 画的竖条,一并清掉 */ body.bili-space-page .bili-dyn-card-video__body::before, body.bili-space-page .bili-dyn-card-video__body::after, body.bili-space-page .bili-dyn-card-video__desc::before, body.bili-space-page .bili-dyn-card-video__desc::after { content: none !important; display: none !important; border: none !important; background: none !important; box-shadow: none !important; } body.bili-space-page .bili-dyn-card-video__title, body.bili-space-page .bili-dyn-card-video__desc, body.bili-space-page .bili-dyn-card-video__title .bili-ellipsis, body.bili-space-page .bili-dyn-card-video__desc .bili-ellipsis { text-align: center !important; } body.bili-space-page .bili-dyn-card-video__stat, body.bili-space-page .bili-dyn-card-video__stat__item, body.bili-space-page .bili-dyn-card-video__stat__item.danmaku { display: none !important; visibility: hidden !important; height: 0 !important; overflow: hidden !important; margin: 0 !important; padding: 0 !important; } body.bili-space-page .bili-dyn-item, body.bili-space-page .bili-dyn-item * { text-align: center !important; } /* 正文容器:只做内边距约束,绝不能隐藏(正文 .bili-dyn-content 就在它里面) */ body.bili-space-page .bili-dyn-item__body { margin-left: 0 !important; margin-right: 0 !important; padding-left: 8px !important; padding-right: 8px !important; width: 100% !important; max-width: 100% !important; box-sizing: border-box !important; } /* 去掉卡片内的「转发 / 评论 / 点赞」数量行(整行隐藏,与动态一致) */ body.bili-space-page .bili-dyn-item__footer, body.bili-space-page .bili-dyn-item__action, body.bili-space-page .bili-dyn-action, body.bili-space-page .bili-dyn-action.forward, body.bili-space-page .bili-dyn-action.comment, body.bili-space-page .bili-dyn-action.like { display: none !important; visibility: hidden !important; height: 0 !important; min-height: 0 !important; max-height: 0 !important; padding: 0 !important; margin: 0 !important; border: none !important; overflow: hidden !important; } /* 隐藏该行后,卡片底部补回一点留白,避免内容紧贴卡片下边缘 */ body.bili-space-page .bili-dyn-item { padding-bottom: 12px !important; } body.bili-space-page .bili-dyn-content__orig__major img, body.bili-space-page .bili-dyn-content__orig__major picture, body.bili-space-page .bili-dyn-content__orig__major .b-img { margin-left: auto !important; margin-right: auto !important; display: block !important; } body.bili-space-page .bili-dyn-content__orig__major [class*="grid"], body.bili-space-page .bili-dyn-content__orig__major [class*="pics"], body.bili-space-page .bili-dyn-content__orig__major [class*="gallery"], body.bili-space-page .bili-dyn-content__orig__major [class*="goods"], body.bili-space-page .bili-dyn-content__orig__major [class*="commodity"], body.bili-space-page .bili-dyn-content__orig__major [class*="card"] { margin-left: auto !important; margin-right: auto !important; justify-content: center !important; } body.bili-space-page .bili-dyn-item__action { flex: 1 1 0 !important; width: auto !important; max-width: none !important; min-width: 0 !important; box-sizing: border-box !important; display: flex !important; align-items: center !important; justify-content: center !important; } body.bili-space-page .bili-dyn-action { display: flex !important; align-items: center !important; justify-content: center !important; width: 100% !important; gap: 4px !important; } body.bili-space-page .space-upload { display: flex !important; flex-direction: column !important; align-items: stretch !important; width: 100% !important; max-width: 100% !important; min-width: 0 !important; padding: 0 !important; margin: 0 !important; box-sizing: border-box !important; gap: 0 !important; } body.bili-space-page .upload-sidenav { order: 1 !important; display: block !important; width: 100% !important; max-width: 100% !important; min-width: 0 !important; height: auto !important; max-height: none !important; /* v131.35:间距必须在容器「外面」用 margin,不能靠内部 padding-top。 按内部 padding 算的话,容器顶 160 紧贴 nav-bar 底 160,容器间距是 0。 padding-top 归零 + margin-top 8 后:容器顶 168、胶囊顶 168, 容器间距与视觉间距都是 8。 */ padding: 0 8px 8px 8px !important; margin: 0 !important; box-sizing: border-box !important; position: static !important; flex: 0 0 auto !important; overflow: visible !important; background: #f1f2f3 !important; /* v131.34:按用户选择改回不吸顶,随页面一起滚走。 吸顶虽能保证间距,但会把最上面的卡片遮住一部分; 改为 static 后卡片完整显示,胶囊距导航条 8px(自身 padding-top)。 */ position: static !important; top: auto !important; z-index: auto !important; } body.bili-space-page .upload-sidenav .side-nav { display: flex !important; flex-direction: row !important; justify-content: center !important; align-items: center !important; gap: 8px !important; width: 100% !important; max-width: 100% !important; padding: 0 !important; margin: 0 auto !important; box-sizing: border-box !important; flex-wrap: wrap !important; position: static !important; } body.bili-space-page .upload-sidenav .side-nav__item { display: flex !important; align-items: center !important; justify-content: center !important; flex: 0 0 auto !important; width: auto !important; min-width: 64px !important; max-width: 100% !important; height: 34px !important; padding: 0 16px !important; margin: 0 !important; box-sizing: border-box !important; border-radius: 17px !important; background: #ffffff !important; color: #18191c !important; font-size: 13px !important; cursor: pointer !important; user-select: none !important; white-space: nowrap !important; position: static !important; } body.bili-space-page .upload-sidenav .side-nav__item.active { background: #00aeec !important; color: #ffffff !important; } body.bili-space-page .upload-sidenav .side-nav__item__main { display: flex !important; align-items: center !important; justify-content: center !important; gap: 4px !important; width: auto !important; height: auto !important; padding: 0 !important; margin: 0 !important; background: transparent !important; } body.bili-space-page .upload-sidenav .side-nav__item__main-text { color: inherit !important; font-size: 13px !important; font-weight: 500 !important; line-height: 34px !important; } body.bili-space-page .upload-content { order: 2 !important; display: block !important; width: 100% !important; max-width: 100% !important; min-width: 0 !important; flex: 1 1 100% !important; padding: 0 8px 16px 8px !important; margin: 0 !important; box-sizing: border-box !important; overflow: visible !important; position: static !important; } /* ------------------------------------------------------------ v131.30 投稿页:移除「TA的视频」,并让筛选胶囊与卡片等距 实测(11-01-27 探针): .upload-sidenav[360x50] = padding 8 + 胶囊 34 + padding 8 .upload-content[360x3742] → .video[344x3734] > .video-header[344x64](.video-header__top > .title「TA的视频」) > .video-body[344x3582](卡片网格) > .video-footer(分页器) 1) 隐藏「TA的视频」:直接收掉整个 .video-header(64 高), 只隐藏 .title 会留下 64px 空白,间距仍然对不上。 2) 间距对齐分页器:v131.24 已把分页器按钮距底定为 16px (pagenation padding-bottom 8 + video-footer margin -8 + upload-content padding-bottom 16)。 胶囊底 → 卡片顶要同样为 16px: sidenav 自带 padding-bottom 8 + .video-body margin-top 8 = 16 ------------------------------------------------------------ */ body.bili-space-page .upload-content .video-header, body.bili-space-page .upload-content .video-header__top, body.bili-space-page .upload-content .video-header .title, body.bili-space-page .upload-content .video-header .sub-title { display: none !important; visibility: hidden !important; width: 0 !important; height: 0 !important; min-height: 0 !important; max-height: 0 !important; padding: 0 !important; margin: 0 !important; border: none !important; overflow: hidden !important; } body.bili-space-page .upload-content .video-body { width: 100% !important; max-width: 100% !important; min-width: 0 !important; /* v131.31:胶囊底 → 卡片顶 = sidenav padding-bottom 8 + 0 = 8 (与卡片间距一致。v131.30 的 8px 会让总间距变成 16) */ margin-top: 0 !important; margin-bottom: 0 !important; margin-left: 0 !important; margin-right: 0 !important; padding: 0 !important; box-sizing: border-box !important; } /* v131.35:nav-bar 底 → 胶囊栏容器顶 = 8(容器外 margin)。 注意这条在后面,会覆盖前面的 margin: 0,必须写成 8。 */ body.bili-space-page .upload-sidenav { margin-top: 8px !important; margin-bottom: 0 !important; padding-top: 0 !important; } /* v131.36 兜底:用「父 > 子:nth-of-type(1)」把特异性提到最高, 确保 margin-top 8 / padding-top 0 不被任何同名规则盖回去。 */ body.bili-space-page .space-upload > div.upload-sidenav:nth-of-type(1) { margin-top: 8px !important; margin-bottom: 0 !important; padding-top: 0 !important; } body.bili-space-page .space-search > div.search-sidebar:nth-of-type(1) { margin-top: 8px !important; margin-bottom: 0 !important; padding-top: 0 !important; } body.bili-space-page .lists-view-mode, body.bili-space-page .video-mode-switcher, body.bili-space-page .lists-view-mode__action { display: none !important; visibility: hidden !important; } body.bili-space-page .upload-content .video-list, body.bili-space-page .upload-content .video-list.grid-mode, body.bili-space-page .upload-content .video-list.hide-stat, body.bili-space-page .video-list.grid-mode, body.bili-space-page .video-list.hide-stat { display: grid !important; grid-template-columns: repeat(2, minmax(0, 1fr)) !important; grid-gap: 8px !important; gap: 8px !important; row-gap: 8px !important; column-gap: 8px !important; padding: 0 !important; margin: 0 !important; width: 100% !important; max-width: 100% !important; box-sizing: border-box !important; list-style: none !important; align-items: start !important; align-content: start !important; background: transparent !important; height: auto !important; min-height: 0 !important; max-height: none !important; overflow: visible !important; grid-auto-rows: auto !important; } /* ------------------------------------------------------------ v131.16 「合集和系列」整页(route_listsIndex)左右边距对齐主页 结构:main.space-main.route_listsIndex > .space-lists[360 满屏,无内边距] > .lists-header[360] + .lists-content[360] > .contet-list[360] > .video-list[360] > .video-list__content[360,已是两列网格 gap8] 这一页此前没有命中任何边距规则,卡片 176 宽直接顶到屏幕边缘; 主页 .space-home > .content 是 padding: 0 8px 16px 8px, 这里给 .space-lists 同一组值,内容宽回到 344、卡片 168,与主页一致。 v131.17 修正:只补左右边距,不要动 position / padding-top。 .lists-header 是 sticky 定位(自带 top 偏移躲开吸顶的 navbar), 上一版给它写了 position: static,粘性失效后它就直接跑到 「主页 动态 投稿 合集和系列」那一排按键底下被压住了。 同理 padding-top 也不能清零。 ------------------------------------------------------------ */ body.bili-space-page .space-lists { display: block !important; width: 100% !important; max-width: 100% !important; min-width: 0 !important; padding-left: 8px !important; padding-right: 8px !important; padding-bottom: 16px !important; margin-left: 0 !important; margin-right: 0 !important; box-sizing: border-box !important; float: none !important; overflow: visible !important; } body.bili-space-page .space-lists .lists-content, body.bili-space-page .space-lists .contet-list, body.bili-space-page .space-lists .video-list { width: 100% !important; max-width: 100% !important; min-width: 0 !important; padding-left: 0 !important; padding-right: 0 !important; margin-left: 0 !important; margin-right: 0 !important; box-sizing: border-box !important; float: none !important; } /* 标题行同样只补左右,保留它自己的 sticky / top 偏移 */ body.bili-space-page .space-lists .lists-header { width: 100% !important; max-width: 100% !important; min-width: 0 !important; padding-left: 0 !important; padding-right: 0 !important; padding-bottom: 16px !important; margin-left: 0 !important; margin-right: 0 !important; box-sizing: border-box !important; float: none !important; } /* v131.49 去掉「合集和系列」这一行大标题。 探针 09-28_17-45-34 实测: main.route_listsIndex top=134(.space-lists mt=30) > .space-lists > .lists-header[344x50] top=134 bottom=184 pt=0 pb=16 > .title[120x34] top=134 bottom=168 text=合集和系列 > .lists-content[344x11707] top=184 .lists-header 里**只有 .title 一个子节点**,没有别的控件, 所以整块 display:none 即可,不需要单独去清 .title (.title 是站内通用类名,单独选中反而容易误伤别的页面)。 隐藏后 .lists-content 直接顶到 main 的 134, 与 navbar 底部(104)之间保留 .space-lists 自带的 mt=30。 上面 v131.17 那条「不要动 .lists-header 的 position / padding-top」 的告诫在这里不适用了——整块都不显示了,sticky 也就无从谈起。 */ body.bili-space-page .space-lists > .lists-header { display: none !important; } body.bili-space-page main.space-main.route_listsIndex > .space-lists > .lists-header { display: none !important; } body.bili-space-page .space-lists .lists-header .title { display: none !important; } /* 标题行与卡片之间,沿用主页「合集·/系列·」的 20px */ body.bili-space-page .space-lists .video-list__content { margin-top: 20px !important; } /* ------------------------------------------------------------ v131.18 合集详情页(route_listDetails,点进某个「合集·xxx」后) 结构:main.space-main.route_listDetails > .space-list-details[360] > .list-header[360x110](.title + .subtitle) > .list-content[360x170] > .list-video-item[59x110,桌面版一排放 5 个] 问题:整页无边距、卡片被压成 59 宽(封面只剩 33 高)。 改法:外层补 8px 左右边距(同主页 .space-home > .content), .list-content 改两列网格,卡片回到 168x172(封面 95 + 信息区 77)。 注意:.list-header 同样是 sticky,这里不写 position / padding-top。 ------------------------------------------------------------ */ body.bili-space-page .space-list-details { display: block !important; width: 100% !important; max-width: 100% !important; min-width: 0 !important; padding-left: 8px !important; padding-right: 8px !important; padding-bottom: 16px !important; margin-left: 0 !important; margin-right: 0 !important; box-sizing: border-box !important; float: none !important; overflow: visible !important; } body.bili-space-page .space-list-details .list-header { width: 100% !important; max-width: 100% !important; min-width: 0 !important; padding-left: 0 !important; padding-right: 0 !important; margin-left: 0 !important; margin-right: 0 !important; box-sizing: border-box !important; float: none !important; } /* 标题「合集·xxx」与卡片之间 20px,和主页一致 */ body.bili-space-page .space-list-details .list-header .subtitle, body.bili-space-page .space-list-details .list-header .meta { width: 100% !important; max-width: 100% !important; min-width: 0 !important; margin-bottom: 20px !important; box-sizing: border-box !important; } /* v131.50 合集详情页:「合集  6个视频 9月14日更新」整行居中 探针 09-28_18-03-48 实测(route_listDetails): .list-header[344x144] top=134 bottom=278 mb=22 > .title[344x68] (.back[20x20] + .name[316x68])mb=20 > .subtitle[344x20] top=222 **pos=relative** mb=20 > .meta[344x20] mb=20 > .stats[344x20] text=合集  6个视频 9月14日更新 三层盒子都已经是满宽 344,文字靠左只是因为默认 text-align。 所以这里**不改 display**(.subtitle 是 relative、.meta/.stats 可能是 flex,贸然改成 block 会把站内的行内排布打散), 只同时给两条居中通路: text-align:center -> 命中普通块级 / 行内文本 justify-content:center -> 命中 flex 容器 两条互不干扰,谁生效取决于站内实际用的是哪种布局。 */ body.bili-space-page .space-list-details .list-header .subtitle, body.bili-space-page .space-list-details .list-header .subtitle .meta, body.bili-space-page .space-list-details .list-header .subtitle .meta .stats, body.bili-space-page .space-list-details .list-header .meta, body.bili-space-page .space-list-details .list-header .stats { text-align: center !important; justify-content: center !important; } /* 高特异性兜底(v131.36 套路) */ body.bili-space-page main.space-main.route_listDetails > .space-list-details > .list-header > .subtitle > .meta > .stats { text-align: center !important; justify-content: center !important; } /* v131.50 顺带覆盖 .list-header 里除 .title 以外的任何直接子节点。 原因:探针算下来 .list-header 有 16px 对不上账—— .title 68 + mb 20 + .subtitle 20 + mb 20 = 128, 而 .list-header 实测 144 高,多出的 16px 在探针里找不到归属元素。 「默认 / 倒序」排序按键在这份探针里也完全查不到 (5 份探针全文 grep「排序 / 默认 / 倒序」均 0 命中), 很可能就是这块延迟渲染 / 未被探针遍历到的东西。 这条规则只写 text-align / justify-content,命中不了就完全无副作用, 命中了就顺手把它一起居中;真正的定位还要等新探针确认。 */ body.bili-space-page .space-list-details .list-header > *:not(.title) { text-align: center !important; justify-content: center !important; } /* v131.51 合集详情页:简介行「.desc」文字一半跑到屏幕外 + 居中 探针 09-28_18-14-58 实测(route_listDetails): .list-header[344x210] top=134 bottom=344 mb=22 > .title[344x102] (.back[20x20] + .name[316x102])mb=20 > **.desc[677x20]** top=256 left=8 mb=12 ovf=hidden > .subtitle[344x20] top=288(pos=relative)mb=20 真凶就是 .desc:它是站内 PC 版留下的**定宽 677px**, 在 360 的视口里从 left=8 一直伸到 685,右半截整个在屏幕外; 自身 overflow:hidden 又只给 20px 高,等于"一行 + 裁掉右边"。 (顺带结案:上一版探针里 .list-header 对不上账的那 16px, 就是这个 .desc —— 那份探针没有列出它,我当时推测是排序按键, 推错了,排序按键在 .subtitle 里,已由 v131.50 那条规则居中。) 改法:宽度收回 100%(344),高度放开让它按 344 宽自动换行 (这句 21 个字,677px 一行 -> 344px 两行), 再解掉站内的单行省略号机制(nowrap / ellipsis / line-clamp), 最后 text-align + justify-content 双通路居中。 */ body.bili-space-page .space-list-details .list-header .desc, body.bili-space-page .space-list-details .list-header > .desc { display: block !important; width: 100% !important; max-width: 100% !important; min-width: 0 !important; height: auto !important; min-height: 0 !important; max-height: none !important; margin: 0 0 12px 0 !important; padding: 0 !important; box-sizing: border-box !important; float: none !important; line-height: 20px !important; text-align: center !important; justify-content: center !important; white-space: normal !important; word-break: break-word !important; overflow-wrap: anywhere !important; text-overflow: clip !important; -webkit-line-clamp: unset !important; line-clamp: unset !important; overflow: visible !important; background: transparent !important; } /* 高特异性兜底(v131.36 套路):站内这条定宽大概率写在选择器里, 用完整链路压过去,确保 677px 一定被 100% 顶掉。 */ body.bili-space-page main.space-main.route_listDetails > .space-list-details > .list-header > .desc { width: 100% !important; max-width: 100% !important; height: auto !important; max-height: none !important; text-align: center !important; white-space: normal !important; overflow: visible !important; } body.bili-space-page .space-list-details .list-content { display: grid !important; grid-template-columns: repeat(2, minmax(0, 1fr)) !important; grid-auto-rows: auto !important; gap: 8px !important; row-gap: 8px !important; column-gap: 8px !important; align-items: start !important; align-content: start !important; width: 100% !important; max-width: 100% !important; min-width: 0 !important; height: auto !important; min-height: 0 !important; max-height: none !important; padding: 0 !important; margin: 0 !important; box-sizing: border-box !important; float: none !important; overflow: visible !important; } /* 桌面版给 item 算的是 5 列宽(59),这里放开让它吃满格子 */ body.bili-space-page .space-list-details .list-video-item { display: block !important; width: 100% !important; max-width: 100% !important; min-width: 0 !important; height: auto !important; min-height: 0 !important; max-height: none !important; margin: 0 !important; padding: 0 !important; box-sizing: border-box !important; position: static !important; transform: none !important; left: auto !important; top: auto !important; float: none !important; flex: 0 1 auto !important; } /* ============================================================ ========== 通用两列视频卡片 ========== ============================================================ */ body.bili-home-page .container .bili-video-card, body.bili-home-page .container .bili-live-card, body.bili-search-page .bili-video-card, body.bili-search-page .bili-live-card, body.bili-search-page .search-video-card, body.bili-space-page .bili-video-card, body.bili-space-page .bili-live-card { --cover-radio: 56.25% !important; --title-font-size: 13px !important; --title-line-height: 18px !important; --title-padding-right: 0 !important; --no-interest-entry-size: 22px !important; --info-margin-top: 6px !important; --subtitle-font-size: 11px !important; width: 100% !important; max-width: 100% !important; min-width: 0 !important; height: auto !important; max-height: none !important; min-height: 0 !important; margin: 0 !important; padding: 0 !important; display: block !important; align-self: start !important; background: #ffffff !important; border: none !important; border-radius: 8px !important; box-shadow: 0 1px 3px rgba(0,0,0,0.08) !important; overflow: hidden !important; box-sizing: border-box !important; position: relative !important; float: none !important; } body.bili-home-page .container .bili-video-card__wrap, body.bili-home-page .container .bili-live-card__wrap, body.bili-search-page .bili-video-card__wrap, body.bili-search-page .bili-live-card__wrap, body.bili-space-page .bili-video-card__wrap, body.bili-space-page .bili-live-card__wrap { width: 100% !important; max-width: 100% !important; min-width: 0 !important; height: auto !important; max-height: none !important; margin: 0 !important; padding: 0 !important; display: block !important; background: transparent !important; border: none !important; border-radius: 8px !important; box-sizing: border-box !important; overflow: hidden !important; } body.bili-home-page .bili-video-card__image--wrap, body.bili-home-page .bili-video-card__image--link, body.bili-home-page .v-img.bili-video-card__cover, body.bili-home-page .bili-video-card .b-img, body.bili-home-page .bili-video-card picture, body.bili-search-page .bili-video-card__image--wrap, body.bili-search-page .bili-video-card__image--link, body.bili-search-page .v-img.bili-video-card__cover, body.bili-search-page .bili-video-card .b-img, body.bili-search-page .bili-video-card picture, body.bili-space-page .bili-video-card__image--wrap, body.bili-space-page .bili-video-card__image--link, body.bili-space-page .v-img.bili-video-card__cover, body.bili-space-page .bili-video-card .b-img, body.bili-space-page .bili-video-card picture { width: 100% !important; max-width: 100% !important; height: auto !important; min-height: 0 !important; margin: 0 !important; padding: 0 !important; border-radius: 8px 8px 0 0 !important; overflow: hidden !important; position: relative !important; display: block !important; float: none !important; box-sizing: border-box !important; } body.bili-home-page .bili-video-card__image--wrap img, body.bili-home-page .bili-video-card__image--link img, body.bili-home-page .v-img.bili-video-card__cover img, body.bili-home-page .bili-video-card .b-img > img, body.bili-home-page .bili-video-card .b-img__inner, body.bili-home-page .bili-video-card picture img, body.bili-search-page .bili-video-card__image--wrap img, body.bili-search-page .bili-video-card__image--link img, body.bili-search-page .v-img.bili-video-card__cover img, body.bili-search-page .bili-video-card .b-img > img, body.bili-search-page .bili-video-card .b-img__inner, body.bili-search-page .bili-video-card picture img, body.bili-space-page .bili-video-card__image--wrap img, body.bili-space-page .bili-video-card__image--link img, body.bili-space-page .v-img.bili-video-card__cover img, body.bili-space-page .bili-video-card .b-img > img, body.bili-space-page .bili-video-card .b-img__inner, body.bili-space-page .bili-video-card picture img { width: 100% !important; max-width: 100% !important; height: auto !important; aspect-ratio: 16 / 9 !important; object-fit: cover !important; display: block !important; margin: 0 !important; padding: 0 !important; box-sizing: border-box !important; } body.bili-home-page .bili-video-card__image--wrap picture > *, body.bili-search-page .bili-video-card__image--wrap picture > *, body.bili-space-page .bili-video-card__image--wrap picture > * { width: 100% !important; max-width: 100% !important; height: auto !important; padding: 0 !important; margin: 0 !important; display: block !important; box-sizing: border-box !important; } body.bili-home-page .bili-video-card__info, body.bili-home-page .bili-live-card__info, body.bili-home-page .video-info, body.bili-search-page .bili-video-card__info, body.bili-search-page .bili-live-card__info, body.bili-search-page .video-info, body.bili-space-page .bili-video-card__details, body.bili-space-page .bili-video-card__info, body.bili-space-page .bili-live-card__info { width: 100% !important; padding: 8px !important; margin: 0 !important; box-sizing: border-box !important; text-align: center !important; display: block !important; height: auto !important; max-height: none !important; min-height: 0 !important; background: transparent !important; } body.bili-home-page .bili-video-card__info--tit, body.bili-home-page .bili-video-card__info--tit a, body.bili-home-page .bili-video-card h3, body.bili-home-page .bili-video-card h3 a, body.bili-home-page .bili-live-card__info--tit, body.bili-home-page .bili-live-card__info--tit a, body.bili-search-page .bili-video-card__info--tit, body.bili-search-page .bili-video-card__info--tit a, body.bili-search-page .bili-video-card h3, body.bili-search-page .bili-video-card h3 a, body.bili-search-page .bili-live-card__info--tit, body.bili-search-page .bili-live-card__info--tit a, body.bili-space-page .bili-video-card__title, body.bili-space-page .bili-video-card__title > a, body.bili-space-page .bili-video-card__title .bili-ellipsis, body.bili-space-page .bili-video-card__info--tit, body.bili-space-page .bili-video-card__info--tit a { display: -webkit-box !important; -webkit-line-clamp: 2 !important; -webkit-box-orient: vertical !important; overflow: hidden !important; text-align: center !important; font-size: 13px !important; line-height: 18px !important; min-height: 36px !important; max-height: 36px !important; color: #18191c !important; font-weight: 500 !important; margin: 0 !important; padding: 0 !important; word-break: break-all !important; width: 100% !important; } body.bili-home-page .bili-video-card__info--bottom, body.bili-home-page .bili-video-card__info--owner, body.bili-home-page .bili-video-card__info--stat, body.bili-search-page .bili-video-card__info--bottom, body.bili-search-page .bili-video-card__info--owner, body.bili-search-page .bili-video-card__info--stat, body.bili-space-page .bili-video-card__info--bottom, body.bili-space-page .bili-video-card__info--owner, body.bili-space-page .bili-video-card__stats, body.bili-space-page .bili-video-card__subtitle, body.bili-space-page .bili-video-card__date { display: flex !important; justify-content: center !important; align-items: center !important; text-align: center !important; width: 100% !important; margin-top: 4px !important; margin-left: auto !important; margin-right: auto !important; padding: 0 !important; height: 21px !important; min-height: 21px !important; } /* ---- v132.10:直播卡「UP主名那一行」与综合页对齐 ---- 两份探针对比(都是搜索页 · 168x172 两列卡片): 综合页(card top=60) 封面 60 → 155 (95) info 155 → 232 (77 = pt8 + 61 + pb8) 标题 163 → 199 (36) UP主行 203 → 224 (21,margin-top 4) 直播页(card top=88) 封面 88 → 183 (95) info 183 → 257 (75 = pt8 + 59 + pb8) 标题 191 → 227 (36)← 与综合页同为「卡顶 +103」,已对齐 UP主行 231 → 249 (18,站内原生)← 少了 3px 标题那一行两页完全一致(都是卡顶 +103),差的只有下面这行: · 综合页被上面那条规则钉成了 21px 高 + margin-top 4px · 直播页的 UP主行没人管,保持站内原生的 18px, 于是整行比综合页矮 3px,卡片底也短了 2px (wrap 169 vs 172,卡底留 3px 空隙) 修法:给直播卡的 UP主行套上与综合页一致的几何值 (21px 高 + margin-top 4px), info = 8 + (36+4+21) + 8 = 77,wrap 补到 172。 ⚠ v132.09 的翻车点(本版修正): 上一版给这一行写了 width:100% + justify-content:center, 结果名字那一格(--author,站内是 flex:1)被撑满到 136px, 而 text-align:center 又是从 .bili-live-card__info 继承下来的, 于是: 图标 16 → 32 ← 贴在行的最左边 名字 32 → 168 ← 占满剩余,文字在这 136px 里居中 名字文字实际落在 74~126 附近,与图标之间空出一大段, 看起来就是「UP 图标和名字分家了」。 探针实证(bili_probe_2026-09-30_18-30-41): a.bili-live-card__info--uname [152x21] left=16 svg.bili-live-card__info--uname-icon [16x16] left=16 ← 顶到最左 span.bili-live-card__info--author [136x21] left=32 ← 撑满剩余 修法:这一行改成**收缩到内容宽**(inline-flex), 让「图标 + 名字」作为一个整体、由父级的 text-align:center 整体居中;名字不再 flex:1,而是紧贴图标、左对齐, 超长才省略。图标的原生右间距也别再抹掉。 ---- */ body.bili-home-page .bili-live-card__info--uname, body.bili-home-page .bili-live-card__info--owner, body.bili-home-page .bili-live-card__info--bottom, body.bili-search-page .bili-live-card__info--uname, body.bili-search-page .bili-live-card__info--owner, body.bili-search-page .bili-live-card__info--bottom, body.bili-space-page .bili-live-card__info--uname, body.bili-space-page .bili-live-card__info--owner, body.bili-space-page .bili-live-card__info--bottom, body.bili-home-page .bili-live-card__info--text > *:not(.bili-live-card__info--tit), body.bili-search-page .bili-live-card__info--text > *:not(.bili-live-card__info--tit), body.bili-space-page .bili-live-card__info--text > *:not(.bili-live-card__info--tit) { /* inline-flex:宽度收缩到「图标 + 名字」的实际内容宽, 整体再由父级的 text-align:center 居中 —— 图标不再被 甩到行首,两者始终贴在一起。 */ display: inline-flex !important; flex-wrap: nowrap !important; align-items: center !important; justify-content: center !important; width: auto !important; max-width: 100% !important; min-width: 0 !important; height: 21px !important; min-height: 21px !important; max-height: 21px !important; margin: 4px auto 0 auto !important; padding: 0 !important; line-height: 21px !important; box-sizing: border-box !important; } /* 名字那一格:只占自己内容那么宽,紧跟图标;超长才省略。 ⚠ 不写 text-align:center —— 那会让文字在剩余空间里居中, 与图标之间空出一大段,正是"分家"的成因。 */ body.bili-home-page .bili-live-card__info--author, body.bili-search-page .bili-live-card__info--author, body.bili-space-page .bili-live-card__info--author, body.bili-home-page .bili-live-card__info--uname > span, body.bili-search-page .bili-live-card__info--uname > span, body.bili-space-page .bili-live-card__info--uname > span { flex: 0 1 auto !important; width: auto !important; max-width: 100% !important; min-width: 0 !important; height: 21px !important; max-height: 21px !important; margin: 0 !important; padding: 0 !important; line-height: 21px !important; text-align: left !important; white-space: nowrap !important; overflow: hidden !important; text-overflow: ellipsis !important; } /* UP 图标:固定 16x16,保留站内原生的右间距(不再 margin:0 抹平) */ body.bili-home-page .bili-live-card__info--uname-icon, body.bili-search-page .bili-live-card__info--uname-icon, body.bili-space-page .bili-live-card__info--uname-icon, body.bili-home-page .bili-live-card__info--uname > svg, body.bili-search-page .bili-live-card__info--uname > svg, body.bili-space-page .bili-live-card__info--uname > svg { flex: 0 0 auto !important; width: 16px !important; height: 16px !important; min-width: 16px !important; max-height: none !important; line-height: normal !important; flex-shrink: 0 !important; } body.bili-home-page .bili-watch-later, body.bili-home-page [class*="watch-later"], body.bili-home-page [class*="watchlater"], body.bili-home-page [class*="add-to-watch-later"], body.bili-home-page [class*="watch-later-btn"], body.bili-home-page .bili-video-card__mask, body.bili-search-page .bili-watch-later, body.bili-search-page [class*="watch-later"], body.bili-search-page [class*="watchlater"], body.bili-search-page [class*="add-to-watch-later"], body.bili-search-page [class*="watch-later-btn"], body.bili-search-page .bili-video-card__mask, body.bili-space-page .bili-card-watch-later, body.bili-space-page .bili-video-card .bili-watch-later, body.bili-space-page .bili-video-card [class*="watch-later"] { display: none !important; visibility: hidden !important; } /* v131.21 投稿页 / 搜索页的卡片外观改为与主页卡片完全一致。 主页和投稿页用的是同一个 .bili-video-card 组件(168x172, 封面 95 + 信息区 77,标题 152x36,副标题 152x21),DOM 尺寸本来就一样, 差的只是这条规则把投稿卡的背景/圆角/阴影全清掉了,看起来比主页卡"素"。 这里只保留 border:none(v131.6 要去掉的投稿卡文字框边框), 背景、圆角、阴影统统交还给原生 -> 与主页同源、必然一致。 搜索页的卡片同样包在 .upload-video-card 里,一并生效。 */ body.bili-space-page .upload-video-card .bili-video-card, body.bili-space-page .upload-video-card .bili-video-card__wrap { border: none !important; overflow: hidden !important; } /* ============================================================ v131.13 UP主主页三处调整 ============================================================ */ /* ---------- 1) 隐藏「收藏夹 ·N」整块 ---------- 结构:section.home-section > .section-wrap.fav-section > .section-wrap__header + .section-wrap__content > .fav-section__content > .items 用 :has() 把外层 section 一并收掉,避免留下空壳占位。 */ /* ---------- 1c) 隐藏「最近点赞的视频」整块(v131.22)---------- 探针实测(洛克宅桑主页): section.home-section:nth-of-type(8) > .section-wrap.like-section[344x964] > .section-wrap__header(标题「最近点赞的视频」) > .section-wrap__content > .like-section__content[344x890] > .items 用 :has() 连带外层 section,避免只收内层留下空壳。 */ body.bili-space-page .route_home .section-wrap.like-section, body.bili-space-page .route_home .like-section__content, body.bili-space-page .route_home .home-section:has(> .section-wrap.like-section) { display: none !important; visibility: hidden !important; width: 0 !important; height: 0 !important; min-height: 0 !important; max-height: 0 !important; margin: 0 !important; padding: 0 !important; border: none !important; overflow: hidden !important; } /* ---------- 1b) 隐藏「订阅追番 ·N」整块(v131.21)---------- 与收藏夹同一套路:按区块类名收掉,并用 :has() 连带外层 section。 站内这一块的类名在 bangumi / sub / follow 之间换过, 这里三种写法都写上,任一命中即隐藏。 */ body.bili-space-page .route_home .section-wrap.bangumi-section, body.bili-space-page .route_home .bangumi-section__content, body.bili-space-page .route_home .section-wrap.sub-section, body.bili-space-page .route_home .sub-section__content, body.bili-space-page .route_home .section-wrap.follow-section, body.bili-space-page .route_home .follow-section__content, body.bili-space-page .route_home .home-section:has(> .section-wrap.bangumi-section), body.bili-space-page .route_home .home-section:has(> .section-wrap.sub-section), body.bili-space-page .route_home .home-section:has(> .section-wrap.follow-section) { display: none !important; visibility: hidden !important; width: 0 !important; height: 0 !important; min-height: 0 !important; max-height: 0 !important; margin: 0 !important; padding: 0 !important; border: none !important; overflow: hidden !important; } body.bili-space-page .route_home .section-wrap.fav-section, body.bili-space-page .route_home .fav-section__content, body.bili-space-page .route_home .home-section:has(> .section-wrap.fav-section) { display: none !important; visibility: hidden !important; width: 0 !important; height: 0 !important; min-height: 0 !important; max-height: 0 !important; margin: 0 !important; padding: 0 !important; border: none !important; overflow: hidden !important; } /* ---------- 2) 专栏卡片 -> 与视频卡片完全一致 ---------- 视频卡实测:168x172 = 封面 95(16:9) + 信息区 77 信息区 = padding8 + 标题36(13px/18px 两行) + 间距4 + 副标题21 + padding8 专栏卡原为 168x166(封面 95 + 底部 61,标题 15px/22.5px 三行), 这里把外框/圆角/阴影/字号行高全部对齐视频卡,并把信息区锁成 77px, 保证两列网格里两种卡片等高、标题基线一致。 */ body.bili-space-page .route_home .article-section .article-list { margin-top: 20px !important; } body.bili-space-page .article-card { width: 100% !important; max-width: 100% !important; min-width: 0 !important; height: 172px !important; max-height: 172px !important; min-height: 172px !important; margin: 0 !important; padding: 0 !important; box-sizing: border-box !important; display: block !important; position: relative !important; float: none !important; background: #ffffff !important; border: none !important; border-radius: 8px !important; box-shadow: 0 1px 3px rgba(0,0,0,0.08) !important; overflow: hidden !important; } /* 封面区:原生是用 padding-top 比例盒(或定高 95px)撑开、 封面 绝对定位铺满的。上一版在这里写了 height:auto + padding:0,把比例盒清零 -> 封面塌成 0 高, 文字就顶到了卡片最上面。这里只改外观,不再碰 height/padding, 比例交给原生(168x95 本身就是 16:9)。 */ body.bili-space-page .article-card__top { display: block !important; width: 100% !important; max-width: 100% !important; min-width: 0 !important; margin: 0 !important; box-sizing: border-box !important; /* 兜底:高度算不出来时用 16:9 撑开(定高或比例盒在时不起作用) */ aspect-ratio: 16 / 9 !important; position: relative !important; float: none !important; border: none !important; border-radius: 8px 8px 0 0 !important; overflow: hidden !important; background: transparent !important; } body.bili-space-page .article-card__cover { display: block !important; width: 100% !important; max-width: 100% !important; margin: 0 !important; border: none !important; border-radius: 8px 8px 0 0 !important; overflow: hidden !important; background: transparent !important; } /* 缩略图兜底:万一原生高度没算出来,用 16:9 撑住, 图片铺满并按 cover 裁切,保证任何情况下都有封面 */ body.bili-space-page .article-card__top > .article-card__cover, body.bili-space-page .article-card__top .bili-cover-card__thumbnail { position: absolute !important; inset: 0 !important; width: 100% !important; height: 100% !important; min-height: 0 !important; padding: 0 !important; margin: 0 !important; box-sizing: border-box !important; } body.bili-space-page .article-card__top img, body.bili-space-page .article-card__cover img, body.bili-space-page .article-card__top .b-img__inner { width: 100% !important; max-width: 100% !important; height: 100% !important; object-fit: cover !important; display: block !important; margin: 0 !important; padding: 0 !important; border: none !important; border-radius: 0 !important; box-sizing: border-box !important; } body.bili-space-page .article-card__bottom { width: 100% !important; height: 77px !important; min-height: 77px !important; max-height: 77px !important; margin: 0 !important; padding: 8px !important; box-sizing: border-box !important; background: transparent !important; display: flex !important; flex-direction: column !important; justify-content: center !important; align-items: stretch !important; text-align: center !important; overflow: hidden !important; } body.bili-space-page .article-card__bottom .title { display: -webkit-box !important; -webkit-line-clamp: 2 !important; -webkit-box-orient: vertical !important; overflow: hidden !important; text-align: center !important; width: 100% !important; font-size: 13px !important; line-height: 18px !important; min-height: 36px !important; max-height: 36px !important; color: #18191c !important; font-weight: 500 !important; margin: 0 !important; padding: 0 !important; word-break: break-all !important; text-decoration: none !important; } /* 标题内层再套了一层 .vui_ellipsis.multi-mode, 让它退化为普通内联文本,避免两层 clamp 叠出额外高度 */ body.bili-space-page .article-card__bottom .title > * { display: inline !important; font-size: 13px !important; line-height: 18px !important; color: #18191c !important; font-weight: 500 !important; -webkit-line-clamp: unset !important; -webkit-box-orient: unset !important; min-height: 0 !important; max-height: none !important; margin: 0 !important; padding: 0 !important; text-align: center !important; white-space: normal !important; } /* ---------- 3) 顶部 tab 蓝色位置条:改为跟随选中项自身定位 ---------- 原因:脚本用 fixSpaceNavTabs() 把「收藏夹/订阅」等 tab 设为 display:none, 站内那条蓝色条是按 tab 序号/旧布局算出来的绝对定位元素, 隐藏若干 tab 后算出的 left 就对不上了(每次刷新还不一定一样)。 做法:隐藏所有非 的兄弟节点(即那条 JS 定位的滑动条), 改由选中项自身的 ::after 画线,位置永远等于该项实际位置。 */ body.bili-space-page .nav-tab { position: relative !important; } body.bili-space-page .nav-tab > *:not(a) { display: none !important; visibility: hidden !important; width: 0 !important; height: 0 !important; margin: 0 !important; padding: 0 !important; overflow: hidden !important; } body.bili-space-page .nav-tab::before, body.bili-space-page .nav-tab::after, body.bili-space-page .nav-tab > a.nav-tab__item::before { content: none !important; display: none !important; } body.bili-space-page .nav-tab > a.nav-tab__item { position: relative !important; } body.bili-space-page .nav-tab > a.nav-tab__item::after { content: '' !important; display: block !important; position: absolute !important; left: 0 !important; right: 0 !important; bottom: 0 !important; width: auto !important; min-width: 0 !important; height: 3px !important; margin: 0 !important; padding: 0 !important; border: none !important; border-radius: 2px !important; transform: none !important; transition: none !important; background: transparent !important; } body.bili-space-page .nav-tab > a.nav-tab__item.active::after, body.bili-space-page .nav-tab > a.nav-tab__item.router-link-exact-active::after { background: #00aeec !important; } body.bili-space-page .nav-tab > a.nav-tab__item.active, body.bili-space-page .nav-tab > a.nav-tab__item.router-link-exact-active { color: #00aeec !important; } /* ---------- 4a) 投稿 → 图文:筛选栏「全部图文 / 专栏 / 动态」上下间距 8px ---------- v131.42 结构(探针 09-27_18-12-07 实测,route_uploadOpus): .upload-content[360x2422](脚本设的 padding: 0 8px 16px) > .opus[344x2406] > .opus-header[344x34](全部图文 专栏 动态) > .opus-header__top[344x34] > .content-filter > .content-tab(.active = 全部图文 / 专栏 / 动态) > .opus-body[344x2222] > .opus-feed > .masonry_grid_v2 目标(与卡片间距 8px 一致): ① 胶囊栏「视频 图文 音频」底 → 筛选栏顶 = 8 = upload-sidenav 自带的 padding-bottom 8 + .opus / .opus-header 的 margin-top 归零 ② 筛选栏底 → 卡片顶 = 8 = .opus-header margin-bottom 8 + .opus-body margin-top 归零 站内原生在 header 与 body 之间留了很大空档(旧探针里 .opus 2406 − header 34 − body 2222 = 150),这里一并归零。 ------------------------------------------------------------ */ body.bili-space-page .opus { width: 100% !important; max-width: 100% !important; min-width: 0 !important; margin: 0 !important; padding: 0 !important; box-sizing: border-box !important; } /* v131.43 修正下边距:v131.42 把 .opus-header 和它的子元素 .opus-header__top 都设了 margin-bottom: 8px,父子两层嵌套叠加 -> 实际间距 16px。这里只保留外层 .opus-header 一个 8, 内层 __top 的 margin 全部归零。 */ /* v131.44 下边距仍偏高 -> 说明 margin 不是唯一来源。 既然 header 内部可能还挂着别的子节点(或站内给它留了固有高度), 这里不再猜内容,直接把「筛选栏这一行的可见高度」锁死为 34px (探针实测筛选胶囊就是 34 高)+ overflow:hidden 裁掉多余, 下方间距就恒等于 margin-bottom 8px,与内容多寡无关。 */ body.bili-space-page .opus-header { display: block !important; width: 100% !important; max-width: 100% !important; min-width: 0 !important; height: 34px !important; min-height: 34px !important; max-height: 34px !important; margin: 0 0 8px 0 !important; padding: 0 !important; box-sizing: border-box !important; overflow: hidden !important; } body.bili-space-page .opus-header__top { display: block !important; width: 100% !important; max-width: 100% !important; min-width: 0 !important; height: 34px !important; min-height: 34px !important; max-height: 34px !important; margin: 0 !important; padding: 0 !important; box-sizing: border-box !important; overflow: hidden !important; } /* v131.46 筛选栏整行居中(纯 CSS,不用 JS 量宽度)。 探针 09-28_17-02-40 实测:.content-filter[344x34] 内三个 .content-tab 分别 130 / 82 / 48,gap 8 -> 内容总宽 276, 右侧空 68,故为左对齐(left 依次 8 / 146 / 236)。 只加 justify-content:center 即可让 276 在 344 内左右各留 34, 不动 tab 自身宽度 / padding / flex,避免连带改变胶囊外观。 */ body.bili-space-page .content-filter { display: flex !important; flex-direction: row !important; align-items: center !important; justify-content: center !important; gap: 8px !important; width: 100% !important; max-width: 100% !important; min-width: 0 !important; height: 34px !important; min-height: 34px !important; max-height: 34px !important; margin: 0 !important; padding: 0 !important; box-sizing: border-box !important; overflow: hidden !important; } body.bili-space-page .content-tab { margin: 0 !important; padding: 0 !important; box-sizing: border-box !important; } /* v131.46 兜底:沿用 v131.36 的思路,把完整链路写进选择器抬高特异性, 防止站内晚加载的同权重 !important 规则把居中顶掉。 */ body.bili-space-page main.space-main .upload-content .opus > .opus-header > .opus-header__top > .content-filter { justify-content: center !important; } /* ---------- 4a-2) 投稿 → 图文:筛选栏竖条居中 + 文字缩小 ---------- v131.47 探针 09-28_17-15-03 实测(居中已生效): .content-filter[344x34](justify-content:center 生效) > .content-tab[130x24] left=42 全部图文 > .content-tab.active[82x24] left=180 专栏 > .content-tab[48x24] left=270 动态 竖条在探针里查不到——探针只遍历真实元素,竖条是 .content-tab 的 伪元素。但宽度把它暴露了:「动态」是最后一个胶囊、身后没有竖条, 48 = 2 字 + 左右内边距;「专栏」2 字却占 82,「全部图文」4 字占 130, 两者都比纯文字多出约 34px。这 34px 就是**在文档流里**的竖条 (约 1px 线 + 左右各 16px 外边距),它长在胶囊内部右侧。 于是「文字 → 竖条」只有 16,而「竖条 → 下一个胶囊的文字」是 16 + 我们设的 gap 8 + 对方内边距 —— 竖条自然偏向左边那个按键, 这正是用户看到的不平分。 解法(依旧纯 CSS): ① 先把站内挂在 ::before / ::after 上的竖条全部停掉, 让胶囊宽度回归纯文字宽度; ② 竖条由我们自己用 ::after 重画,position:absolute + left:100% + margin-left:3.5px —— 即落在 8px 间隙的正中 ((8 − 1) / 2 = 3.5),与左右两个按键严格等距; ③ 字号 14 → 12,行高锁 24 保持胶囊高度与垂直居中不变。 绝对定位的竖条不占文档流,所以 gap 就是纯粹的文字间距, 整行仍由 .content-filter 的 justify-content:center 居中。 ------------------------------------------------------------ */ body.bili-space-page .content-filter > .content-tab { position: relative !important; height: 24px !important; min-height: 24px !important; max-height: 24px !important; margin: 0 !important; padding: 0 !important; border: none !important; box-sizing: border-box !important; font-size: 12px !important; line-height: 24px !important; flex: 0 0 auto !important; } /* ① 停掉站内自绘的竖条(两个伪元素都清,避免漏网或重复) */ body.bili-space-page .content-filter > .content-tab::before { display: none !important; content: none !important; } body.bili-space-page .content-filter > .content-tab::after { display: none !important; content: none !important; } /* ② 我们自己画:只在非最后一个胶囊的右侧、8px 间隙正中 */ body.bili-space-page .content-filter > .content-tab:not(:last-child)::after { display: block !important; content: '' !important; position: absolute !important; top: 50% !important; left: 100% !important; right: auto !important; width: 1px !important; height: 10px !important; margin: 0 0 0 3.5px !important; padding: 0 !important; border: none !important; border-radius: 0 !important; transform: translateY(-50%) !important; background: #e5e9ef !important; } /* 高特异性兜底:与 v131.36 / v131.46 同一套路, 防站内晚加载的同权重 !important 把上面这组顶掉。 */ body.bili-space-page main.space-main .upload-content .opus > .opus-header > .opus-header__top > .content-filter > .content-tab { position: relative !important; margin: 0 !important; padding: 0 !important; border: none !important; font-size: 12px !important; line-height: 24px !important; } /* v131.43:下游这一串的上边距全部归零, 下边距只由 .opus-header 那一个 8px 提供,避免任何一处再叠加。 */ body.bili-space-page .opus-body { width: 100% !important; max-width: 100% !important; min-width: 0 !important; margin: 0 !important; padding: 0 !important; box-sizing: border-box !important; } body.bili-space-page .opus-body .opus-feed, body.bili-space-page .opus-body .opus-feed .masonry_grid_v2, body.bili-space-page .opus-body .opus-feed .masonry_grid_v2 > .container, body.bili-space-page .opus-body .opus-feed .masonry_grid_v2 > .container > .item { margin-top: 0 !important; padding-top: 0 !important; min-height: 0 !important; box-sizing: border-box !important; } /* v131.44 兜底:瀑布流是 JS 布局,站内常给容器留 min-height / 给首个 item 写 transform 偏移。这里把首行之前的一切偏移清掉。 */ body.bili-space-page .opus-body .opus-feed .masonry_grid_v2 > .container > .item:first-child, body.bili-space-page .opus-body .opus-feed .masonry_grid_v2 > .container > .item:nth-of-type(1) { margin-top: 0 !important; padding-top: 0 !important; transform: none !important; translate: none !important; } /* ---------- 4) 投稿 → 图文:瀑布流改两列网格,卡片对齐主页专栏卡 ---------- 结构:.opus-feed > .masonry_grid_v2 > .container[814 宽,JS 瀑布流] > .item(绝对定位 + transform) > .opus-card > .opus-card--with-cover > [a.opus-card__cover(缩略图 + stats), a.opus-card__title] 原卡 189x187(封面 142 + 标题 46),瀑布流列宽由 JS 算。 (!important 的作者样式优先级高于站内 JS 写在 style 属性里的普通声明, 所以 transform / position / width 都能直接压住。) */ /* 外层只做"满宽容器",绝不能再设成网格: 一旦 .masonry_grid_v2 也是两列网格,它唯一的子元素 .container 就会变成占一列的网格项,宽度掉到 (344-8)/2 = 168, 卡片再被挤成 80x172,整块内容就都堆在屏幕左半边了。 */ body.bili-space-page .opus-feed .masonry_grid_v2 { display: block !important; width: 100% !important; max-width: 100% !important; min-width: 0 !important; height: auto !important; min-height: 0 !important; max-height: none !important; padding: 0 !important; margin: 0 !important; box-sizing: border-box !important; position: static !important; overflow: visible !important; } body.bili-space-page .opus-feed .masonry_grid_v2 > .container { display: grid !important; grid-template-columns: repeat(2, minmax(0, 1fr)) !important; grid-auto-rows: auto !important; gap: 8px !important; row-gap: 8px !important; column-gap: 8px !important; align-items: start !important; align-content: start !important; width: 100% !important; max-width: 100% !important; min-width: 0 !important; height: auto !important; min-height: 0 !important; max-height: none !important; padding: 0 !important; margin: 0 !important; box-sizing: border-box !important; position: static !important; overflow: visible !important; list-style: none !important; } body.bili-space-page .opus-feed .masonry_grid_v2 > .container > .item { position: static !important; transform: none !important; translate: none !important; left: auto !important; top: auto !important; right: auto !important; bottom: auto !important; inset: auto !important; width: auto !important; max-width: 100% !important; min-width: 0 !important; height: auto !important; min-height: 0 !important; max-height: none !important; margin: 0 !important; padding: 0 !important; box-sizing: border-box !important; display: block !important; visibility: visible !important; opacity: 1 !important; float: none !important; } /* 卡片本体:与主页专栏卡同一套外观(白底 / 8px 圆角 / 同一条阴影 / 172 高) */ body.bili-space-page .opus-card, body.bili-space-page .opus-card--with-cover { width: 100% !important; max-width: 100% !important; min-width: 0 !important; height: 172px !important; min-height: 172px !important; max-height: 172px !important; margin: 0 !important; padding: 0 !important; box-sizing: border-box !important; display: block !important; position: relative !important; float: none !important; background: #ffffff !important; border: none !important; border-radius: 8px !important; box-shadow: 0 1px 3px rgba(0,0,0,0.08) !important; overflow: hidden !important; } body.bili-space-page .opus-card__cover { display: block !important; position: relative !important; float: none !important; width: 100% !important; max-width: 100% !important; height: 95px !important; min-height: 95px !important; max-height: 95px !important; margin: 0 !important; padding: 0 !important; box-sizing: border-box !important; border: none !important; border-radius: 8px 8px 0 0 !important; overflow: hidden !important; background: transparent !important; } body.bili-space-page .opus-card__cover > .bili-cover-card__thumbnail, body.bili-space-page .opus-card__cover > a.bili-cover-card__thumbnail { position: absolute !important; inset: 0 !important; width: 100% !important; height: 100% !important; min-height: 0 !important; padding: 0 !important; margin: 0 !important; box-sizing: border-box !important; } body.bili-space-page .opus-card__cover img, body.bili-space-page .opus-card__cover .b-img__inner { width: 100% !important; max-width: 100% !important; height: 100% !important; object-fit: cover !important; display: block !important; margin: 0 !important; padding: 0 !important; border: none !important; border-radius: 0 !important; box-sizing: border-box !important; } /* 标题区:高度仍是 77px(= 卡片 172 − 封面 95),但内部不再留白。 v131.48 探针 09-28_17-02-40 实测: a.opus-card__title[168x77](pt 8 / pb 8,overflow hidden) > div.vui_ellipsis.multi-mode[152x36] ← 只有这一个子节点 关键差异:别的页面卡片(主页 / 投稿视频 / 专栏)标题下方还有一行 日期·播放量之类的元信息,所以 77px 里必须给那行留位置; 而图文卡的标题盒里**只有文字**,没有任何元信息行, 旧规则照抄 77px 结构 + 2 行截断,就白扔掉了 77 − 8×2 − 36 = 25px 的空白。 可用文字高度 = 77 − 上下 padding 8×2 = 61px: 2 行 × 18 = 36(旧,浪费 25) 3 行 × 20 = 60(新,只剩 1px 余量,几乎填满) 4 行 × 18 = 72 > 61(放不下,会被 overflow 裁掉半行) 所以取 3 行,并把行高从 18 提到 20 —— 字号仍是 13px 不变, 多出的 2px 行距既补足高度,也让三行不至于挤在一起。 */ body.bili-space-page .opus-card__title { display: block !important; width: 100% !important; max-width: 100% !important; height: 77px !important; min-height: 77px !important; max-height: 77px !important; padding: 8px !important; margin: 0 !important; box-sizing: border-box !important; text-align: center !important; text-decoration: none !important; background: transparent !important; overflow: hidden !important; } body.bili-space-page .opus-card__title > * { display: -webkit-box !important; -webkit-line-clamp: 3 !important; line-clamp: 3 !important; -webkit-box-orient: vertical !important; overflow: hidden !important; text-align: center !important; width: 100% !important; font-size: 13px !important; line-height: 20px !important; min-height: 60px !important; max-height: 60px !important; color: #18191c !important; font-weight: 500 !important; margin: 0 !important; padding: 0 !important; word-break: break-all !important; white-space: normal !important; } /* v131.48 兜底:站内 .vui_ellipsis.multi-mode 自己带一套 line-clamp / max-height(探针里它被压成 152x36 就是这套在起作用), 用完整链路抬特异性,确保 3 行 / 60px 压得住。 */ body.bili-space-page .opus-card .opus-card--with-cover > a.opus-card__title > .vui_ellipsis.multi-mode { display: -webkit-box !important; -webkit-line-clamp: 3 !important; line-clamp: 3 !important; -webkit-box-orient: vertical !important; overflow: hidden !important; width: 100% !important; max-width: 100% !important; height: 60px !important; min-height: 60px !important; max-height: 60px !important; font-size: 13px !important; line-height: 20px !important; text-align: center !important; margin: 0 !important; padding: 0 !important; box-sizing: border-box !important; word-break: break-all !important; white-space: normal !important; text-overflow: ellipsis !important; } /* ---------- 4a-3) 投稿 → 图文 → 专栏:隐藏封面底部的播放量浮层 ---------- v131.52 探针 09-28_18-44-13 实测(route_uploadOpus,专栏 tab): .opus-collection[344x209] mb=30 > .opus-collection-wrap[344x208] > .opus-collection-list[344x208] pb=30 ← 一行 5 张 > .upload-opus-collection-card[51x178] ×5 > .upload-opus-collection-card__top[51x68] > a.upload-opus-collection-card__cover[51x68] (pt=68.4062px,用 padding 撑封面比例) > .bili-cover-card__thumbnail[51x68](absolute) > **.bili-cover-card__stats[51x34]** (absolute z=2,pt=14 pb=4,top=230→264) text = 30万 1篇专栏 / 111.7万 4篇专栏 … > .upload-opus-collection-card__bottom[51x74] (a.title[51x44] + .subtitle[51x26]) 用户要去掉的「眼睛图标 30万 / 眼睛图标 111.7万」就是 .bili-cover-card__stats 这层浮在封面底部的半透明条。 ⚠ 一个硬限制:探针显示 .bili-cover-card__stats **没有任何子元素**, 「30万」和「1篇专栏」是同一个 div 里的两串文本节点 (眼睛图标走伪元素 / 图标字体),CSS 能选到的最小粒度就是这个 div 整体 —— 没法只挑出播放量那一串而留下「N篇专栏」。 所以这里整层 display:none,「N篇专栏」会一并消失。 真要只留「N篇专栏」,就只能上 JS 遍历文本节点,与"尽量用 CSS"相悖。 封面本体不受影响:比例是靠 a 上的 padding-top:68.4062px 撑的, 与 stats 无绝对定位依赖,隐藏后封面不会塌陷。 作用域严格锁在 .upload-opus-collection-card 内 —— 全部图文 tab 的 .opus-card 封面同样挂着 .bili-cover-card__stats (显示 379 / 420 之类播放量),那处用户没要求动,绝不能误伤。 ------------------------------------------------------------ */ body.bili-space-page .opus-collection-list .upload-opus-collection-card .bili-cover-card__stats { display: none !important; visibility: hidden !important; opacity: 0 !important; } body.bili-space-page .upload-opus-collection-card__cover > .bili-cover-card__stats { display: none !important; } /* 高特异性兜底(v131.36 套路):完整链路压过去, 防站内晚加载的同权重 !important 把浮层放回来。 */ body.bili-space-page main.space-main.route_uploadOpus .opus-collection > .opus-collection-wrap > .opus-collection-list > .upload-opus-collection-card > .upload-opus-collection-card__top > a.upload-opus-collection-card__cover > .bili-cover-card__stats { display: none !important; visibility: hidden !important; opacity: 0 !important; } /* ---------- 4a-4) 投稿 → 图文 → 专栏:5 卡一行的间距统一 8px ---------- v131.53 探针 09-28_18-44-13 实测(route_uploadOpus,专栏 tab): .opus-collection[344x209] left=8 mb=30 > .opus-collection-wrap[344x208] left=8 > .opus-collection-list[344x208] left=8 pb=30 > .upload-opus-collection-card[51x178] ×5 5 张卡的实测 left 与宽度: ①left=8 ②left=81 ③left=154 ④left=228 ⑤left=301,每张 w=51 由此反推现状: 卡间间隙 = 81-59=22 / 154-132=22 / 228-205=23 / 301-279=22 末卡右边 = 301+51 = 352 = 容器右边(8+344) 5×51 + (22+22+23+22) = 255 + 89 = 344 ✓ 正好占满 即:**左右边距本来就是 8px**(首卡 left=8 距屏幕左边 8, 末卡右边 352 距屏幕右边 360-352 = 8),需要改的只有卡间间隙。 22/22/23/22 这种"余数摊不平"的分布,是 flex + space-between 把 344-255=89 的剩余空间平分给 4 个间隙的结果(89/4=22.25)。 改法:不跟站内的定宽 + space-between 纠缠,直接把容器改成 5 等分网格 + gap 8,卡片宽度交还给网格(width:100% 填满列): 列宽 = (344 - 4×8) / 5 = 312 / 5 = 62.4px 卡间 = 8px 恒定,不再有 22/23 的抖动 首末 = 8px(网格铺满 344,与容器 padding 一致)→ 距屏幕边缘仍 8px ✓ 用 grid 而非 flex 的原因:62.4 是小数,flex 定宽要写 calc 且 仍可能因舍入差 1px;grid 的 1fr 由浏览器精确分配,天然铺满。 注意保留 .opus-collection-list 自带的 padding-bottom:30 (那是这一行到下方内容的纵向间距,不在本次需求内), 所以只写 grid / gap / width,不碰 padding 与 margin。 ------------------------------------------------------------ */ body.bili-space-page .opus-collection-list { display: grid !important; grid-template-columns: repeat(5, minmax(0, 1fr)) !important; grid-auto-rows: auto !important; grid-auto-flow: row !important; gap: 8px !important; row-gap: 8px !important; column-gap: 8px !important; justify-content: stretch !important; justify-items: stretch !important; align-items: start !important; align-content: start !important; width: 100% !important; max-width: 100% !important; min-width: 0 !important; box-sizing: border-box !important; float: none !important; } /* 卡片宽度交还网格:站内那套 51px 定宽必须让位, 否则 5×51 + 4×8 = 287 < 344,右边会空出 57px, "末卡距屏幕右边 8px"就不成立了。 */ body.bili-space-page .opus-collection-list > .upload-opus-collection-card { width: 100% !important; max-width: 100% !important; min-width: 0 !important; margin: 0 !important; float: none !important; box-sizing: border-box !important; } /* 卡内各层同样满宽跟随,否则封面 / 标题仍按 51px 排, 卡片变宽后右侧会留白 */ body.bili-space-page .opus-collection-list .upload-opus-collection-card__top, body.bili-space-page .opus-collection-list .upload-opus-collection-card__bottom, body.bili-space-page .opus-collection-list a.upload-opus-collection-card__cover, body.bili-space-page .opus-collection-list .upload-opus-collection-card__bottom > .title, body.bili-space-page .opus-collection-list .upload-opus-collection-card__bottom > .subtitle, body.bili-space-page .opus-collection-list .upload-opus-collection-card .vui_ellipsis { width: 100% !important; max-width: 100% !important; min-width: 0 !important; box-sizing: border-box !important; } /* 高特异性兜底(v131.36 套路) */ body.bili-space-page main.space-main.route_uploadOpus .opus-collection > .opus-collection-wrap > .opus-collection-list { display: grid !important; grid-template-columns: repeat(5, minmax(0, 1fr)) !important; gap: 8px !important; row-gap: 8px !important; column-gap: 8px !important; } body.bili-space-page main.space-main.route_uploadOpus .opus-collection > .opus-collection-wrap > .opus-collection-list > .upload-opus-collection-card { width: 100% !important; max-width: 100% !important; min-width: 0 !important; margin: 0 !important; } /* ============================================================ ========== 专栏文集页(/read/readlist/rlXXX)头部整块居中 ========== v131.54 探针 09-29_07-17-17 实测(body.bili-opus-page,360x951): #app[360x943] > .container[344x879] left=8 pt=27 pb=30 ← 8..352,本身已居中 > .list[344x822] top=99 > .list-header[344x226] left=8 pt=20 pb=20 mb=10 > **.list-header__right[294x186] left=38** pt=6 > .title[275x36] left=57 「宝可梦剧场版 神速的炎帝与圈圈熊觉醒」 > .up-info[275x42] left=57 mt=13 mb=10 > .up-info__holder[42x42] left=57 (头像 24 + 挂件 42) > .up-name[89x42] left=103 (.up-name-text 50 + .nameplate 25) > button.follow-btn.on[49x24] left=206 「已关注」 > .desc[275x30] left=57 mb=12 > div[30x30] left=57 「4篇专栏」 > div[38x30] left=97 「7591个字」 > div[57x30] left=145 「1117550次阅读」 > div[50x30] left=212 「2023-11-26更新」 > div[50x30] left=272 「文集号:771595」 > .list-content[344x586] 不居中的根因:这一栏是 PC 版的「左封面 + 右信息」两栏布局。 左侧封面位在手机站没渲染出来(探针里查不到 .list-header__left), 但它的占位还在 —— .list-header__right 被推到 left=38 (距容器左边 30,距右边 352-332 = 20),自身又是 294 定宽, 里面的 .title / .up-info / .desc 全是 275 定宽左对齐, 所以标题、UP 行、5 个统计项统统偏在左半边。 ⚠ 还有一处对不上账:.list-header__right 高 186, pt6 + title36 + up-info(13+42+10) + desc(30+12) = 149, 差 37px 在探针里找不到归属元素 —— 用户报的最后一行 「宝可梦同人剧场版」在整份探针里 grep 也是 0 命中, 这 37px 极可能就是它(探针漏遍历,和上一版 .desc 被漏掉同因)。 所以这里**不逐个点名**,改用 .list-header__right > * 通配, 让探针没列出来的那一行也一并被覆盖到。 改法(三步,纯 CSS): ① .list-header 打散成单列块级,隐藏 PC 的左侧封面占位; ② .list-header__right 满宽 344 + margin auto,回到正中; ③ 右栏每个直接子节点满宽 + text-align:center + justify-content:center 双通路(块级文本 / flex 行都能命中), 其中 .up-info 的头像+名字+关注按钮、.desc 的 5 个统计项 都是"整组居中",组内相对位置不变。 只写 margin-left/right: auto,**不写 margin 简写**, 以保住 .up-info 的 mt13/mb10 与 .desc 的 mb12 这些纵向节奏。 ------------------------------------------------------------ */ /* ⑦ 头部整块(标题 / UP 行 / 统计 / 简介)左右各留 8px(v131.59) 探针 09-29_10-24-31 实测(视口 360): .container[344x29700] left=8 ← 8..352,容器本身距屏幕已 8px > .list[344x29643] left=8 > .list-header[344x268] **left=8 宽 344** ← 与容器同宽 > .list-header__right[344x228] left=8 > .title / .up-info / .desc / .introduce 全是 344 即头部内容 344 宽 = 容器 344 宽 -> **距容器左右边距 = 0**, 标题、UP 行、5 个统计项、简介统统顶到容器边上。 改法:.list-header 外框保持 344(仍占 8..352), 只加 padding-left/right: 8px + box-sizing: border-box, 内容盒自然收成 328(占 16..344)—— 距容器左右各 8px。 ⚠ 只写 padding-left/right,**不写 padding 简写**, 以保住站内 .list-header 原本的 pt20 / pb20 纵向节奏。 下面的 .list-header__right 与其子节点都是 width:100%, 会自动继承这 328 —— 不需要逐个改数字。 注意:只缩头部。**章节列表 .list-content 仍是 344(8..352)**, 这是 v131.55 为了和全站其它页对齐才去掉的内边距,本轮不动。---- */ body.bili-opus-page .list > .list-header { display: block !important; width: 100% !important; max-width: 100% !important; padding-left: 8px !important; padding-right: 8px !important; box-sizing: border-box !important; text-align: center !important; } /* 高特异性兜底(v131.36 套路):完整链路压过去, 防站内 padding:0 用同权重 !important 顶回来 */ body.bili-opus-page #app > .container > .list > .list-header { padding-left: 8px !important; padding-right: 8px !important; box-sizing: border-box !important; } /* PC 版左侧封面位:手机站没渲染内容,但占位把右栏推偏了 30px */ body.bili-opus-page .list > .list-header > .list-header__left { display: none !important; width: 0 !important; min-width: 0 !important; margin: 0 !important; padding: 0 !important; } body.bili-opus-page .list > .list-header > .list-header__right { display: block !important; width: 100% !important; max-width: 100% !important; min-width: 0 !important; margin-left: auto !important; margin-right: auto !important; padding-left: 0 !important; padding-right: 0 !important; box-sizing: border-box !important; float: none !important; text-align: center !important; } /* 右栏每一行:满宽 + 居中(含探针漏掉的那一行) */ body.bili-opus-page .list-header__right > * { width: 100% !important; max-width: 100% !important; min-width: 0 !important; margin-left: auto !important; margin-right: auto !important; box-sizing: border-box !important; float: none !important; text-align: center !important; justify-content: center !important; } /* 5 个统计项:本身按内容宽,只补文字居中; flex 场景下不许被拉伸,否则"整组居中"会变成"每项等分铺满" v131.55 修正:这里原来写的 flex: 0 0 auto(禁止收缩)是错的。 探针 09-29_09-04-35 实测后果 —— 5 项各取自然单行宽 67 / 75 / 74 / 59 / 105,合计 380 + 间隙 ≈ 412 > 344, 整行从 left=-34 一直伸到 385,两端都戳出屏幕(视口只有 360)。 改成允许换行:单项仍不收缩(保持一行不断字), 但父容器 .desc 开 flex-wrap,装不下就整项折到第二行。 */ body.bili-opus-page .list-header__right .desc > * { flex: 0 0 auto !important; float: none !important; width: auto !important; max-width: 100% !important; height: auto !important; min-height: 0 !important; line-height: normal !important; white-space: nowrap !important; text-align: center !important; justify-content: center !important; } /* UP 行同理:头像 / 名字 / 关注按钮保持原尺寸,整组居中 v131.57:补 flex-wrap,超长昵称 + 按钮装不下时整组折行,不再溢出屏幕 */ body.bili-opus-page .list-header__right .up-info { flex-wrap: wrap !important; row-gap: 6px !important; column-gap: 4px !important; } body.bili-opus-page .list-header__right .up-info > * { flex: 0 0 auto !important; } /* 高特异性兜底(v131.36 套路):完整链路压过去, 防站内 PC 的定宽 294 / 275 用同权重 !important 顶回来 */ body.bili-opus-page #app > .container > .list > .list-header > .list-header__right { display: block !important; width: 100% !important; max-width: 100% !important; margin-left: auto !important; margin-right: auto !important; padding-left: 0 !important; padding-right: 0 !important; } body.bili-opus-page #app > .container > .list > .list-header > .list-header__right > .title, body.bili-opus-page #app > .container > .list > .list-header > .list-header__right > .up-info, body.bili-opus-page #app > .container > .list > .list-header > .list-header__right > .desc { width: 100% !important; max-width: 100% !important; min-width: 0 !important; text-align: center !important; justify-content: center !important; } /* ============================================================ ========== 专栏文集页:整页手机化(v131.55) ========== 探针 09-29_09-04-35("含隐藏"全量版,7629 节点,body 360x32219) 逐处实测与对策如下。 ------------------------------------------------------------ */ /* ---- ① 头部统计行「233篇专栏 974595个字 5752次阅读 9-16更新 文集号:1018845」 探针实测(v131.54 之后): .desc[344x10] left=8 mb=12 > div[67x10] left=-34 233篇专栏 ← 已经戳到屏幕外 > div[75x10] left=42 974595个字 > div[74x10] left=127 5752次阅读 > div[59x10] left=211 9-16更新 > div[105x10] left=280 文集号:1018845 ← 右端 385 > 360 5 项自然宽合计 380,加间隙约 412,远超 344,所以两端都溢出。 对策:父容器开 flex-wrap,整项折行(不在词中间断), 两行各自居中。实测会分成 4 项 + 1 项两行。---- */ body.bili-opus-page .list-header__right > .desc { display: flex !important; flex-direction: row !important; flex-wrap: wrap !important; justify-content: center !important; align-items: center !important; align-content: center !important; column-gap: 8px !important; row-gap: 4px !important; width: 100% !important; max-width: 100% !important; min-width: 0 !important; height: auto !important; min-height: 0 !important; max-height: none !important; overflow: visible !important; box-sizing: border-box !important; } /* ---- ② 文集简介「你我均是不谙世事的幼兽……」默认全文展开 + 去掉展开按键 探针实测: .introduce[344x38] top=230 > .fold-text[344x19] ovf=hidden ← 只露 1 行(19px) > .unfold-btn[344x19] text=展开 .fold-text 是"全文已在 DOM 里、靠 overflow:hidden 裁成一行"的 典型折叠组件(高度 19 = 单行),所以纯 CSS 放开高度即可展开全文, 不需要 JS 去点那个按键。 按键用 > *:not(.fold-text) 通配隐藏 —— 展开态它会变成「收起」, 类名可能变,通配才不会被漏掉。---- */ body.bili-opus-page .list-header__right .introduce { width: 100% !important; max-width: 100% !important; height: auto !important; min-height: 0 !important; max-height: none !important; overflow: visible !important; box-sizing: border-box !important; } body.bili-opus-page .list-header__right .introduce .fold-text { display: block !important; width: 100% !important; max-width: 100% !important; min-width: 0 !important; height: auto !important; min-height: 0 !important; max-height: none !important; overflow: visible !important; -webkit-line-clamp: unset !important; line-clamp: unset !important; text-overflow: clip !important; white-space: normal !important; word-break: break-word !important; overflow-wrap: anywhere !important; line-height: 1.7 !important; box-sizing: border-box !important; } body.bili-opus-page .list-header__right .introduce > *:not(.fold-text) { display: none !important; } /* 高特异性兜底(v131.36 套路) */ body.bili-opus-page #app > .container > .list > .list-header > .list-header__right > .introduce > .fold-text { height: auto !important; max-height: none !important; overflow: visible !important; -webkit-line-clamp: unset !important; } /* ---- ③ 章节列表:序号与正文贴死 + 右侧封面整块跑到屏幕外 探针实测(单章): .list-content[344x31854] left=8 padding 20(左右各 20) > div[304x31814] left=28 > .list-content-item[304x137] left=28 pt=20 ├ .list-content-item-index[13x117] left=28 序号「1」 └ .list-content-item-container[304x117] left=41 ← 304 定宽 ├ .__left[304x117] left=41 │ ├ .title[304x29] ovf=hidden │ │ └ .title-text[79x26](长标题时实测 378 宽,被父级裁掉) │ ├ .desc[304x22] mt=5 ovf=hidden(章节摘录,1 行) │ └ .info-bar[304x24] mt=16(分类 / 阅读 / 点赞 / 评论) └ .__right[117x117] **left=365** ← 视口只有 360,整块在屏幕外 两个硬伤: a) 序号 13 宽结束于 41,正文正好从 41 起 —— 间隙 = 0,贴死; b) 13(序号) + 304(正文定宽) = 317 > 304(行宽),整行向右溢出 13, 连带把封面顶到 left=365 屏幕外;封面本身在窄屏也没意义。 对策: · .list-content 去掉左右 20 内边距 -> 行宽 304 变 344,与头部对齐 (首末距屏幕边缘都是 8px,和全站其它页一致) · 行改 flex,序号占固定 36px 列并居中(见下方 ⑥), 正文 flex:1 吃掉剩余宽度、min-width:0 允许收缩 · 封面 .__right 直接 display:none(顺带省掉 233 张懒加载图) · 长标题不再被硬裁:宽度收回 100% + 单行省略号 ---- */ body.bili-opus-page .list > .list-content { padding-left: 0 !important; padding-right: 0 !important; width: 100% !important; max-width: 100% !important; box-sizing: border-box !important; } body.bili-opus-page .list > .list-content > div { width: 100% !important; max-width: 100% !important; min-width: 0 !important; margin: 0 !important; padding: 0 !important; box-sizing: border-box !important; } body.bili-opus-page .list-content-item { display: flex !important; flex-direction: row !important; flex-wrap: nowrap !important; align-items: flex-start !important; justify-content: flex-start !important; /* ⑥ 序号列自带 36px(含与正文的视觉间距),所以行间距归零, 这样正文左边缘恒为 44,不随序号位数变化 */ gap: 0 !important; column-gap: 0 !important; width: 100% !important; max-width: 100% !important; min-width: 0 !important; box-sizing: border-box !important; } /* ---- ⑥ 章节序号:两位数以上紧贴左边缘 -> 在剩余宽度内居中(v131.58) 探针 09-29_10-24-31 实测(视口 360,行 left=8 / 行宽 344): 序号 1 位:.list-content-item-index[13x29] left=8 正文 left=44 序号 2 位: [26x29] left=8 正文 left=44 序号 3 位: [39x29] left=8 正文 **left=57** 数字是**全角**字形(13px 字号 -> 每字符 13px 宽): 1 位 13px、2 位 26px、3 位 39px。 原写法 min-width:26 + text-align:right 的后果: · 2 位数:26px 正好填满 26px 的列,左边距 = 0 -> 紧贴容器左边缘; · 3 位数:39 > 26,flex 项目被撑宽 13px, 连带把正文从 left=44 顶到 left=57 —— 前 99 章和后面的章节对不齐。 改法(纯 CSS): · 整行 gap 归零,序号列**锁死 36px**(flex 0 0 36px + min/max 同值), 8 + 36 = 44,正文左边缘在任何位数下都稳定在 44,不再左右跳动; · 序号 text-align:center,数字在这 36px 里居中,左右自然留出空隙: 1 位 13px -> 两侧各 11.5px 2 位 26px -> 两侧各 5px(原来左侧 0,这就是"紧贴"的根因) 3 位 39px -> 见下 · 3 位数 39px 仍略大于 36px,两道保险把它压进去: a) font-size 13 -> 12px,全角 3 位降到 36px,刚好装下; b) 指定西文字体族,数字走半角字形(3 位约 20px), 即使 a) 被站内样式顶回也依然宽松; 两道都命中时也不会显得过小 —— 序号本就是辅助信息, 比正文标题(约 15px)略小才符合层级。 · overflow:visible + white-space:nowrap:极端情况下宁可两侧等宽溢出, 也不让数字被裁掉半截或把正文挤走。---- */ body.bili-opus-page .list-content-item-index { flex: 0 0 36px !important; width: 36px !important; min-width: 36px !important; max-width: 36px !important; height: auto !important; align-self: flex-start !important; /* 与 .title 的 29px 行高对齐,让序号和章节标题在同一水平线上 */ line-height: 29px !important; text-align: center !important; font-size: 12px !important; font-family: 'Helvetica Neue', Helvetica, Arial, sans-serif !important; white-space: nowrap !important; overflow: visible !important; margin: 0 !important; padding: 0 !important; box-sizing: border-box !important; } /* 高特异性兜底(v131.36 套路):完整链路压过去, 防站内的 width:auto / min-width 用同权重 !important 顶回来 */ body.bili-opus-page .list > .list-content .list-content-item > .list-content-item-index { flex: 0 0 36px !important; width: 36px !important; min-width: 36px !important; max-width: 36px !important; text-align: center !important; font-size: 12px !important; overflow: visible !important; } body.bili-opus-page .list > .list-content .list-content-item { gap: 0 !important; column-gap: 0 !important; } body.bili-opus-page .list-content-item-container { flex: 1 1 auto !important; width: auto !important; max-width: 100% !important; min-width: 0 !important; margin: 0 !important; box-sizing: border-box !important; } body.bili-opus-page .list-content-item-container__left { width: 100% !important; max-width: 100% !important; min-width: 0 !important; box-sizing: border-box !important; } /* 每章右侧封面:按要求整块隐藏(本来就在屏幕外,留着只会撑破行宽) */ body.bili-opus-page .list-content-item-container__right { display: none !important; width: 0 !important; min-width: 0 !important; margin: 0 !important; padding: 0 !important; } body.bili-opus-page .list-content .title { width: 100% !important; max-width: 100% !important; min-width: 0 !important; box-sizing: border-box !important; } body.bili-opus-page .list-content .title > .title-text { display: block !important; width: 100% !important; max-width: 100% !important; min-width: 0 !important; overflow: hidden !important; text-overflow: ellipsis !important; white-space: nowrap !important; box-sizing: border-box !important; } /* 章节摘录:由 1 行放开到 3 行(v131.56) 探针实测 .desc[288x22] ovf=hidden —— 单行 22px 硬裁。 这里改成 -webkit-box + line-clamp:3,配合 height:auto 让第三行露出来, 第 4 行起才省略号截断。 */ body.bili-opus-page .list-content .desc { display: -webkit-box !important; -webkit-box-orient: vertical !important; -webkit-line-clamp: 3 !important; line-clamp: 3 !important; overflow: hidden !important; text-overflow: ellipsis !important; white-space: normal !important; word-break: break-word !important; overflow-wrap: anywhere !important; line-height: 1.5 !important; height: auto !important; max-height: none !important; width: 100% !important; max-width: 100% !important; min-width: 0 !important; box-sizing: border-box !important; } /* 高特异性兜底(v131.36 套路):压过站内同权重 !important 的单行裁切 */ body.bili-opus-page .list > .list-content .list-content-item .list-content-item-container .list-content-item-container__left > .desc { display: -webkit-box !important; -webkit-box-orient: vertical !important; -webkit-line-clamp: 3 !important; line-clamp: 3 !important; overflow: hidden !important; white-space: normal !important; height: auto !important; max-height: none !important; } /* 章节统计行「原创连载 / 阅读 / 点赞 / 评论」整行隐藏(v131.56) 探针实测 .info-bar[288x24] mt=16,是 .__left 的最后一个子节点, display:none 后行高自然收缩,序号与标题的相对位置不受影响。 */ body.bili-opus-page .list-content-item .info-bar, body.bili-opus-page .list-content .list-content-item .list-content-item-container__left > .info-bar { display: none !important; visibility: hidden !important; width: 0 !important; height: 0 !important; min-height: 0 !important; margin: 0 !important; padding: 0 !important; overflow: hidden !important; } /* ---- ④ 顶部 #BiliMainHeader:一个 64px 的空壳 探针实测:#BiliMainHeader[344x64] top=8 bottom=72,无文字, 里面唯一的 .bili-header.bili-header--mini.bili-header--fixed 已经被脚本压成 [0x0] (hidden)。 即这 64px 是纯空白,手机站直接收掉,正文上移 64px。---- */ body.bili-opus-page #BiliMainHeader { height: 0 !important; min-height: 0 !important; max-height: 0 !important; padding: 0 !important; margin: 0 !important; overflow: hidden !important; } /* ---- ⑤ 取消关注确认弹窗「您确认要取消关注吗(゚Д゚≡゚д゚)!? 取消 确定」 整块跑到屏幕右外侧(v131.57) 探针 09-29_10-24-31 实测(视口 360): .dialog[344x29700] pos=absolute top=8 left=8 ← 蒙层,铺满整页 > .box[360x173] pos=**fixed** z=9999 top=320 **left=144** ← 144+360 = 504,右边 144px 全在屏幕外 > .text[360x23] top=370 left=144 > .buttons[360x40] top=423 left=144 > button.cancel[120x40] left=174 > button.confirm[120x40] left=354 ← 右端 474,戳出屏幕 根因:.box 是 PC 版的定宽 360 弹窗,用固定 left 偏移定位 (144 ≈ 40%×360),在 360 视口下既没居中也没收缩,右半边被裁掉。 改法(纯 CSS,不动任何 JS): · 蒙层 .dialog 改 fixed + inset:0,跟随视口而不跟着整页滚; · .box 用 left:50% + translate(-50%,-50%) 做视口正中定位, 同时把定宽 360 换成 max-width: calc(100vw - 16px), 窄屏(如 320)自动再收,永不越界; · 盒内留左右 16px 内边距,文案与按钮不会贴边; · .text / .buttons 收回 100% 满宽,跟着新宽度走; · 两个按钮加 flex-wrap,极端窄屏时上下排列而不是横向溢出。 注:translate 与 left/top 一起写,-50% 以自身尺寸为基准, 站内联样式即使改了 left 也不会破坏居中。---- */ body.bili-opus-page .dialog, body.bili-space-page .dialog { position: fixed !important; top: 0 !important; left: 0 !important; right: 0 !important; bottom: 0 !important; width: 100vw !important; max-width: 100vw !important; height: 100vh !important; max-height: 100vh !important; margin: 0 !important; padding: 0 !important; box-sizing: border-box !important; overflow: hidden !important; } body.bili-opus-page .dialog > .box, body.bili-space-page .dialog > .box { position: fixed !important; top: 50% !important; left: 50% !important; right: auto !important; bottom: auto !important; transform: translate(-50%, -50%) !important; width: 344px !important; max-width: calc(100vw - 16px) !important; min-width: 0 !important; height: auto !important; min-height: 0 !important; max-height: calc(100vh - 32px) !important; margin: 0 !important; padding-left: 16px !important; padding-right: 16px !important; box-sizing: border-box !important; overflow: visible !important; } body.bili-opus-page .dialog > .box > .text, body.bili-space-page .dialog > .box > .text { width: 100% !important; max-width: 100% !important; min-width: 0 !important; height: auto !important; margin-left: 0 !important; margin-right: 0 !important; box-sizing: border-box !important; text-align: center !important; word-break: break-word !important; overflow-wrap: anywhere !important; } body.bili-opus-page .dialog > .box > .buttons, body.bili-space-page .dialog > .box > .buttons { display: flex !important; flex-direction: row !important; flex-wrap: wrap !important; justify-content: center !important; align-items: center !important; gap: 12px !important; column-gap: 12px !important; row-gap: 12px !important; width: 100% !important; max-width: 100% !important; min-width: 0 !important; height: auto !important; box-sizing: border-box !important; } body.bili-opus-page .dialog > .box > .buttons > button, body.bili-space-page .dialog > .box > .buttons > button { flex: 0 1 120px !important; width: 120px !important; max-width: calc(50% - 6px) !important; min-width: 0 !important; height: 40px !important; margin: 0 !important; box-sizing: border-box !important; } /* 高特异性兜底(v131.36 套路):完整链路压过去, 防站内的定宽 360 / 固定 left 用同权重 !important 顶回来 */ body.bili-opus-page #app > .container > .dialog > .box, body.bili-space-page #app > .container > .dialog > .box { position: fixed !important; top: 50% !important; left: 50% !important; transform: translate(-50%, -50%) !important; width: 344px !important; max-width: calc(100vw - 16px) !important; box-sizing: border-box !important; } /* ============================================================ ========== 直播间页(live.bilibili.com/房间号) ========== ============================================================ 探针 bili_probe_2026-09-30_08-03-19 实测(视口 360): body.supportWebp > div.live-room-app[360x4458] > main.app-content(padding-top 74px) > div.link-navbar-ctnr (PC 顶部导航, fixed z=1000, h64) > div.app-body[980x4384] > section.player-and-aside-area[980x428] > #player-ctnr[668x428] > #head-info-vm[668x52] ← 主播信息条 > .fullscreen-container-paddingbox[668x376] (padding-top 375.75px) > #fullscreen-container (absolute) > .player-section[668x292] > #live-player-ctnr > #live-player > video > #gift-control-vm[668x84] ← 礼物栏 > #aside-area-vm (absolute left=680, w300) > #rank-list-vm[300x96] ← 排行榜 > .chat-history-panel[300x223] ← ★评论区(聊天区) > #chat-control-panel-vm[300x109] ← 发送框 > #sections-vm[980x3944] ← 动态/公告 > footer.link-footer > #sidebar-vm (右下角悬浮 实验室/关注) > #room-background-vm (房间背景图) 目标:整页只剩「播放器」+「评论区」两块,评论区落到播放器正下方。 · 播放器:3px #00aeec 边框 + 12px 圆角 + 左右各 8px + 顶部 36px + 16:9 —— 与番剧页 #bilibili-player-wrap 的数值逐项对齐(同一套 calc 公式)。 · 评论区:#aside-area-vm 由 absolute 改回 static,自然排到 #player-ctnr 之后。 全文纯 CSS,JS 只负责给 body 打上 bili-live-room-page(页面判定)。---- */ html:has(body.bili-live-room-page), body.bili-live-room-page { background: #ffffff !important; width: 100% !important; max-width: 100vw !important; min-width: 0 !important; overflow-x: hidden !important; padding-top: 0 !important; margin: 0 !important; } /* ---- 1) 除播放器 + 评论区外,其余板块全部隐藏 ---- */ body.bili-live-room-page #room-ssr-vm, body.bili-live-room-page .link-navbar-ctnr, body.bili-live-room-page .link-navbar-wrap, body.bili-live-room-page nav.link-navbar, body.bili-live-room-page #room-background-vm, body.bili-live-room-page #head-info-vm, body.bili-live-room-page #gift-control-vm, body.bili-live-room-page #rank-list-vm, body.bili-live-room-page #rank-list-ctnr-box, body.bili-live-room-page #gift-screen-animation-vm, body.bili-live-room-page #guard-popup, body.bili-live-room-page #sections-vm, body.bili-live-room-page footer.link-footer, body.bili-live-room-page #sidebar-vm, /* 播放器内的 PK / 礼物菜单 / 贴纸 / 连麦 等覆盖层 */ body.bili-live-room-page #universal-pk-vm, body.bili-live-room-page #gift-menu-vm, body.bili-live-room-page #interactive-sticker-vm, body.bili-live-room-page #multi-voice-index, /* v131.95:连麦(语音连线)入口条 探针实测 #link-mic-vm > .lin-mic-entrance [270x40], 浮在播放器正中(top=134,即画面垂直居中偏上), 上面写着「吃西瓜的夏冰 与主播通话中」,直接压在视频画面上。 它挂在 #businessContainerElement / .web-player-inject-wrap 里, 那两层只被设了 pointer-events:none(防挡点击),文字依然可见。 整条挂掉:父 #link-mic-vm + 子 .lin-mic-entrance 双写, 外加同级可能的 .link-mic-* 变体,纯 CSS 隐藏。 */ body.bili-live-room-page #link-mic-vm, body.bili-live-room-page #link-mic-vm .lin-mic-entrance, body.bili-live-room-page #link-mic-vm .link-mic-entrance, body.bili-live-room-page .lin-mic-entrance, body.bili-live-room-page .link-mic-entrance, body.bili-live-room-page .web-player-icon-roomStatus { display: none !important; visibility: hidden !important; width: 0 !important; height: 0 !important; min-height: 0 !important; padding: 0 !important; margin: 0 !important; overflow: hidden !important; } /* 兜底:main 下凡是「不是 .app-body」的一律不显示(导航条 / 页脚 / 未知挂件) */ body.bili-live-room-page main.app-content > *:not(.app-body) { display: none !important; visibility: hidden !important; height: 0 !important; margin: 0 !important; padding: 0 !important; overflow: hidden !important; } /* ---- 2) 容器链拉直:980 定宽 -> 满宽,宽屏收窄并居中 ---- */ body.bili-live-room-page main.app-content, body.bili-live-room-page .app-body, body.bili-live-room-page section.player-and-aside-area { width: 100% !important; max-width: 820px !important; min-width: 0 !important; height: auto !important; min-height: 0 !important; margin: 0 auto !important; padding: 0 !important; box-sizing: border-box !important; overflow: visible !important; position: relative !important; float: none !important; left: auto !important; right: auto !important; } /* ---- 3) 播放器:边框 / 边距 / 比例 与番剧页完全一致 ---- */ body.bili-live-room-page #player-ctnr { width: 100% !important; max-width: 100% !important; min-width: 0 !important; height: auto !important; min-height: 0 !important; padding: 0 8px !important; /* 与番剧 .plp-player 一致:左右各 8px */ margin: 36px auto !important; /* 与番剧 .plp-player 一致:上下各 36px */ box-sizing: border-box !important; overflow: visible !important; position: relative !important; float: none !important; left: auto !important; right: auto !important; } /* 站内 JS 按 PC 宽度算出的 padding-top: 375.75px(= 668 * 9/16)用来撑 16:9, 窄屏下必须顶掉,改由下方 #fullscreen-container 自己定高 */ body.bili-live-room-page .fullscreen-container-paddingbox { width: 100% !important; max-width: 100% !important; height: auto !important; min-height: 0 !important; padding: 0 !important; margin: 0 !important; box-sizing: border-box !important; } /* 与番剧页 #bilibili-player-wrap 同一套数值: 宽 100%(含 3px 边框)· 高 (100vw - 22px) * 9/16 + 6px —— 100vw - 22px = 360 - 16(左右 8px) - 6(左右边框 3px) = 338,即内容区宽 */ body.bili-live-room-page #fullscreen-container { position: relative !important; width: 100% !important; max-width: 100% !important; height: calc((100vw - 22px) * 9 / 16 + 6px) !important; max-height: calc((100vw - 22px) * 9 / 16 + 6px) !important; min-height: 0 !important; padding: 0 !important; margin: 0 auto !important; border: 3px solid #00aeec !important; border-radius: 12px !important; box-shadow: 0 4px 16px rgba(0, 174, 236, 0.25) !important; overflow: hidden !important; box-sizing: border-box !important; } /* ★★★ 播放器内部整条链:height:100% 跟随父级,消除次像素缝隙 ★★★ v131.93 重写:旧版用显式 calc 给内层链定高,与外层 calc 产生 两份独立取整,左/底部差出约 1px 缝隙。当时用 scale(1.012) 遮盖, 但会裁掉视频边缘 1~2px 内容。 新版改法(纯 CSS,不裁不拉伸): 内层链统一用 height:100% 跟随 #fullscreen-container 的内容盒, 只有一份取整(外层的 calc),不存在两份独立取整的差值, 视频严格铺满容器内容区,左/底部缝隙彻底消失。 站内 JS 行内 !important 仍会给 .player-section 写错误高度 (容器高 - 礼物栏 84px),CSS 压不过 → 由 JS applyLivePlayerSize 用同样的 100% 行内 !important 顶掉(后写覆盖先写)。 ⚠ video 的 transform 必须是 none(不能有 scale), 否则画面会被轻微放大、边缘被 overflow:hidden 裁掉。 ⚠ object-fit: contain 保证视频原始比例不变形。 ---- */ /* ★★★ v131.94:直播间「播放器内部下方 84px 空档 / 画面被压扁」根治 ★★★ 探针实测(bili_probe_2026-09-30_12-43-30): #fullscreen-container [344x196](3px 边框 → 内容盒 338x190) > .player-section [338x106] ← 只有 106,应为 190 106 = 190 - 84 —— 站内 JS 一直按「容器高 - 礼物栏 84px」 给 .player-section 写**行内**几何值(礼物栏早已被隐藏,这 84px 却仍被扣掉),视频被压成扁条、下方空出一条黑边。 行内 !important 样式表压不过(它连 min/max-height 一起写, 所以写 100% 的 min-height 也救不回来),因此不跟它抢属性: display:contents 让 .player-section 根本不生成盒子 —— 元素一旦不生盒,写在它身上的全部几何声明(height / min-height / max-height / top / bottom…)无论行内与否一律失效。 #live-player-ctnr 于是直接以 #fullscreen-container 为定位父级, height:100% = 内容盒 190px,画面满铺、零裁剪、零拉伸, 且只剩外层 calc 一份取整,v131.93 消灭的次像素缝隙不会回归。 (下方内层链规则里的 min-height:100% 与 JS 的 stripPlayerSectionInline 分别作为二、三道保险。) */ body.bili-live-room-page #fullscreen-container .player-section { display: contents !important; } body.bili-live-room-page #fullscreen-container .player-section, body.bili-live-room-page #live-player-ctnr, body.bili-live-room-page #live-player-ctnr > .h-100.p-relative, body.bili-live-room-page #live-player, body.bili-live-room-page #live-player video { position: absolute !important; top: 0 !important; left: 0 !important; width: 100% !important; max-width: 100% !important; height: 100% !important; min-height: 100% !important; max-height: 100% !important; margin: 0 !important; padding: 0 !important; border: none !important; border-radius: 0 !important; transform: none !important; box-sizing: border-box !important; } body.bili-live-room-page #live-player video { object-fit: contain !important; background-color: #000 !important; } /* 弹幕层:保留,但压回播放器范围内(站内给它加了 15° 旋转 transform,会溢出) */ body.bili-live-room-page #live-player .web-player-danmaku, body.bili-live-room-page #live-player .danmaku-item-container { position: absolute !important; top: 0 !important; left: 0 !important; width: 100% !important; height: 100% !important; overflow: hidden !important; z-index: 10 !important; } /* 业务注入层(PK / 礼物菜单 / 贴纸等都挂在它下面)已全部隐藏, 留着会是一张盖在播放器上的透明膜,拦掉播放器的点击,直接放行指针事件 */ body.bili-live-room-page #live-player .web-player-inject-wrap, body.bili-live-room-page #businessContainerElement { pointer-events: none !important; overflow: hidden !important; } /* ---- 4) 评论区:从右侧 absolute 挪到播放器正下方 ---- */ body.bili-live-room-page #aside-area-vm { position: static !important; width: 100% !important; max-width: 100% !important; min-width: 0 !important; height: auto !important; min-height: 0 !important; padding: 0 8px !important; /* 与播放器左右 8px 对齐 */ margin: 8px auto 0 !important; /* 距播放器 8px */ box-sizing: border-box !important; overflow: visible !important; float: none !important; top: auto !important; left: auto !important; right: auto !important; touch-action: pan-y !important; /* v131.96:纵向手势留给页面滚动 */ } /* ★★★ v131.97:聊天区「定高 + 内部滚动」,页面不再需要滚动 ★★★ 上一版(v131.96)改成 height:auto + overflow:visible 让聊天内容参与 页面排版,结果聊天越滚越长、整页无限往屏幕外延伸,而手指落在聊天区 依然纹丝不动 —— 说明聊天区上有东西把纵向手势吃掉了(站内为聊天区 绑的手势逻辑 / touch-action),页面滚动压根没被触发。 换个思路:既然手势在聊天区里必然被聊天区接管,那就让**聊天区自己 成为一个好用的滚动容器**,同时把它限死在屏内: · .chat-history-panel 定高 calc(100dvh - 284px) —— 284px = 顶部 36 + 播放器 196 + 播放器上下 margin 36x2 实测 #aside-area-vm 从 top=268 起算,再留 16px 底边距。 这样「播放器 + 聊天区」总高恒 ≤ 一屏,页面本身不再产生滚动, 聊天内容也就永远不会溢出到屏幕外。想看历史就在聊天区里滑。 · #chat-history-list 恢复 overflow-y:auto,由它承载滚动; · overscroll-behavior:contain —— 聊天区滑到头不要把整页也拽动, 避免"滑聊天区时页面跟着抽"的连带感; · transform:none —— 站内平滑滚动会给列表加 translateY, 会把整块内容平移出可视区; · touch-action:pan-y 覆盖聊天区整棵子树 —— 站内若给其中某层 写了 touch-action:none / 绑了手势,纵向手势会被彻底掐死, 这里逐层强制把纵向手势交还给浏览器。 另配 JS bindLiveChatScroll:钉住列表高度 + 手势兜底。 */ body.bili-live-room-page .chat-history-panel { width: 100% !important; max-width: 100% !important; /* v131.99:284 → 304,多留 36px 底距(面板顶距 268 + 36 = 304) */ height: calc(100vh - 304px) !important; height: calc(100dvh - 304px) !important; min-height: 120px !important; max-height: calc(100vh - 304px) !important; max-height: calc(100dvh - 304px) !important; padding: 0 !important; margin: 0 !important; background: #f6f7f8 !important; border-radius: 12px !important; overflow: hidden !important; box-sizing: border-box !important; touch-action: pan-y !important; overscroll-behavior: contain !important; } body.bili-live-room-page #chat-history-list { width: 100% !important; max-width: 100% !important; height: 100% !important; min-height: 0 !important; max-height: 100% !important; padding: 6px 8px !important; margin: 0 !important; overflow-x: hidden !important; overflow-y: auto !important; overscroll-behavior: contain !important; -webkit-overflow-scrolling: touch !important; transform: none !important; touch-action: pan-y !important; box-sizing: border-box !important; } /* 聊天区整棵子树:纵向手势一律放行,谁也不许掐 */ body.bili-live-room-page #aside-area-vm *, body.bili-live-room-page .chat-history-panel * { touch-action: pan-y !important; } /* 盖在聊天区上方的浮层直接放行指针事件: 探针实测 .chat-overlay-layer [344x67] absolute z=10 压在聊天区顶部, #welcome-area-bottom-vm [344x83](带 canvas 欢迎动画)也悬在同一片区域。 手指一落在聊天区上半部分就打在这些浮层上,手势自然传不到列表。 */ body.bili-live-room-page .chat-overlay-layer, body.bili-live-room-page #welcome-area-bottom-vm, body.bili-live-room-page #welcome-item-video, body.bili-live-room-page .chat-overlay-layer *, body.bili-live-room-page #welcome-area-bottom-vm * { pointer-events: none !important; } body.bili-live-room-page #chat-items, body.bili-live-room-page .chat-item { width: 100% !important; max-width: 100% !important; box-sizing: border-box !important; overflow-wrap: break-word !important; word-break: break-word !important; } /* ★★★ v131.96:隐藏「发送框」与它上方那一行「XX 进入直播间」★★★ 探针实测(bili_probe_2026-09-30_13-41-13)聊天区纵向排布: #chat-history-list 103 ~ 691 #brush-prompt [344x20] 691 ~ 711 ← 「南城浅忆萧 进入直播间」 #chat-control-panel-vm [344x109] 711 ~ 820 ← 输入区(图标行 + 输入框 + 发送) 手机端只用来看直播/弹幕,这两块纯占位,整条摘掉: · #chat-control-panel-vm 整块(含 #control-panel-ctnr-box / .control-panel-icon-row / .chat-input-ctnr / textarea / 发送按钮) · #brush-prompt(进入直播间提示行,z=19 浮在聊天区与发送框之间) */ body.bili-live-room-page #chat-control-panel-vm, body.bili-live-room-page #control-panel-ctnr-box, body.bili-live-room-page .control-panel-icon-row, body.bili-live-room-page .chat-input-ctnr, body.bili-live-room-page .chat-input-area, body.bili-live-room-page #brush-prompt, body.bili-live-room-page .brush-prompt { display: none !important; visibility: hidden !important; width: 0 !important; height: 0 !important; min-height: 0 !important; max-height: 0 !important; padding: 0 !important; margin: 0 !important; overflow: hidden !important; } /* ★★★ v132.00:点聊天内容弹出的「按键面板」不再弹出 ★★★ 探针实测(bili_probe_2026-09-30_14-39-43,点击一条弹幕后): .danmaku-menu.p-fixed.ts-dot-4 [148x212] position:fixed z=30,挂在 .chat-history-panel 下 内含:用户名 / 去 TA 的个人空间 / @TA / 屏蔽发送者 / 举报选中弹幕 / 航海之旅 手机端这些操作一个都用不上(也点不准),面板还会盖住画面。 纯 CSS 整块隐藏即可;触发源 .open-menu 一并去掉 pointer 样式, 点击不再有"可点"的手型,也不会再有面板冒出来。 */ body.bili-live-room-page .danmaku-menu, body.bili-live-room-page .danmaku-menu.p-fixed, body.bili-live-room-page #aside-area-vm .danmaku-menu, body.bili-live-room-page .chat-history-panel .danmaku-menu { display: none !important; visibility: hidden !important; width: 0 !important; height: 0 !important; min-height: 0 !important; max-height: 0 !important; padding: 0 !important; margin: 0 !important; overflow: hidden !important; pointer-events: none !important; } body.bili-live-room-page .chat-history-panel .open-menu, body.bili-live-room-page .chat-history-panel .pointer { cursor: default !important; } /* ---- 5) 全屏(原生全屏 / 网页全屏):前面所有约束一律让位 ---- v131.85 引出的两个全屏问题,根因都在"把 16:9 尺寸锁死"这件事上: · 竖屏全屏「顶部没居中 + 左右有边距」 ← #player-ctnr 的 margin:36px auto 与 padding:0 8px 把播放器推离顶部、 左右各留 8px,视频贴不到屏幕边缘,也没垂直居中。 · 横屏全屏「上下被裁掉」 ← #fullscreen-container 及内层被锁成 calc((100vw - 22px) * 9 / 16), 横屏下 100vw 是**长边**,算出的高度远超屏幕高度,上下直接溢出被裁。 全屏时必须把尺寸控制权完整交回站内。 检测由 JS 完成(原生 fullscreenElement / 站内 class / 尺寸启发式), 命中即给 body 打 bili-live-fs。下面这组选择器多一个类,特异性更高, 能覆盖本页前面写下的全部尺寸约束。 播放器直接 fixed + inset:0 硬贴视口四边: 不再猜站内用的是 fixed 还是 absolute,也不依赖父级链是否 100%, 竖屏横屏都保证「贴边 + 完整」。 */ /* html 单独写一条:不给 定高,body 的 height:100% 无从参照。 刻意不与下面 body 那条合并成选择器列表 —— :has() 一旦不被支持, 整组选择器会被一起丢弃,body 那条也会跟着失效。 */ html:has(body.bili-live-room-page.bili-live-fs) { width: 100% !important; height: 100% !important; max-width: none !important; max-height: none !important; padding: 0 !important; margin: 0 !important; overflow: hidden !important; background: #000 !important; } body.bili-live-room-page.bili-live-fs { width: 100% !important; height: 100% !important; max-width: none !important; min-width: 0 !important; max-height: none !important; padding: 0 !important; margin: 0 !important; overflow: hidden !important; background: #000 !important; } body.bili-live-room-page.bili-live-fs .live-room-app, body.bili-live-room-page.bili-live-fs main.app-content, body.bili-live-room-page.bili-live-fs .app-body, body.bili-live-room-page.bili-live-fs section.player-and-aside-area, body.bili-live-room-page.bili-live-fs #player-ctnr, body.bili-live-room-page.bili-live-fs .fullscreen-container-paddingbox { width: 100% !important; height: 100% !important; max-width: none !important; min-width: 0 !important; max-height: none !important; min-height: 0 !important; padding: 0 !important; margin: 0 !important; border: none !important; border-radius: 0 !important; box-shadow: none !important; background: #000 !important; overflow: hidden !important; box-sizing: border-box !important; float: none !important; transform: none !important; } body.bili-live-room-page.bili-live-fs #fullscreen-container { position: fixed !important; top: 0 !important; right: 0 !important; bottom: 0 !important; left: 0 !important; width: 100% !important; height: 100% !important; max-width: none !important; min-width: 0 !important; max-height: none !important; min-height: 0 !important; padding: 0 !important; margin: 0 !important; border: none !important; border-radius: 0 !important; box-shadow: none !important; background: #000 !important; overflow: hidden !important; box-sizing: border-box !important; z-index: 2147483647 !important; } /* 内层链解除 16:9 的 calc 锁,改回跟随父级铺满 */ /* v131.94:同上,原生全屏态也摘掉 .player-section 的盒子 (站内网页全屏同样会扣 84px;这里用 100% 跟满视口) */ body.bili-live-room-page.bili-live-fs #fullscreen-container .player-section { display: contents !important; } body.bili-live-room-page.bili-live-fs #fullscreen-container .player-section, body.bili-live-room-page.bili-live-fs #live-player-ctnr, body.bili-live-room-page.bili-live-fs #live-player-ctnr > .h-100.p-relative, body.bili-live-room-page.bili-live-fs #live-player, body.bili-live-room-page.bili-live-fs #live-player video, body.bili-live-room-page.bili-live-fs #live-player .web-player-danmaku, body.bili-live-room-page.bili-live-fs #live-player .danmaku-item-container { position: absolute !important; top: 0 !important; left: 0 !important; width: 100% !important; height: 100% !important; max-width: none !important; max-height: none !important; min-height: 0 !important; padding: 0 !important; margin: 0 !important; border: none !important; border-radius: 0 !important; transform: none !important; box-sizing: border-box !important; } /* contain 保证横屏下画面完整不裁(cover 会填满但切掉上下) */ body.bili-live-room-page.bili-live-fs #live-player video { object-fit: contain !important; background-color: #000 !important; } /* 全屏时评论区不该再占位 */ body.bili-live-room-page.bili-live-fs #aside-area-vm { display: none !important; visibility: hidden !important; width: 0 !important; height: 0 !important; min-height: 0 !important; margin: 0 !important; padding: 0 !important; overflow: hidden !important; } /* ============================================================ ---- 6) v131.89:站内「网页全屏」body.player-full-win 一律 按**普通态**渲染(纯 CSS 兜底) ---- 退出原生全屏(双击 / 返回键 / ESC)时,站内播放器会自己补一个 player-full-win —— 也就是「网页全屏」:带浏览器地址栏、底部留 84px 礼物栏空档、播放器被写死 668px 定宽。上一版把它当全屏 处理(isLiveFullscreen 命中即铺满视口),于是双击就在 「原生全屏 ↔ 带地址栏的全屏」之间来回跳,永远退不回普通态。 新规则:这个态我们根本不要,见到就当普通态。 · JS:class 一出现立刻摘掉(bindLiveWebFullscreenGuard) · CSS:这里兜底 —— 万一它活了几帧,也强制按普通态排版, 不会出现"带地址栏的全屏" :not(.bili-live-fs) 保证真正的原生全屏不受这组规则影响 (bili-live-fs 只在原生 Fullscreen API 命中时才打)。 ---- */ html:has(body.bili-live-room-page.player-full-win:not(.bili-live-fs)) { width: 100% !important; height: auto !important; max-width: 100vw !important; max-height: none !important; padding: 0 !important; margin: 0 !important; overflow-x: hidden !important; background: #ffffff !important; } body.bili-live-room-page.player-full-win:not(.bili-live-fs) { position: static !important; width: 100% !important; height: auto !important; max-width: 100vw !important; max-height: none !important; padding-top: 0 !important; margin: 0 !important; overflow-x: hidden !important; background: #ffffff !important; } body.bili-live-room-page.player-full-win:not(.bili-live-fs) .live-room-app, body.bili-live-room-page.player-full-win:not(.bili-live-fs) main.app-content, body.bili-live-room-page.player-full-win:not(.bili-live-fs) .app-body, body.bili-live-room-page.player-full-win:not(.bili-live-fs) section.player-and-aside-area { position: relative !important; width: 100% !important; max-width: 820px !important; height: auto !important; min-height: 0 !important; max-height: none !important; margin: 0 auto !important; padding: 0 !important; overflow: visible !important; background: #ffffff !important; box-sizing: border-box !important; float: none !important; left: auto !important; right: auto !important; top: auto !important; bottom: auto !important; } body.bili-live-room-page.player-full-win:not(.bili-live-fs) #player-ctnr { position: relative !important; width: 100% !important; max-width: 100% !important; height: auto !important; min-height: 0 !important; max-height: none !important; padding: 0 8px !important; /* 与普通态一致:左右各 8px */ margin: 36px auto !important; /* 与普通态一致:上下各 36px */ box-sizing: border-box !important; overflow: visible !important; left: auto !important; right: auto !important; top: auto !important; bottom: auto !important; } /* 网页全屏给 #fullscreen-container 的 668px 定宽 / fixed 定位 / 满屏高 全部顶掉,回到普通态的 16:9 + 3px 边框 + 12px 圆角 */ body.bili-live-room-page.player-full-win:not(.bili-live-fs) #fullscreen-container { position: relative !important; top: auto !important; right: auto !important; bottom: auto !important; left: auto !important; width: 100% !important; max-width: 100% !important; height: calc((100vw - 22px) * 9 / 16 + 6px) !important; min-height: 0 !important; max-height: calc((100vw - 22px) * 9 / 16 + 6px) !important; padding: 0 !important; margin: 0 auto !important; border: 3px solid #00aeec !important; border-radius: 12px !important; box-shadow: 0 4px 16px rgba(0, 174, 236, 0.25) !important; z-index: auto !important; background: #000 !important; box-sizing: border-box !important; } /* v131.94:网页全屏(player-full-win)是 84px 空档的重灾区 —— 站内正是为了给礼物栏留位置才扣掉这 84px。按普通态数值顶回。 */ body.bili-live-room-page.player-full-win:not(.bili-live-fs) #fullscreen-container .player-section { display: contents !important; } body.bili-live-room-page.player-full-win:not(.bili-live-fs) #fullscreen-container .player-section, body.bili-live-room-page.player-full-win:not(.bili-live-fs) #live-player-ctnr, body.bili-live-room-page.player-full-win:not(.bili-live-fs) #live-player-ctnr > .h-100.p-relative, body.bili-live-room-page.player-full-win:not(.bili-live-fs) #live-player, body.bili-live-room-page.player-full-win:not(.bili-live-fs) #live-player video { position: absolute !important; top: 0 !important; left: 0 !important; width: 100% !important; max-width: 100% !important; height: 100% !important; min-height: 100% !important; max-height: 100% !important; padding: 0 !important; margin: 0 !important; border: none !important; border-radius: 0 !important; transform: none !important; box-sizing: border-box !important; } /* 评论区:网页全屏会把播放器下的内容全吃掉,这里强制回到播放器正下方 */ body.bili-live-room-page.player-full-win:not(.bili-live-fs) #aside-area-vm { display: block !important; visibility: visible !important; position: static !important; width: 100% !important; max-width: 100% !important; height: auto !important; min-height: 0 !important; max-height: none !important; padding: 0 8px !important; margin: 8px auto 0 !important; box-sizing: border-box !important; overflow: visible !important; float: none !important; top: auto !important; left: auto !important; right: auto !important; } /* ============================================================ ---- 7) v131.90:真·原生全屏的纯 CSS 兜底(不依赖任何 JS class)---- :fullscreen 只有原生 Fullscreen API 才会命中;站内自造的"假全屏" (position:fixed 铺满视口、仍带浏览器地址栏)命中不了。 所以这条规则同时干两件事: · 原生全屏时铺满视口(与第 5 段的 .bili-live-fs 等价,互为备份) · 不在原生全屏时绝不生效 —— 假全屏因此永远走普通态排版 刻意写成独立的一条规则,不与其它选择器并列表: :has() / :fullscreen 万一不被支持,这条被整条丢弃即可, 不会连累同规则里的其它选择器。 ---- */ html:has(body.bili-live-room-page):has(:fullscreen) { width: 100% !important; height: 100% !important; max-width: none !important; max-height: none !important; padding: 0 !important; margin: 0 !important; overflow: hidden !important; background: #000 !important; } body.bili-live-room-page:has(:fullscreen) { width: 100% !important; height: 100% !important; max-width: none !important; min-width: 0 !important; max-height: none !important; padding: 0 !important; margin: 0 !important; overflow: hidden !important; background: #000 !important; } body.bili-live-room-page:has(:fullscreen) .live-room-app, body.bili-live-room-page:has(:fullscreen) main.app-content, body.bili-live-room-page:has(:fullscreen) .app-body, body.bili-live-room-page:has(:fullscreen) section.player-and-aside-area, body.bili-live-room-page:has(:fullscreen) #player-ctnr, body.bili-live-room-page:has(:fullscreen) .fullscreen-container-paddingbox { width: 100% !important; height: 100% !important; max-width: none !important; min-width: 0 !important; max-height: none !important; min-height: 0 !important; padding: 0 !important; margin: 0 !important; border: none !important; border-radius: 0 !important; box-shadow: none !important; background: #000 !important; overflow: hidden !important; box-sizing: border-box !important; float: none !important; transform: none !important; } body.bili-live-room-page:has(:fullscreen) #fullscreen-container { position: fixed !important; top: 0 !important; right: 0 !important; bottom: 0 !important; left: 0 !important; width: 100% !important; height: 100% !important; max-width: none !important; min-width: 0 !important; max-height: none !important; min-height: 0 !important; padding: 0 !important; margin: 0 !important; border: none !important; border-radius: 0 !important; box-shadow: none !important; background: #000 !important; overflow: hidden !important; box-sizing: border-box !important; z-index: 2147483647 !important; } /* v131.94::fullscreen 伪类兜底态同样摘掉 .player-section 的盒子 */ body.bili-live-room-page:has(:fullscreen) #fullscreen-container .player-section { display: contents !important; } body.bili-live-room-page:has(:fullscreen) #fullscreen-container .player-section, body.bili-live-room-page:has(:fullscreen) #live-player-ctnr, body.bili-live-room-page:has(:fullscreen) #live-player-ctnr > .h-100.p-relative, body.bili-live-room-page:has(:fullscreen) #live-player, body.bili-live-room-page:has(:fullscreen) #live-player video, body.bili-live-room-page:has(:fullscreen) #live-player .web-player-danmaku, body.bili-live-room-page:has(:fullscreen) #live-player .danmaku-item-container { position: absolute !important; top: 0 !important; left: 0 !important; width: 100% !important; height: 100% !important; max-width: none !important; max-height: none !important; min-height: 0 !important; padding: 0 !important; margin: 0 !important; border: none !important; border-radius: 0 !important; transform: none !important; box-sizing: border-box !important; object-fit: contain !important; } body.bili-live-room-page:has(:fullscreen) #aside-area-vm { display: none !important; visibility: hidden !important; width: 0 !important; height: 0 !important; min-height: 0 !important; margin: 0 !important; padding: 0 !important; overflow: hidden !important; } /* ============================================================ ---- 8) v131.91:屏蔽播放器「长按」 ---- 长按会同时冒出两个东西: A) 浏览器自己的「选中文字 / 复制分享」浮层 —— 纯 CSS 就能掐掉:touch-callout + user-select 全关。 B) 播放器自带的调试面板(探针实测: #live-player > ul,z=99,里面是 「画面异常?切换解码策略试试 / 播放器日志信息 / 视频统计信息 / Room Player 3.11.9 / 关闭」) —— 双击退出全屏时大概率被带出来,挡住画面; 连点还会点中面板里的按键。 CSS 直接隐藏(结构选择器 #live-player > ul 稳定), JS 另给同类面板打 .bili-live-ctx-menu 兜底(按文本识别)。 pointer-events:none 再加一层保险:就算它真的被触发, 也点不到任何一项。 */ body.bili-live-room-page #fullscreen-container, body.bili-live-room-page #fullscreen-container .player-section, body.bili-live-room-page #live-player-ctnr, body.bili-live-room-page #live-player-ctnr > .h-100.p-relative, body.bili-live-room-page #live-player, body.bili-live-room-page #live-player video, body.bili-live-room-page #live-player .web-player-danmaku, body.bili-live-room-page #live-player .danmaku-item-container { -webkit-touch-callout: none !important; -webkit-user-select: none !important; -moz-user-select: none !important; -ms-user-select: none !important; user-select: none !important; } body.bili-live-room-page #live-player > ul, body.bili-live-room-page #fullscreen-container .bili-live-ctx-menu, body.bili-live-room-page .bili-live-ctx-menu { display: none !important; visibility: hidden !important; width: 0 !important; height: 0 !important; min-height: 0 !important; max-height: 0 !important; margin: 0 !important; padding: 0 !important; overflow: hidden !important; opacity: 0 !important; pointer-events: none !important; } /* ============================================================ ---- 9) v131.91:控制栏只留「时间」+「清晰度」,居中 ---- 探针 11-21-56 实测(视口 800,单击播放器弹出的那条): #web-player-controller-wrap-el > div.live-web-player-controller.svelte-4rgwwa > div.control-area.svelte-4rgwwa [778x36] > div.left-area [148x36] 含「47:43」时间 > div.right-area [606x36] 含「自动」清晰度 + 一串图标 窄屏下右侧那排图标挤成一团、显示不全也点不准,全部隐藏; 时间按键与清晰度按键由 JS 按文本识别后打 data-bili-live-keep="1", 这里只做「非标记即隐藏」+ flex 居中 —— 隐藏和排版全在 CSS。 ---- */ body.bili-live-room-page .control-area { display: flex !important; flex-direction: row !important; flex-wrap: nowrap !important; align-items: center !important; justify-content: center !important; width: 100% !important; max-width: 100% !important; padding: 0 !important; } body.bili-live-room-page .control-area > .left-area, body.bili-live-room-page .control-area > .right-area, body.bili-live-room-page .live-web-player-controller > .left-area, body.bili-live-room-page .live-web-player-controller > .right-area { display: flex !important; flex-direction: row !important; flex-wrap: nowrap !important; align-items: center !important; justify-content: center !important; flex: 0 0 auto !important; width: auto !important; min-width: 0 !important; max-width: none !important; height: auto !important; margin: 0 !important; padding: 0 !important; float: none !important; position: static !important; } /* 两个区之间留 8px;空的那个区直接不占位(:has 支持时) */ body.bili-live-room-page .control-area > .left-area { margin-right: 8px !important; } body.bili-live-room-page .control-area > .right-area { margin-left: 0 !important; } body.bili-live-room-page .control-area > .left-area:not(:has([data-bili-live-keep])), body.bili-live-room-page .control-area > .right-area:not(:has([data-bili-live-keep])) { display: none !important; width: 0 !important; margin: 0 !important; overflow: hidden !important; } body.bili-live-room-page .control-area .left-area > *:not([data-bili-live-keep]), body.bili-live-room-page .control-area .right-area > *:not([data-bili-live-keep]) { display: none !important; visibility: hidden !important; width: 0 !important; min-width: 0 !important; height: 0 !important; min-height: 0 !important; margin: 0 !important; padding: 0 !important; overflow: hidden !important; pointer-events: none !important; } /* 保留的两个键:居中、字号统一、不再被压缩 */ body.bili-live-room-page .control-area [data-bili-live-keep] { display: flex !important; visibility: visible !important; flex: 0 0 auto !important; align-items: center !important; justify-content: center !important; width: auto !important; min-width: 0 !important; max-width: none !important; height: auto !important; margin: 0 !important; padding: 0 4px !important; opacity: 1 !important; overflow: visible !important; } /* ============================================================ ---- 10) v131.92:三处细节 ---- ① 播放器右上角 36x36 的「反馈」图标 探针实测:它是 #live-player 的**直接子级** svg#图层_1, [36x36] top=39 left=301,常年盖在画面右上角。窄屏下用不上, 直接隐藏(控制栏内的图标都在更深的层级里,不受影响)。 ② 画面与边框之间约 1px 的露边(v131.93 根治) 根因是「两份取整」: #fullscreen-container 高 calc((100vw - 22px) * 9 / 16 + 6px) = 196.125px → 内容盒 = 196.125 - 6(上下边框) = 190.125px v131.92 时内层链又各自写了一条 calc((100vw - 22px) * 9 / 16) = 190.125px 两条算式分别取整时,左侧 / 底部会差出不到 1px, 露出容器底色 —— 就是看到的那条细缝。 视频页用的是 height:100%(跟随父级内容盒,只有一份取整),所以没事。 v131.92 用 scale(1.012) 放大视频遮盖缝隙, 但会裁掉视频边缘 1~2px 内容(不符合"不裁剪"要求)。 v131.93 根治:内层链全部改用 height:100% 跟随父级内容盒, 只有一份取整,缝隙彻底消失。站内 JS 行内 !important 写死的错误高度由 applyLivePlayerSize 用 100% 行内 !important 顶掉。 容器底色补 #000 兜底保留。 全屏态由 .bili-live-fs / :has(:fullscreen) 那两组 特异性更高的规则接管,不受本条影响。 ③ 画质面板(.quality-wrap .panel) 探针「点击自动按键后」实测: .panel [160x236],transform: matrix(1,0,0,1,-80,-238) → 相对按钮向上弹 238px,最终落在 top=-148 ~ bottom=88, 比按钮(top=190)高出一百多像素。 普通态 / 横屏下它整个跑到可视区外面被裁,只有竖屏全屏 (屏高够)才显示得全。改成视口居中 + 限高可滚动, 任何尺寸、任何朝向都完整可见。 ---- */ /* ① 隐藏「反馈」图标 */ body.bili-live-room-page #live-player > svg, body.bili-live-room-page #live-player > svg[id], body.bili-live-room-page #live-player > [class*="feedback"], body.bili-live-room-page #live-player [class*="feedback"], body.bili-live-room-page #live-player [class*="FeedBack"] { display: none !important; visibility: hidden !important; width: 0 !important; height: 0 !important; min-width: 0 !important; min-height: 0 !important; margin: 0 !important; padding: 0 !important; overflow: hidden !important; pointer-events: none !important; } /* ② v131.93:次像素缝隙已由内层链 height:100% 根治(见第 3 段), 不再需要 scale 放大。video 的 transform 保持 none(上面已写), 画面不被裁剪也不被拉伸。容器底色补黑兜底仍保留。 */ body.bili-live-room-page #fullscreen-container { background: #000 !important; } /* ③ 画质面板:视口居中 + 限高可滚动 */ body.bili-live-room-page .quality-wrap .panel, body.bili-live-room-page .control-area .panel { position: fixed !important; top: 50% !important; right: auto !important; bottom: auto !important; left: 50% !important; transform: translate(-50%, -50%) !important; width: 160px !important; max-width: 200px !important; min-width: 0 !important; height: auto !important; max-height: calc(100vh - 32px) !important; margin: 0 !important; border-radius: 10px !important; overflow-x: hidden !important; overflow-y: auto !important; -webkit-overflow-scrolling: touch !important; z-index: 2147483000 !important; } /* ============================================================ ---- 11) v132.05:弃用站内遮罩层,自建渐变遮罩 ---- 【目标】按键贴播放器底、遮罩从底部连续铺上来, 同时**绝不破坏站内自己的"点击收起 / 延时自动隐藏"**。 【v132.01 / v132.02 为什么把自动隐藏改坏了 —— 复盘】 站内控制栏的唤出/收起,动画走的是控制栏自身的 transform(translateY 滑入滑出),配合高度/透明度。 而那两版给控制栏整条链写了: · height:100% / inset:0 ← 顶掉站内"收起"时的高度 · transform: none !important ← 顶掉站内的滑出动画 结果:站内以为自己收起了,节点却仍铺在画面上 —— 表现出来就是"弹出来就不隐藏,点屏幕也没反应"。 这两类属性(height / transform / inset)是站内的 **状态通道**,外部一律不许碰。 【v132.04 的遮罩为什么会在 84px 处闪一下】 站内遮罩层 .web-player-controller-bg 是 height:56px + bottom:84px(礼物栏让位的残留) 唤出瞬间它先在 84px 处渲染出来,我们的 JS 要等到 下一拍(MutationObserver 30ms / 轮询 250ms)才把 margin 补偿写上去 —— 这一拍的错位就是肉眼看到的"闪一下"。 补偿永远比站内渲染慢一拍,这个闪没法靠加快轮询根治。 【本版做法:干脆不用站内那层,自己画】 ① 站内遮罩层直接 display:none —— 它只是纯视觉层 (本来就已被设成 pointer-events:none), 隐藏它不影响任何交互,也就不存在"闪"了; ② 遮罩改用 #live-player 的 ::after 伪元素: · 常驻、opacity:0,靠 .bili-live-ctrl-on 切到 1, 带 180ms 过渡,跟控制栏滑入同步淡入,不突兀; · 铺满整个播放器(不使用百分比之外的任何几何值), 底部最浓、向上渐隐,本身就不存在"断在 84px"的问题; · pointer-events:none + 纯视觉,点击照样穿透回画面; · z=11 —— 低于控制栏包层 z=13,不挡按键; ③ 按键行仍用 margin 位移补偿(v132.03 起的成熟做法), JS 实测偏移量,不动任何状态通道。 ---- */ /* ① 弃用站内遮罩层(纯视觉层,隐藏不影响交互) */ body.bili-live-room-page .web-player-controller-bg, body.bili-live-room-page #live-player > [class*="controller-bg"] { display: none !important; visibility: hidden !important; pointer-events: none !important; } /* ② 自建遮罩:常驻 + opacity 0/1 过渡,彻底没有"闪一下" */ body.bili-live-room-page #live-player::after { content: '' !important; position: absolute !important; top: 0 !important; right: 0 !important; bottom: 0 !important; left: 0 !important; width: 100% !important; height: 100% !important; background: linear-gradient( to top, rgba(0, 0, 0, 0.62) 0%, rgba(0, 0, 0, 0.44) 9%, rgba(0, 0, 0, 0.22) 20%, rgba(0, 0, 0, 0.08) 32%, rgba(0, 0, 0, 0) 45% ) !important; opacity: 0 !important; transition: opacity 180ms ease !important; pointer-events: none !important; z-index: 11 !important; } body.bili-live-room-page #live-player.bili-live-ctrl-on::after { opacity: 1 !important; } /* ③ 按键行:下移补偿(只动 margin,不动 transform / height / inset) 探针实证(bili_probe_2026-09-30_17-16,全屏 800x360): .control-area [800x36] top=324 bottom=360(补偿后贴底 ✓) 84 只是首帧兜底(限全屏态),真实偏移由 JS 实测 (播放器底 − 按键底)后写精确值;普通态实测为 0 就写 0。 */ body.bili-live-room-page.bili-live-fs .control-area, body.bili-live-room-page:has(:fullscreen) .control-area { margin-bottom: -84px !important; } /* ============================================================ ---- 12) v132.06:首屏零闪 —— 顶部栏等"一出生就该藏" ---- 现象:刚打开直播间,官方 PC 顶部导航会先显示一下(还带着 被窄屏挤压后的变形),过一瞬才消失。 根因:本页所有隐藏规则都挂在 body.bili-live-room-page ××× 这个前缀上,而 bili-live-room-page 是 JS 给 打的。 脚本虽然是 document-start(样式表在 HTML 解析前就已注入), 但 body 要等 HTML 解析到才存在、class 要等 syncPageClass 跑过才生效 —— 中间这段时间导航栏是"无人管"的状态, 浏览器于是老老实实把它画了出来。 修法:这些元素是直播间**独有**的(#room-ssr-vm 是直播间 SSR 根节点 id,.link-navbar / footer.link-footer / #sidebar-vm 都只在 live.bilibili.com 出现,主站用的是 .bili-header), 所以可以直接用**不带任何 class 前缀**的选择器隐藏 —— 不依赖 body、不依赖 JS 打标,样式表一注入就成立, 元素刚被解析出来就是 display:none,一帧都不会画出来。 ⚠ 刻意放在样式表**最后**:同为 !important 且特异性相同时 后写覆盖先写,放在末尾保证它压过前面任何一条同分规则。 ⚠ 用 html:root 前缀抬特异性到 (1,1,1),与 body.bili-live-room-page #room-ssr-vm 同分,靠位置取胜。 ⚠ main.app-content 的 padding-top:74px 是顶部栏留的位置, 顶部栏一藏它就是一块无来由的顶部空白,一并归零。 ---- */ html:root #room-ssr-vm, html:root #room-ssr-vm *, html:root .link-navbar-ctnr, html:root .link-navbar-wrap, html:root nav.link-navbar, html:root .link-navbar, html:root #head-info-vm, html:root #gift-control-vm, html:root #rank-list-vm, html:root #rank-list-ctnr-box, html:root #sections-vm, html:root #sidebar-vm, html:root #room-background-vm, html:root #gift-screen-animation-vm, html:root #guard-popup, html:root footer.link-footer { display: none !important; visibility: hidden !important; width: 0 !important; height: 0 !important; min-width: 0 !important; min-height: 0 !important; max-height: 0 !important; padding: 0 !important; margin: 0 !important; border: none !important; overflow: hidden !important; pointer-events: none !important; } /* 顶部栏留的那 74px,一并抹掉,避免首屏内容先被推下去再弹回来 */ html:root main.app-content, html:root main.app-content.p-relative { padding-top: 0 !important; } `; root.appendChild(style); } const PAGE_CLASS_RULES = [ { test: isSearchPage, cls: ['bili-search-page'] }, { test: isTBiliDynamic, cls: ['bili-dynamic-page'] }, { test: isOpusPage, cls: ['bili-opus-page'] }, { test: isHome, cls: ['bili-home-page'] }, { test: isSpacePage, cls: ['bili-space-page'] }, // 播放列表页:额外带上 bili-video-page,直接复用视频页的全部优化 { test: isListPage, cls: ['bili-video-page', 'bili-list-page'] }, { test: isVideoPage, cls: ['bili-video-page'] }, { test: isBangumiPage, cls: ['bili-bangumi-page'] }, { test: isLiveRoomPage, cls: ['bili-live-room-page'] } ]; const ALL_PAGE_CLASSES = [ 'bili-search-page', 'bili-dynamic-page', 'bili-opus-page', 'bili-home-page', 'bili-space-page', 'bili-video-page', 'bili-list-page', 'bili-bangumi-page', 'bili-live-room-page' ]; function currentPageClasses() { for (let i = 0; i < PAGE_CLASS_RULES.length; i++) { if (PAGE_CLASS_RULES[i].test()) return PAGE_CLASS_RULES[i].cls; } return []; } function syncPageClass() { if (!document.body) return false; const want = currentPageClasses(); const cl = document.body.classList; ALL_PAGE_CLASSES.forEach(c => { if (want.indexOf(c) === -1) cl.remove(c); }); want.forEach(c => cl.add(c)); return true; } function applyPageClassEarly() { if (!syncPageClass()) { const obs = new MutationObserver(() => { if (syncPageClass()) obs.disconnect(); }); obs.observe(document.documentElement, { childList: true, subtree: true }); } // 站内跳转(如 /list/ 与 /video/ 互跳)时同步页面 class window.addEventListener('popstate', syncPageClass); ['pushState', 'replaceState'].forEach(fn => { const orig = history[fn]; if (typeof orig !== 'function') return; history[fn] = function () { const ret = orig.apply(this, arguments); setTimeout(syncPageClass, 0); return ret; }; }); } function fixVideoControls() { if (!isVideoPage() && !isBangumiPage() && !isListPage()) return; if (fixVideoControls._done) return; const playerContainer = document.querySelector('body.bili-video-page .bpx-player-container') || document.querySelector('body.bili-bangumi-page .bpx-player-container'); if (!playerContainer) return; const videoArea = playerContainer.querySelector('.bpx-player-video-area'); if (!videoArea) return; const videoPerch = videoArea.querySelector('.bpx-player-video-perch'); const videoWrap = (videoPerch && videoPerch.querySelector('.bpx-player-video-wrap')) || videoArea.querySelector('.bpx-player-video-wrap'); if (!videoWrap) return; const video = videoWrap.querySelector('video'); if (!video) return; if (videoWrap.parentElement === videoArea && videoArea.firstElementChild === videoWrap) { fixVideoControls._done = true; return; } if (videoPerch && videoWrap.parentElement !== videoArea) { videoArea.insertBefore(videoWrap, videoPerch); } video.playsInline = true; const oldControlWrap = videoArea.querySelector('.bpx-player-control-wrap:not(.new)'); if (!oldControlWrap) return; const controlEntity = oldControlWrap.querySelector('.bpx-player-control-entity'); if (!controlEntity) return; let clickTimer; let hideTimer; const controlWrap = document.createElement('div'); controlWrap.className = 'bpx-player-control-wrap new'; controlWrap.innerHTML = '
'; videoArea.insertBefore(controlWrap, oldControlWrap); controlWrap.appendChild(controlEntity); const controlTop = controlEntity.querySelector('.bpx-player-control-top'); const bottomRight = controlEntity.querySelector('.bpx-player-control-bottom-right'); const isBpxStateShow = () => controlEntity.querySelector('.bpx-player-control-bottom-right > .bpx-state-show'); const isShown = () => playerContainer.getAttribute('ctrl-shown') === 'true'; playerContainer.setAttribute('ctrl-shown', 'false'); const observer = new MutationObserver((mutations) => { mutations.forEach((mutation) => { const firstNode = mutation.addedNodes[0]; if (firstNode && firstNode.nodeType === Node.ELEMENT_NODE && firstNode.classList.contains('bpx-player-ctrl-web')) { if (video.paused) showControlWrap(); const subtitleBtn = document.querySelector('.bpx-player-ctrl-subtitle'); if (subtitleBtn) { window.addEventListener('click', (event) => { if (!subtitleBtn.contains(event.target)) { subtitleBtn.dispatchEvent(new MouseEvent('mouseleave')); } }); } observer.disconnect(); } }); }); if (bottomRight) observer.observe(bottomRight, { childList: true }); function hideControlWrap(isEnd = false) { if ((!video.paused && !isBpxStateShow()) || isEnd) { playerContainer.setAttribute('ctrl-shown', 'false'); clearTimeout(hideTimer); } else { delayHideTimer(); } } function showControlWrap() { playerContainer.setAttribute('ctrl-shown', 'true'); delayHideTimer(); } function delayHideTimer() { clearTimeout(hideTimer); hideTimer = setTimeout(hideControlWrap, 3000); } function unmute() { video.muted = false; if (video.volume === 0) { const muteIcon = document.querySelector('.bpx-player-ctrl-muted-icon'); if (muteIcon) muteIcon.click(); } } video.addEventListener('ended', () => hideControlWrap(true)); video.addEventListener('play', delayHideTimer); videoWrap.addEventListener('mousemove', (e) => e.stopPropagation()); videoWrap.addEventListener('click', () => { clearTimeout(clickTimer); clickTimer = setTimeout(() => { if (isShown()) hideControlWrap(); else showControlWrap(); if (video.paused) video.play(); else video.pause(); }, 250); }); videoWrap.addEventListener('dblclick', () => { clearTimeout(clickTimer); unmute(); const isPortrait = video.videoHeight / video.videoWidth > 1; if (isPortrait) { const webBtn = document.querySelector('.bpx-player-ctrl-web'); if (webBtn) webBtn.click(); } else if (videoPerch) { videoPerch.dispatchEvent(new MouseEvent('dblclick', { bubbles: true })); } }); controlWrap.addEventListener('mousemove', (e) => e.stopPropagation()); controlWrap.addEventListener('click', (e) => { e.stopPropagation(); delayHideTimer(); }); if (controlTop) controlTop.addEventListener('touchstart', delayHideTimer); fixVideoControls._done = true; } function bindVideoSlideGesture() { if (!isVideoPage() && !isBangumiPage() && !isListPage()) return; if (bindVideoSlideGesture._bound) return; bindVideoSlideGesture._bound = true; let mask = document.getElementById('my-bili-right-mask'); if (!mask) { mask = document.createElement('div'); mask.id = 'my-bili-right-mask'; document.body.appendChild(mask); } const MIN_DISTANCE = 60; const MAX_TIME = 600; function getPanel() { if (isListPage()) return document.querySelector('body.bili-list-page .playlist-container--right'); if (isVideoPage()) return document.querySelector('body.bili-video-page .right-container'); if (isBangumiPage()) return document.querySelector('body.bili-bangumi-page .plp-r-wrap'); return null; } function isOpen() { const r = getPanel(); return r && r.classList.contains('show'); } function openPanel() { const r = getPanel(); if (r) r.classList.add('show'); mask.classList.add('show'); } function closePanel() { const r = getPanel(); if (r) r.classList.remove('show'); mask.classList.remove('show'); } mask.addEventListener('click', closePanel); let startX = 0, startY = 0, startTime = 0; document.addEventListener('touchstart', e => { if (e.touches.length !== 1) return; startX = e.touches[0].clientX; startY = e.touches[0].clientY; startTime = Date.now(); }, { passive: true }); document.addEventListener('touchend', e => { if (e.changedTouches.length !== 1) return; const dx = e.changedTouches[0].clientX - startX; const dy = e.changedTouches[0].clientY - startY; const dt = Date.now() - startTime; if (Math.abs(dy) > Math.abs(dx)) return; if (dt > MAX_TIME) return; if (dx < -MIN_DISTANCE && !isOpen()) openPanel(); else if (dx > MIN_DISTANCE && isOpen()) closePanel(); }, { passive: true }); } function bindFullscreenFix() { if (!isVideoPage() && !isListPage()) return; if (bindFullscreenFix._bound) return; bindFullscreenFix._bound = true; const handleChange = () => { const isFull = !!(document.fullscreenElement || document.webkitFullscreenElement || document.mozFullScreenElement || document.msFullscreenElement); if (isFull) { document.body.classList.add('video-fullscreen'); } else { document.body.classList.remove('video-fullscreen'); } }; document.addEventListener('fullscreenchange', handleChange); document.addEventListener('webkitfullscreenchange', handleChange); document.addEventListener('mozfullscreenchange', handleChange); document.addEventListener('MSFullscreenChange', handleChange); document.addEventListener('orientationchange', () => { if (document.fullscreenElement || document.webkitFullscreenElement) { setTimeout(handleChange, 100); } }); } /* ================================================================ 关键词屏蔽(+必含 / -排除)v131.62 官方搜索没有屏蔽词,这里在自建搜索栏的输入语法上补一层: 输入 "+洛克王国 -手游 -世界" · 提交给 B 站的关键词只剩 "洛克王国"(+ 号本身只是标记,会被剥掉) · "手游"、"世界" 存为屏蔽词,结果页把标题/UP主命中它们的卡片整块隐藏 屏蔽词同时写进 URL(?_no=手游|世界)和 sessionStorage: · URL —— 刷新、翻页、切排序后仍然有效,链接分享给别人也带着 · 存储 —— URL 参数万一被站内跳转抹掉时兜底 过滤范围:卡片标题 + UP主 + 底部信息(播放/弹幕/时间那一行), 大小写不敏感,命中任意一个屏蔽词就整块消失。 ⚠ 这一段必须用 JS:CSS 选择器无法按元素的文本内容做匹配 (规范里的 :contains() 从未实装,至今也没有替代方案), 想"标题含某个词就不显示"只能遍历节点判断。 其余部分仍全部走 CSS,这段 JS 只负责打标记 + 插入提示条。 ================================================================ */ const FILTER_PARAM = '_no'; const FILTER_STORE = 'bili_mobile_minus_words'; // 把 " +洛克王国 -手游 -世界 " 拆成 include / exclude 两组 function parseQueryTokens(raw) { const tokens = String(raw || '').split(/\s+/).filter(Boolean); const include = [], exclude = []; tokens.forEach(function (t) { if (t.length > 1 && t.charAt(0) === '-') exclude.push(t.slice(1)); else if (t.length > 1 && t.charAt(0) === '+') include.push(t.slice(1)); else include.push(t); }); return { include: include, exclude: exclude }; } function readBlockedWords() { let raw = ''; try { raw = new URL(location.href).searchParams.get(FILTER_PARAM) || ''; } catch (e) {} if (raw) { try { sessionStorage.setItem(FILTER_STORE, raw); } catch (e) {} } else { try { raw = sessionStorage.getItem(FILTER_STORE) || ''; } catch (e) {} } return raw.split('|').filter(Boolean); } function saveBlockedWords(list) { try { if (list && list.length) sessionStorage.setItem(FILTER_STORE, list.join('|')); else sessionStorage.removeItem(FILTER_STORE); } catch (e) {} } function escapeHTML(s) { return String(s).replace(/[&<>"']/g, function (c) { return { '&': '&', '<': '<', '>': '>', '"': '"', "'": ''' }[c]; }); } // 四种搜索结果的卡片根元素(v131.83:原来只写了 .bili-video-card, // 导致屏蔽词只对综合页生效,直播 / 专栏 / 用户页一张都不过滤) const FILTER_CARD_SELECTOR = [ '.bili-video-card', // 综合页 视频(综合页的直播区也是 .bili-live-card) '.bili-live-card', // 直播页 直播间 / 综合页 直播区 '.b-article-card', // 专栏页 '.b-user-info-card' // 用户页 ].join(', '); // 卡片上参与匹配的文本:标题 + UP主 + 信息行 / 摘要 function cardMatchText(card) { const pick = function (sel) { const el = card.querySelector(sel); return el ? (el.textContent || '') : ''; }; const parts = [ // 综合页 · 视频卡 pick('.bili-video-card__info--tit'), pick('.bili-video-card__info--owner'), pick('.bili-video-card__info--bottom'), // 直播卡 pick('.bili-live-card__info--tit'), pick('.bili-live-card__info--uname'), pick('.bili-live-card__info--text'), // 专栏卡(h2 标题 + 摘要 + 信息行) pick('.i_card_title'), pick('.atc-desc'), pick('.atc-info'), // 用户卡(名字 + 粉丝数/简介) pick('.user-content'), pick('.user-name') ].filter(Boolean); // 兜底:万一某个页面的类名又变了,用整卡文本,保证任何卡片都参与匹配 return parts.length ? parts.join(' ') : (card.textContent || ''); } function removeFilterBar() { const bar = document.getElementById('my-bili-filterbar'); if (bar && bar.parentNode) bar.parentNode.removeChild(bar); if (document.body) document.body.classList.remove('has-filter-bar'); renderFilterBar._sig = null; } function renderFilterBar(blocked, hidden) { if (!document.body) return; // 内容没变就不重绘 —— run() 会被 MutationObserver 反复触发, // 每次都重建 innerHTML 会让横向滚动位置被重置、看着一闪一闪 const sig = blocked.join('|') + '#' + hidden; if (renderFilterBar._sig === sig && document.getElementById('my-bili-filterbar')) return; renderFilterBar._sig = sig; let bar = document.getElementById('my-bili-filterbar'); if (!bar) { bar = document.createElement('div'); bar.id = 'my-bili-filterbar'; document.body.appendChild(bar); } document.body.classList.add('has-filter-bar'); bar.innerHTML = '已屏蔽' + blocked.map(function (w) { return '' + escapeHTML(w) + ''; }).join('') + '已过滤 ' + hidden + ' 条' + '清除'; const clear = bar.querySelector('.fb-clear'); if (clear) { clear.addEventListener('click', function () { saveBlockedWords([]); try { const u = new URL(location.href); u.searchParams.delete(FILTER_PARAM); location.href = u.toString(); } catch (e) { location.reload(); } }); } } function applyKeywordFilter() { if (!isSearchPage()) { removeFilterBar(); return; } const blocked = readBlockedWords(); // 先复位:把上一轮(或刚点了"清除")隐藏过的卡片全部放出来,再重算 document.querySelectorAll('[data-blocked="1"]').forEach(function (el) { el.style.removeProperty('display'); el.removeAttribute('data-blocked'); }); if (!blocked.length) { removeFilterBar(); return; } const lowBlocked = blocked.map(function (w) { return w.toLowerCase(); }); let hidden = 0; document.querySelectorAll(FILTER_CARD_SELECTOR).forEach(function (card) { const text = cardMatchText(card).toLowerCase(); let hit = false; for (let i = 0; i < lowBlocked.length; i++) { if (text.indexOf(lowBlocked[i]) !== -1) { hit = true; break; } } if (!hit) return; // 隐藏"网格项"而不是内层卡片 —— 探针实测外层才占栅格单元, // 只藏内层卡片的话外层仍占 168x172,会留下一排空洞 // 综合页 / 直播页:.col_3、.video-list-item.col_3… // 专栏页:.col_6.mb_x40 用户页:.col_6.col_md_4 let item = card; const p = card.parentElement; if (p && /\bcol_/.test(p.className)) item = p; item.setAttribute('data-blocked', '1'); item.style.setProperty('display', 'none', 'important'); hidden++; }); renderFilterBar(blocked, hidden); } // 搜索类型:/live 直播、/article 专栏、/upuser 用户,其余算综合 const SEARCH_TYPES = [ { key: 'all', name: '综合', path: '/all' }, { key: 'live', name: '直播', path: '/live' }, { key: 'article', name: '专栏', path: '/article' }, { key: 'upuser', name: '用户', path: '/upuser' } ]; const MENU_CARET = ''; function currentSearchType() { const p = location.pathname.replace(/\/$/, '') || '/'; let t = 'all'; SEARCH_TYPES.forEach(function (x) { if (p === x.path) t = x.key; }); return t; } // SPA 跳转 / 异步渲染后,重算菜单项的高亮与链接 function syncSearchMenu() { const bar = document.getElementById('my-bili-searchbar'); if (bar && typeof bar._refreshMenu === 'function') bar._refreshMenu(); } function createSearchBar() { if (!isHome() && !isSearchPage() && !isSpacePage()) return; if (document.getElementById('my-bili-searchbar')) return; const onSearch = isSearchPage(); const onSpace = isSpacePage(); const url = new URL(location.href); const currentOrder = url.searchParams.get('order') || ''; const curType = currentSearchType(); // 直播页的排序是「综合排序 / 最新开播」,参数 online / live_time, // 与综合页、专栏页的 pubdate 不是一套,必须分开判断。 const onLive = onSearch && curType === 'live'; const isLatest = onLive ? (currentOrder === 'live_time') : (currentOrder === 'pubdate'); const bar = document.createElement('div'); bar.id = 'my-bili-searchbar'; // 用户搜索页(/upuser)的排序是「默认排序/粉丝数/Lv等级」, // 与综合页的「综合/最新」不是一套参数,这里点了没效果,直接不显示。 const onUpuser = onSearch && curType === 'upuser'; const showLeftBtn = !onSpace && !onUpuser; let leftBtnHTML = ''; if (showLeftBtn) { if (onSearch) { // 左侧按钮:名字改为「排序」,点击逻辑与「切换」一致(展开/收起一行) leftBtnHTML = ` `; } else { leftBtnHTML = `
`; } } // 右侧「切换」按钮 + 两行展开菜单(只在搜索页) let switchBtnHTML = ''; let menuHTML = ''; if (onSearch) { switchBtnHTML = ` `; // 名字统一为「综合 / 最新」,与各页保持一致; // 直播页底层参数仍是官方的 online / live_time(不是 pubdate)。 const orderItems = onLive ? [{ v: '', n: '综合' }, { v: 'live_time', n: '最新' }] : [{ v: '', n: '综合' }, { v: 'pubdate', n: '最新' }]; menuHTML = (onUpuser ? '' : `
${orderItems.map(function (o) { return '' + o.n + ''; }).join('')}
`) + `
${SEARCH_TYPES.map(function (t) { return '' + t.name + ''; }).join('')}
`; } // 两个隐藏 checkbox 必须排在所有被控元素之前(CSS 只有后继兄弟选择器) // 用户页没有「排序」按钮,对应的 checkbox 也不生成 const cbHTML = !onSearch ? '' : (onUpuser ? '' : '') + ''; const placeholderText = onSpace ? '搜索视频、动态' : '搜索视频、番剧、UP主...(用 -词 排除,例:洛克王国 -手游)'; const kw = onSearch ? (url.searchParams.get('keyword') || '') : ''; // 回填时把屏蔽词拼回原文("洛克王国 -手游 -世界"),用户接着编辑不会丢 const blockedNow = onSearch ? readBlockedWords() : []; const fullKw = blockedNow.length ? kw + ' ' + blockedNow.map(function (w) { return '-' + w; }).join(' ') : kw; const escapedKw = fullKw.replace(/"/g, '"').replace(//g, '>'); bar.innerHTML = ` ${cbHTML} ${leftBtnHTML}
${switchBtnHTML} ${menuHTML} `; const attach = () => { if (!document.body) { setTimeout(attach, 50); return; } document.body.appendChild(bar); // ⚠ 必须用 id 取!bar 里第一个 input 是隐藏 checkbox #my-bili-order-cb, // checkbox 的默认 value 就是字符串 "on",裸 querySelector('input') 会抓到它, // 导致搜索关键词变成 "on"(v131.69 修复)。 const input = bar.querySelector('#my-bili-search-input'); const btn = bar.querySelector('.my-search-btn'); const doSearch = () => { // 拆出 +必含 / -排除,只把正经关键词交给 B 站 const parsed = parseQueryTokens(input.value.trim()); const keyword = parsed.include.join(' '); if (!keyword) return; saveBlockedWords(parsed.exclude); if (onSpace) { const mid = location.pathname.split('/').filter(Boolean)[0] || ''; if (!mid || !/^\d+$/.test(mid)) return; location.href = `https://space.bilibili.com/${mid}/search?keyword=${encodeURIComponent(keyword)}`; return; } // v131.82:原来硬编码跳 /all,导致在直播 / 专栏 / 用户页搜索 // 都会跳回综合页。改成按当前页路径构造: // 综合 /all、直播 /live、专栏 /article、用户 /upuser // 并带上各页需要的官方参数(vt / from_source / search_type)。 const ct = currentSearchType(); let base = 'https://search.bilibili.com/all'; SEARCH_TYPES.forEach(function (t) { if (t.key === ct) base = 'https://search.bilibili.com' + t.path; }); const next = new URL(base); next.searchParams.set('keyword', keyword); if (ct !== 'all') { next.searchParams.set('vt', '63088886'); next.searchParams.set('from_source', 'web_search'); } // 直播页:主播区已隐藏,只搜直播间,与页面「共找到 N 个结果」一致 if (ct === 'live') next.searchParams.set('search_type', 'live_room'); // 屏蔽词带在 URL 上:刷新 / 翻页 / 切排序都还在 if (parsed.exclude.length) next.searchParams.set(FILTER_PARAM, parsed.exclude.join('|')); // 排序保持当前状态:直播页用 live_time,其余用 pubdate if (isLatest) next.searchParams.set('order', ct === 'live' ? 'live_time' : 'pubdate'); location.href = next.toString(); }; input.addEventListener('keydown', e => { if (e.key === 'Enter' || e.keyCode === 13) { e.preventDefault(); doSearch(); } }); btn.addEventListener('click', doSearch); // ---- 菜单项链接:随输入框实时重算,保证切过去用的是当前关键词 ---- const currentKeyword = () => { const parsed = parseQueryTokens(input.value.trim()); return { kw: parsed.include.join(' '), exclude: parsed.exclude }; }; // 切类型:综合走 /all,直播/专栏/用户照抄官方带的 vt 与 from_source const buildSwitchHref = (type) => { const c = currentKeyword(); let base = 'https://search.bilibili.com/all'; SEARCH_TYPES.forEach(function (t) { if (t.key === type) base = 'https://search.bilibili.com' + t.path; }); const next = new URL(base); const kw = c.kw || url.searchParams.get('keyword') || ''; if (kw) next.searchParams.set('keyword', kw); if (type !== 'all') { next.searchParams.set('vt', '63088886'); next.searchParams.set('from_source', 'web_search'); } if (c.exclude.length) next.searchParams.set(FILTER_PARAM, c.exclude.join('|')); return next.toString(); }; // 排序:留在当前搜索类型上,只动 order 参数(不会莫名跳回综合页) const buildOrderHref = (order) => { const c = currentKeyword(); const next = new URL(location.href); const kw = c.kw || next.searchParams.get('keyword') || ''; if (kw) next.searchParams.set('keyword', kw); else next.searchParams.delete('keyword'); if (c.exclude.length) next.searchParams.set(FILTER_PARAM, c.exclude.join('|')); else next.searchParams.delete(FILTER_PARAM); if (order) next.searchParams.set('order', order); else next.searchParams.delete('order'); // 直播页:主播区已隐藏,排序只针对直播间, // 补上官方「直播间」用的 search_type=live_room, // 这样结果数与页面上「共找到 N 个结果」一致。 if (currentSearchType() === 'live') next.searchParams.set('search_type', 'live_room'); return next.toString(); }; const refreshMenuHrefs = () => { const ct = currentSearchType(); const ordNow = new URL(location.href).searchParams.get('order') || ''; const latestNow = ct === 'live' ? (ordNow === 'live_time') : (ordNow === 'pubdate'); bar.querySelectorAll('.my-bili-menu-item').forEach(function (a) { if (a.dataset.type) { a.href = buildSwitchHref(a.dataset.type); a.classList.toggle('is-current', a.dataset.type === ct); } else if (a.hasAttribute('data-order')) { a.href = buildOrderHref(a.dataset.order || ''); a.classList.toggle('is-current', !!a.dataset.order === latestNow); } }); }; // 供 syncSearchMenu 在 SPA 跳转后复用 bar._refreshMenu = refreshMenuHrefs; refreshMenuHrefs(); input.addEventListener('input', refreshMenuHrefs); // ---- 互斥 + 点击外部收起(展开/收起本身是纯 CSS,这里只管状态互斥) ---- const allCb = () => bar.querySelectorAll('.my-bili-menu-cb'); const closeAll = () => { allCb().forEach(function (o) { o.checked = false; }); }; bar.addEventListener('change', function (e) { const t = e.target; if (!t.classList || !t.classList.contains('my-bili-menu-cb')) return; if (t.checked) { allCb().forEach(function (o) { if (o !== t) o.checked = false; }); } }); document.addEventListener('click', function (e) { if (bar.contains(e.target)) return; closeAll(); }); // 菜单项点完就跳走了,顺手收起,避免 SPA 返回时菜单还开着 bar.querySelectorAll('.my-bili-menu-item').forEach(function (a) { a.addEventListener('click', function () { setTimeout(closeAll, 0); }); }); // 兜底:B站是 SPA,站内跳转后如果 bar 还在,重置菜单状态 window.addEventListener('popstate', closeAll); }; attach(); } function fixSpaceNavTabs() { if (!isSpacePage()) return; const allowedTabs = ['主页', '动态', '投稿', '合集和系列']; document.querySelectorAll('body.bili-space-page .nav-tab > a.nav-tab__item').forEach(el => { const text = (el.textContent || '').trim(); el.style.removeProperty('display'); el.style.removeProperty('visibility'); const isAllowed = allowedTabs.some(t => text.indexOf(t) !== -1); if (!isAllowed) { el.style.setProperty('display', 'none', 'important'); el.style.setProperty('visibility', 'hidden', 'important'); } }); } function run() { if (!document.body) return; // 兜底:直播页 / 用户页偶发首屏拿不到自建搜索栏,这里补建并同步菜单状态 createSearchBar(); syncSearchMenu(); if (isTBiliDynamic()) { // 动态页 } else if (isOpusPage()) { // opus 详情页 } else if (isHome()) { // 首页 } else if (isSearchPage()) { // 搜索页:按 -排除词 过滤卡片(结果懒加载,run() 会被 MutationObserver 反复触发) applyKeywordFilter(); } else if (isSpacePage()) { fixSpaceNavTabs(); } else if (isVideoPage() || isListPage()) { fixVideoControls(); bindVideoSlideGesture(); bindFullscreenFix(); } else if (isBangumiPage()) { fixVideoControls(); bindVideoSlideGesture(); } else if (isLiveRoomPage()) { liveDropWebFullscreenClass(); // 站内补的网页全屏,每次 run 顺手清一次 syncLiveFullscreen(); applyLivePlayerSize(); bindLivePlayerSizeWatch(); bindLiveDblclickFullscreen(); bindLiveWebFullscreenGuard(); bindLiveBackExitFullscreen(); liveTrimController(); // 控制栏只留时间 + 清晰度 applyLiveControllerGeom(); // v132.05:按键行偏移补偿 + 自建遮罩开关 liveMarkContextMenu(); // 给长按调试面板打标记(隐藏在 CSS) bindLiveControllerWatch(); bindLiveLongPressGuard(); bindLiveChatScroll(); // 聊天区滚动(v131.98) bindLiveControllerCompLoop(); // v132.05:按键行偏移补偿 + 遮罩开关轮询 } } /* ===== 直播间:全屏状态检测(v131.90 重写)===== CSS 自己认不出"当前是不是全屏",只能由 JS 判断后给 body 打 bili-live-fs, 再由 CSS 里那组更高特异性的 .bili-live-fs 规则撤掉全部尺寸约束。 ⚠⚠ 旧判定的致命坑(v131.88 / 131.89 都没修好,现象"没变化"就出在这): 旧版第 4 条「尺寸启发式:播放器贴满视口四边就算全屏」。 而退出原生全屏的那一刻,站内播放器会自己给 #fullscreen-container 写上一套 position:fixed + 铺满视口的**行内样式**(所谓"网页全屏", 仍带浏览器地址栏)。于是: 尺寸启发式命中 -> 判成"全屏" -> applyLivePlayerSize 走全屏分支, 把整条链写成 100%/100% -> 它真的铺满视口 -> 用户看到的就是"带地址栏的全屏"。 下一拍双击:不在原生全屏 -> 又 requestFullscreen 进原生全屏。 ⇒ 两种全屏来回跳,永远退不回普通态。返回键同理: 浏览器用第一次返回退出原生全屏,站内立刻补上假全屏, "看起来就是退到了带地址栏的全屏",再按一次才真的离开页面。 新判定:只认**原生**全屏,其余一切(class、行内尺寸、fixed 定位)都不算。 1) document.fullscreenElement / webkit 前缀 2) #fullscreen-container 命中 :fullscreen / :-webkit-full-screen(等价兜底) 站内自造的假全屏一律判"非全屏",由普通态那套 16:9 排版接管, 并立刻被 applyLivePlayerSize 写回正常尺寸 —— 即"双击 = 退出全屏"。 唯一例外:iOS Safari 不支持元素级 requestFullscreen,liveEnterFullscreen 只能退回点站内全屏键(那种确实是假全屏),此时靠 liveFsViaButton 放开, 仍按全屏铺满。Android 走不到这条分支,不会重新引入来回跳。 */ function isLiveFullscreen() { if (liveIsNativeFs()) return true; if (liveFsViaButton) return true; const wrap = document.querySelector('#fullscreen-container'); if (wrap) { try { if (wrap.matches(':fullscreen') || wrap.matches(':-webkit-full-screen')) return true; } catch (e) {} } return false; } function syncLiveFullscreen() { if (!isLiveRoomPage() || !document.body) return false; const on = isLiveFullscreen(); document.body.classList.toggle('bili-live-fs', on); return on; } /* ===== 直播间:站内「假全屏」class 的摘除(辅助,非主力)===== 主播间的"网页全屏"在不同版本里挂过 body.player-full-win。 它不是根因(根因是 isLiveFullscreen 的尺寸启发式,已在 v131.90 修正), 但留着无害:class 一出现就摘掉,配合样式表第 6 段把它按普通态渲染。 只有"摘 class"这件事 CSS 做不到,所以保留这一小段 JS。 */ function liveDropWebFullscreenClass() { if (!document.body) return false; // 原生全屏生效时留着无害,但没必要动,免得和站内状态机互相抖 if (liveIsNativeFs()) return false; if (!document.body.classList.contains('player-full-win')) return false; document.body.classList.remove('player-full-win'); return true; } /* 假全屏不只会挂 class,还会给容器链写行内 position:fixed / inset / z-index (行内 !important,样式表压不过,只能清行内)。非全屏时清一次, 播放器和评论区才会老老实实回到普通流里。 */ const LIVE_RESET_SEL = [ '.live-room-app', 'main.app-content', '.app-body', 'section.player-and-aside-area', '#player-ctnr', '.fullscreen-container-paddingbox' ]; const LIVE_RESET_PROPS = [ 'position', 'top', 'left', 'right', 'bottom', 'inset', 'width', 'height', 'max-width', 'min-height', 'max-height', 'transform', 'z-index', 'overflow' ]; function resetLiveFakeFullscreenInline() { let changed = false; const roots = [document.documentElement, document.body]; roots.forEach(function (el) { if (!el || !el.style) return; LIVE_RESET_PROPS.forEach(function (p) { if (el.style.getPropertyValue(p)) { el.style.removeProperty(p); changed = true; } }); }); LIVE_RESET_SEL.forEach(function (s) { const el = document.querySelector(s); if (!el || !el.style) return; LIVE_RESET_PROPS.forEach(function (p) { if (el.style.getPropertyValue(p)) { el.style.removeProperty(p); changed = true; } }); }); return changed; } function bindLiveWebFullscreenGuard() { if (!isLiveRoomPage() || bindLiveWebFullscreenGuard._done) return; const start = function () { if (!document.body) { setTimeout(start, 50); return; } if (bindLiveWebFullscreenGuard._done) return; bindLiveWebFullscreenGuard._done = true; const obs = new MutationObserver(function () { // 摘掉后自己也会触发一次(class 没了 -> 直接返回 false),不会自激 const a = liveDropWebFullscreenClass(); const b = isLiveFullscreen() ? false : resetLiveFakeFullscreenInline(); if (a || b) { syncLiveFullscreen(); applyLivePlayerSize(); } }); obs.observe(document.body, { attributes: true, attributeFilter: ['class', 'style'] }); liveDropWebFullscreenClass(); }; start(); } /* ===== 直播间:返回键 ===== 实测行为:浏览器自己会把「全屏中的第一次返回」用来退出全屏(不发生导航), 第二次返回才真的后退。所以只要把退出全屏后站内补上的"假全屏"及时压回普通态 (见 isLiveFullscreen / applyLivePlayerSize),返回键的行为就自动正确了: 第一次返回 = 退出全屏,仍停在直播间 第二次返回 = 正常离开直播间页面 v131.89 曾经用 pushState 哨兵条目去"吃"这次返回,实测无效(浏览器压根不派 popstate,哨兵反而多留一条历史记录),这里删掉,只保留一条兜底: 万一有浏览器在返回时既退全屏又派 popstate,这里补一次 exitFullscreen, 保证不会带着全屏态去后退。 */ function bindLiveBackExitFullscreen() { if (!isLiveRoomPage() || bindLiveBackExitFullscreen._done) return; bindLiveBackExitFullscreen._done = true; window.addEventListener('popstate', function () { if (!isLiveRoomPage()) return; if (liveIsNativeFs()) liveExitFullscreen(); }, true); } function bindLiveFullscreenWatch() { if (!isLiveRoomPage()) return; const sync = function () { syncLiveFullscreen(); }; ['fullscreenchange', 'webkitfullscreenchange', 'mozfullscreenchange'].forEach(function (ev) { document.addEventListener(ev, function () { // 进来过就是成功,别再被 liveEnterFullscreen 的复核当成失败去重试 const on = isLiveFullscreen(); if (on) { liveFsSawFs = true; } else { // 退出原生全屏的瞬间,站内会补一套"假全屏"(fixed 铺满视口)。 // 连清几拍:class、行内定位、尺寸全部压回普通态。 [0, 60, 150, 300, 600, 1000].forEach(function (ms) { setTimeout(function () { const a = liveDropWebFullscreenClass(); const b = resetLiveFakeFullscreenInline(); if (a || b) { syncLiveFullscreen(); applyLivePlayerSize(); } }, ms); }); } // 站内切换全屏后还要重排一帧,延后一拍才量得到真实尺寸 setTimeout(sync, 0); setTimeout(sync, 120); setTimeout(sync, 400); setTimeout(applyLivePlayerSize, 0); setTimeout(applyLivePlayerSize, 120); setTimeout(applyLivePlayerSize, 400); }); }); window.addEventListener('resize', function () { sync(); applyLivePlayerSize(); // 假全屏常在 resize 时补写行内尺寸,一并压回去 }); window.addEventListener('orientationchange', function () { [0, 300, 800].forEach(function (ms) { setTimeout(function () { sync(); applyLivePlayerSize(); }, ms); }); }); } /* ================================================================ 直播间:控制栏只留「时间」+「清晰度」 ================================================================ 单击播放器弹出的那条控制栏,探针实测: .control-area > .left-area(含「47:43」)+ .right-area(含「自动」+ 一排图标) 窄屏(360)下右侧那排图标挤成一团,显示不全、点了也没反应(音量/弹幕/网页全屏 这些在手机上都用不了),全部隐藏;只留: · 时间(形如 12:34 / 1:02:03) · 清晰度(自动 / 流畅 / 高清 / 蓝光 / 原画 / 1080P …) ⚠ 为什么需要一点点 JS:CSS 选择器无法按「元素里的文字」匹配 (:contains() 从未实装),认不出哪个是时间、哪个是清晰度。 所以 JS 只做一件事:给要留的按键打 data-bili-live-keep="1"; 隐藏、居中、间距全部由样式表第 9 段的 CSS 完成。 ---- */ const LIVE_TIME_RE = /^\d{1,3}:\d{2}(:\d{2})?$/; const LIVE_QUALITY_RE = /^(自动|流畅|清晰|标清|高清|超清|蓝光|原画|真彩|4K|8K|\d{3,4}[pP](30|50|60)?)$/; const LIVE_QUALITY_KEY = /画质|清晰度|quality|definition/i; function liveIsKeepCtrl(node) { if (!node || node.nodeType !== 1) return false; const txt = ((node.textContent || '').trim()); if (LIVE_TIME_RE.test(txt)) return true; if (LIVE_QUALITY_RE.test(txt)) return true; const meta = (typeof node.className === 'string' ? node.className : '') + ' ' + (node.getAttribute('aria-label') || '') + ' ' + (node.getAttribute('title') || ''); return LIVE_QUALITY_KEY.test(meta); } // 文字有时在嵌套的子 div 里(探针:时间文字在 .tip-wrap 内的 div 上), // 所以自己不匹配时再往下看一层;太宽的直接不认,避免整条区域被保留 function liveCtrlKeep(node) { if (!node || node.nodeType !== 1) return false; const r = node.getBoundingClientRect(); if (r.width > 200 || r.height > 80) return false; if (liveIsKeepCtrl(node)) return true; const kids = node.children || []; if (kids.length > 8) return false; for (let i = 0; i < kids.length; i++) { if (liveIsKeepCtrl(kids[i])) return true; } return false; } function liveTrimController() { if (!isLiveRoomPage()) return false; const wrap = document.querySelector('#fullscreen-container') || document.body; if (!wrap) return false; const ctrl = wrap.querySelector('#web-player-controller-wrap-el') || wrap.querySelector('.web-player-controller-wrap') || wrap.querySelector('.live-web-player-controller') || wrap.querySelector('[class*="web-player-controller"]'); if (!ctrl) { // 控制栏节点被整块换掉了:放开重绑开关,让 watch 重新挂到新节点上 bindLiveControllerWatch._done = false; return false; } const area = ctrl.querySelector('.control-area') || ctrl.querySelector('[class*="control-area"]') || ctrl; const areas = []; ['.left-area', '.right-area'].forEach(function (sel) { Array.prototype.forEach.call(area.querySelectorAll(sel), function (a) { // 只取直接子级,避免把嵌套区域也算进来 if (a.parentElement === area && areas.indexOf(a) === -1) areas.push(a); }); }); if (!areas.length) areas.push(area); let changed = false; areas.forEach(function (a) { Array.prototype.forEach.call(a.children, function (c) { if (!c || c.nodeType !== 1) return; const keep = liveCtrlKeep(c); const has = c.getAttribute('data-bili-live-keep') === '1'; if (keep && !has) { c.setAttribute('data-bili-live-keep', '1'); changed = true; } else if (!keep && has) { c.removeAttribute('data-bili-live-keep'); changed = true; } }); }); return changed; } function bindLiveControllerWatch() { if (!isLiveRoomPage() || bindLiveControllerWatch._done) return; const start = function () { const wrap = document.querySelector('#fullscreen-container'); const ctrl = wrap && (wrap.querySelector('#web-player-controller-wrap-el') || wrap.querySelector('.live-web-player-controller') || wrap.querySelector('.control-area')); if (!ctrl) { setTimeout(start, 400); return; } if (bindLiveControllerWatch._done) return; bindLiveControllerWatch._done = true; const obs = new MutationObserver(function () { if (obs._t) clearTimeout(obs._t); obs._t = setTimeout(function () { liveTrimController(); applyLiveControllerGeom(); // v132.05:控制栏重渲染后重新测偏移 }, 80); }); // 控制栏是 svelte 组件,会整体重渲染;class 变化也一起盯 obs.observe(ctrl, { childList: true, subtree: true, attributes: true, attributeFilter: ['class'] }); liveTrimController(); applyLiveControllerGeom(); }; start(); } /* ================================================================ 直播间:屏蔽播放器「长按」 ================================================================ 双击(尤其是退出全屏那一下)会带出两个东西: A) 浏览器的「选中文字 / 复制分享」浮层 —— 已由 CSS 的 -webkit-touch-callout:none + user-select:none 掐掉。 B) 播放器自带的调试面板(#live-player > ul,z=99, 「画面异常?切换解码策略试试 / 播放器日志信息 / 视频统计信息 / Room Player」) —— 挡画面,连点还会误触面板里的按键。 CSS 已经把 #live-player > ul 整块隐藏;这里再补两件 CSS 做不到的事: 1) contextmenu 在捕获阶段拦掉(浏览器长按浮层 + 站内面板都靠它触发), stopImmediatePropagation 保证站内挂在元素上的监听也收不到; 2) 按文本识别面板,打 .bili-live-ctx-menu —— 万一站内换了容器 (不再挂在 #live-player 下面),CSS 那组选择器照样能隐藏它。 */ function liveMarkContextMenu() { if (!isLiveRoomPage() || !document.body) return false; let changed = false; // 面板可能被挂到播放器外(portal),所以整棵文档都扫; // 识别串("画面异常 / 切换解码 / 播放器日志 / Room Player")是播放器独有的,不会误伤 const nodes = document.querySelectorAll('ul, [class*="menu"], [class*="context"]'); Array.prototype.forEach.call(nodes, function (el) { const txt = (el.textContent || '') + ' ' + ((typeof el.className === 'string' ? el.className : '') || ''); if (!/画面异常|播放器日志|视频统计信息|Room Player|切换解码/.test(txt)) return; if (el.classList.contains('bili-live-ctx-menu')) return; el.classList.add('bili-live-ctx-menu'); changed = true; }); return changed; } function bindLiveLongPressGuard() { if (!isLiveRoomPage() || bindLiveLongPressGuard._done) return; bindLiveLongPressGuard._done = true; // 捕获阶段:window 是最外层,先于站内任何元素级监听,能彻底掐断 window.addEventListener('contextmenu', function (e) { if (!isLiveRoomPage()) return; const t = e.target; if (!t || !t.closest) return; if (!t.closest('#fullscreen-container, #live-player')) return; e.preventDefault(); e.stopPropagation(); if (e.stopImmediatePropagation) e.stopImmediatePropagation(); // 面板万一已经被触发,立刻补一次标记,让 CSS 收掉 setTimeout(liveMarkContextMenu, 0); }, true); // 切换全屏后的一小段时间里,长按 / 连点最容易误触,多扫几次 const sweep = function () { if (liveMarkContextMenu()) liveTrimController(); }; [0, 120, 400, 900].forEach(function (ms) { setTimeout(sweep, ms); }); liveMarkContextMenu(); } /* ===== 直播间:播放器尺寸接管 ===== 站内有两种「行内 !important」写死的尺寸,样式表压不过,只能由 JS 补写行内: A) 正常态:站内 JS 按「容器高 - 礼物栏 84px」给 .player-section 写高度, 礼物栏被我们隐藏后这 84 仍被扣掉,视频被压成 106 高的扁条(应为 190)。 B) 网页全屏(body.player-full-win):站内把 #fullscreen-container 写成 行内 668px(PC 定宽),塞进 360 的视口 → 右侧溢出被裁、左侧一片空白。 两种都靠"后写覆盖先写"解决:同一元素的 inline style 是同一个声明块, 我们后写同一属性就会顶掉站内的值。 v131.93:内层链改用 height:100%(而非 calc),跟随外层内容盒高度, 只有一份取整,彻底消除左/底部约 1px 的次像素缝隙(旧版 calc 与外层 calc 分别取整会产生差值)。min-height 与 max-height 同步写 100%, 防止站内再改 height 时出现闪动。 外层仍用 calc 维持 16:9 比例(含 6px 边框补偿)。 */ /* v131.93:内层链统一用 100% 跟随父级,消除两份 calc 取整带来的次像素缝隙。 外层仍用 calc 维持 16:9 比例(含 3px 边框 x2 = 6px)。 */ const LIVE_PLAYER_H = '100%'; // 外层还要带上 3px 边框 x2 = 6px,与 CSS 里 #fullscreen-container 的取值一致 const LIVE_WRAP_H = 'calc((100vw - 22px) * 9 / 16 + 6px)'; const LIVE_PLAYER_SEL = ['.player-section', '#live-player-ctnr', '#live-player', '#live-player video']; // 只在值真的不一样时才写:observer 会盯着 style 属性,无脑重写会自激死循环 function setLiveStyle(el, prop, val) { if (!el || !el.style) return; if (el.style.getPropertyValue(prop) === val && el.style.getPropertyPriority(prop) === 'important') return; el.style.setProperty(prop, val, 'important'); } /* v131.94 兜底(只在 display:contents 不被支持的环境才会真正起作用): CSS 里已让 .player-section 走 display:contents,行内几何值自然失效。 万一某个 WebView 不支持 display:contents,站内那套「容器高 - 84px」 的行内 height / min-height / max-height / bottom 就会重新压扁画面, 而样式表压不过行内 !important —— 这里直接把它摘掉,交回样式表。 摘完后 setLiveStyle 会立刻补写 100%,两边不会打架。 */ function stripPlayerSectionInline(wrap) { const sec = wrap && wrap.querySelector('.player-section'); if (!sec || !sec.style) return; ['height', 'min-height', 'max-height', 'top', 'bottom'].forEach(function (p) { if (sec.style.getPropertyValue(p)) sec.style.removeProperty(p); }); } function applyLivePlayerSize() { const wrap = document.querySelector('#fullscreen-container'); if (!wrap) return; stripPlayerSectionInline(wrap); const chain = LIVE_PLAYER_SEL.map(function (s) { return wrap.querySelector(s); }); if (isLiveFullscreen()) { // 原生全屏:贴满视口,顶掉站内行内的 668px 定宽 setLiveStyle(wrap, 'position', 'fixed'); setLiveStyle(wrap, 'top', '0'); setLiveStyle(wrap, 'left', '0'); setLiveStyle(wrap, 'width', '100%'); setLiveStyle(wrap, 'max-width', 'none'); setLiveStyle(wrap, 'height', '100%'); setLiveStyle(wrap, 'max-height', 'none'); setLiveStyle(wrap, 'min-height', '0'); setLiveStyle(wrap, 'transform', 'none'); chain.forEach(function (el) { if (!el) return; setLiveStyle(el, 'width', '100%'); setLiveStyle(el, 'max-width', 'none'); setLiveStyle(el, 'height', '100%'); setLiveStyle(el, 'min-height', '0'); setLiveStyle(el, 'max-height', 'none'); }); applyLiveControllerGeom(); // v132.05:全屏态同样实测补偿 return; } // 正常态:恢复 16:9。外层必须一并写回来 —— // 上面全屏分支给它写过 height:100%,退出全屏后行内 !important 会压过 CSS, // 播放器就会一直顶着满屏高。两条分支的属性集要对齐,才能来回切换都收敛。 // // v131.90:这里额外把 position / inset / transform / z-index 一并写回。 // 站内退出原生全屏时会给 #fullscreen-container 写上一套行内 // 「position:fixed; top/left:0; 满视口」的假全屏,光改尺寸不够 —— // 它还 fixed 着,就会盖在整页上面,看着仍然像全屏(只是带地址栏)。 // // v131.93:内层链 height 改为 100%(不再用 calc),跟随外层内容盒, // 只有一份取整,彻底消除左/底部约 1px 的次像素缝隙。 setLiveStyle(wrap, 'position', 'relative'); setLiveStyle(wrap, 'top', 'auto'); setLiveStyle(wrap, 'right', 'auto'); setLiveStyle(wrap, 'bottom', 'auto'); setLiveStyle(wrap, 'left', 'auto'); setLiveStyle(wrap, 'transform', 'none'); setLiveStyle(wrap, 'z-index', 'auto'); setLiveStyle(wrap, 'width', '100%'); setLiveStyle(wrap, 'max-width', '100%'); setLiveStyle(wrap, 'height', LIVE_WRAP_H); setLiveStyle(wrap, 'min-height', '0'); setLiveStyle(wrap, 'max-height', LIVE_WRAP_H); chain.forEach(function (el) { if (!el) return; setLiveStyle(el, 'position', 'absolute'); setLiveStyle(el, 'top', '0'); setLiveStyle(el, 'left', '0'); setLiveStyle(el, 'transform', 'none'); setLiveStyle(el, 'width', '100%'); setLiveStyle(el, 'max-width', '100%'); setLiveStyle(el, 'height', LIVE_PLAYER_H); setLiveStyle(el, 'min-height', LIVE_PLAYER_H); setLiveStyle(el, 'max-height', LIVE_PLAYER_H); }); applyLiveControllerGeom(); // v132.05:同上,普通态也实测(通常 d=0) } /* ===== 直播间:控制栏偏移补偿 + 自建遮罩开关(v132.05)===== 样式表第 11 段负责两件 CSS 能做的事: ① 弃用站内遮罩层 .web-player-controller-bg(display:none) —— 它带着 bottom:84px 让位,唤出瞬间会先在 84px 处渲染, 补偿永远比它慢一拍,因此"闪一下"无法靠轮询根治,直接弃用; ② 自建遮罩 #live-player::after(常驻 opacity:0, .bili-live-ctrl-on 时淡入到 1),铺满播放器、底部渐隐向上。 这里补 CSS 做不到的一件事:**测出按键行真实的偏移像素数** d = 播放器底边 − 按键行底边 只写 margin(绝不写 height / top / bottom / transform / opacity —— 那是站内收起动画的状态通道,v132.01/02 碰了它才改坏自动隐藏)。 ⚠ 用哪条 margin 取决于站内用的是 top 还是 bottom 定位: bottom 定位 → margin-bottom: -d 下移 top 定位 / 静态 → margin-top: +d 下移 读了 computed style 再决定,两条都写会双重位移。 ⚠ 撤除规则: · d <= 2px(已贴底)→ 撤; · 元素零尺寸 / 整块跑到播放器外(站内已收起卸载)→ 撤; · 撤除必须写 0(行内 !important),光 removeProperty 会让 样式表那条 -84px 兜底立刻重新生效。 ⚠ 补偿会让测得底边跟着下移,所以每轮都要用当前生效的位移量 还原原始位置再算,避免自激振荡。 ---- */ // 需要补偿的目标:按键行(站内遮罩层已在第 11 段直接弃用) const LIVE_SHIFT_SEL = ['.control-area']; /* 读当前**实际生效**的位移量与定位方式。 返回 { v: 下移像素(正数=已下移), via: 'mb' | 'mt' } */ function liveShiftState(el) { let cs = null; try { cs = window.getComputedStyle(el); } catch (e) {} if (!cs) return { v: 0, via: 'mb' }; // bottom 定位时用 margin-bottom 负值下移;否则用 margin-top 正值 const via = (cs.bottom && cs.bottom !== 'auto') ? 'mb' : 'mt'; const raw = via === 'mb' ? cs.marginBottom : cs.marginTop; const n = parseInt(raw, 10); const v = isNaN(n) ? 0 : n; return { v: (via === 'mb' ? -v : v), via: via }; } /* 写入下移 d(另一条 margin 清零,避免残留造成双重位移) */ function liveSetShift(el, via, d) { const val = (via === 'mb' ? (-d) : d) + 'px'; setLiveStyle(el, via === 'mb' ? 'margin-top' : 'margin-bottom', '0px'); setLiveStyle(el, via === 'mb' ? 'margin-bottom' : 'margin-top', val); } function liveClearShift(el) { if (!el || !el.style) return; setLiveStyle(el, 'margin-bottom', '0px'); setLiveStyle(el, 'margin-top', '0px'); } function applyLiveControllerGeom() { if (!isLiveRoomPage()) return false; const player = document.querySelector('#live-player') || document.querySelector('#fullscreen-container'); if (!player) return false; const pr = player.getBoundingClientRect(); if (pr.height <= 0) return false; const pBottom = pr.bottom; let shown = false; LIVE_SHIFT_SEL.forEach(function (sel) { Array.prototype.forEach.call(document.querySelectorAll(sel), function (el) { if (!el || !el.style) return; const r = el.getBoundingClientRect(); // 零尺寸 / 整块跑到播放器外 —— 站内已收起或卸载,撤补偿 if (r.height <= 0 || r.width <= 0 || r.top >= pBottom - 2 || r.bottom <= 2) { liveClearShift(el); return; } if (sel === '.control-area') shown = true; const st = liveShiftState(el); // 还原未补偿时的原始底边 const rawBottom = r.bottom - st.v; const d = Math.round(pBottom - rawBottom); if (d <= 2) { liveClearShift(el); return; } if (d === st.v) return; // 已收敛,别反复写(防自激) liveSetShift(el, st.via, d); }); }); // 补底渐变的开关:控制栏显示时才亮,收起立刻灭 if (player.classList) player.classList.toggle('bili-live-ctrl-on', shown); return true; } function bindLiveControllerCompLoop() { if (!isLiveRoomPage() || bindLiveControllerCompLoop._done) return; bindLiveControllerCompLoop._done = true; // 站内滑入滑出有动画 + 会重新挂载,轮询跟上;250ms 一次,只在直播间页跑 setInterval(applyLiveControllerGeom, 250); // 控制栏一挂载就立刻量一次,免得等下一拍才贴底(首帧闪一下) const host = document.querySelector('#live-player') || document.body; if (host) { const mo = new MutationObserver(function () { if (mo._t) clearTimeout(mo._t); mo._t = setTimeout(applyLiveControllerGeom, 30); }); // 只听**直接子节点**:控制栏就是 #live-player 的子孙, // 用 subtree 会被弹幕的频繁插入带着一直跑 mo.observe(host, { childList: true }); } applyLiveControllerGeom(); } /* 站内会随时重写行内尺寸(切清晰度、切全屏、双击…), 光靠 run() 的那几个定时器抓不住,这里专盯着播放器链的 style/class 变化。 */ function bindLivePlayerSizeWatch() { if (!isLiveRoomPage() || bindLivePlayerSizeWatch._done) return; const wrap = document.querySelector('#fullscreen-container'); if (!wrap) { setTimeout(bindLivePlayerSizeWatch, 300); return; } bindLivePlayerSizeWatch._done = true; const obs = new MutationObserver(function () { if (obs._t) clearTimeout(obs._t); obs._t = setTimeout(applyLivePlayerSize, 60); }); obs.observe(wrap, { attributes: true, attributeFilter: ['style', 'class'] }); LIVE_PLAYER_SEL.forEach(function (s) { const el = wrap.querySelector(s); if (el) obs.observe(el, { attributes: true, attributeFilter: ['style', 'class'] }); }); if (document.body) obs.observe(document.body, { attributes: true, attributeFilter: ['class'] }); applyLivePlayerSize(); } /* ===== 直播间:聊天区滚动(v131.98 真·修好)===== 探针实录(bili_probe 含隐藏的探针)暴露了真正的根因: .chat-history-panel [344x516] ← 面板被限死在一屏内(v131.97 生效了) > #chat-history-list [344x1286] ← 列表却有 1286 高,跟内容一样长! 列表自己跟内容一样高 ⇒ scrollHeight === clientHeight ⇒ 可滚动量 max = 0 ⇒ **它压根不是滚动容器**: · 手指在聊天区滑 → 没有可滚的东西 → 纹丝不动 · 面板 overflow:hidden 把它裁掉 → 页面也不产生滚动 → 整页也滑不动 这正是「从一开始只要手指落在聊天区,滑动就完全无效」的原因, 也解释了 v131.97 的 JS 兜底为何没动静(它第一条就是 max<=2 直接 return)。 为什么 CSS 的 height:100% !important 没把它压回 516? 站内给列表写了**行内 !important** 的高度(与播放器那套 84px 同款手段), 样式表的 !important 压不过行内的 !important,只能由 JS 后写覆盖。 本版两步走: ① forceLiveChatSize —— JS 用行内 !important 把列表高度钉成面板高度 (优先取 panel.clientHeight 的 px 值,最稳;拿不到才退回 100%), 并补齐 overflow-y:auto / overscroll-behavior:contain / touch-action 等。 站内随时会重写(Vue 重渲染、新弹幕),用 MutationObserver 盯着补写。 ② 手势兜底 —— 监听挂在 document **捕获阶段**(比站内任何监听器都早, 否则站内在祖先上 stopPropagation 我们就永远收不到事件), 只在「原生确实没动」时接管:defaultPrevented 为真,或累计位移 > 12px 而 scrollTop 纹丝不动。接管后手动写 scrollTop, 用 passive:false 以便必要时 preventDefault 掐掉页面滚动。 */ /* v131.99:聊天区高度改为「实测视口 - 面板顶距 - 36px」 —— 为什么不用纯 CSS 的 100dvh?两份探针对比说明了问题: 刚进直播间:100dvh ≈ 524 → 面板 240,看着很矮 全屏再退出:100dvh ≈ 800 → 面板 516,明显变高 同一个页面视口差出 276px,是移动端浏览器地址栏/工具栏收放造成的, dvh 在某些 WebView 里还会滞后一拍,纯 CSS 算出来的高度忽高忽低。 这里直接读 visualViewport.height(拿不到退 innerHeight), 再用面板的**文档坐标**顶距(rect.top + scrollY,不随滚动变化)换算: 目标高 = 视口高 - 面板顶距 - 36 这样无论地址栏是收是放,聊天区底边恒距屏幕底 36px。 */ function forceLiveChatSize() { const panel = document.querySelector('.chat-history-panel'); const list = document.querySelector('#chat-history-list'); if (!list) return false; let h = '100%'; if (panel) { const vp = window.visualViewport; const vh = (vp && vp.height) || window.innerHeight || (document.documentElement && document.documentElement.clientHeight) || 0; const scrollY = window.scrollY || window.pageYOffset || 0; const docTop = panel.getBoundingClientRect().top + scrollY; // 文档坐标,稳定 if (vh > 320 && docTop > 0) { const target = Math.round(vh - docTop - 36); // 距屏幕底 36px if (target > 120) h = target + 'px'; } else if (panel.clientHeight > 40) { h = panel.clientHeight + 'px'; // 兜底:沿用面板高 } } setLiveStyle(list, 'height', h); setLiveStyle(list, 'min-height', '0'); setLiveStyle(list, 'max-height', h); setLiveStyle(list, 'overflow-x', 'hidden'); setLiveStyle(list, 'overflow-y', 'auto'); setLiveStyle(list, 'overscroll-behavior', 'contain'); setLiveStyle(list, 'touch-action', 'pan-y'); setLiveStyle(list, 'transform', 'none'); setLiveStyle(list, '-webkit-overflow-scrolling', 'touch'); if (panel) { // 面板跟着列表一起定高,两者始终等高(否则列表会被面板裁掉一截) if (h !== '100%') { setLiveStyle(panel, 'height', h); setLiveStyle(panel, 'min-height', '0'); setLiveStyle(panel, 'max-height', h); } setLiveStyle(panel, 'overflow', 'hidden'); setLiveStyle(panel, 'overscroll-behavior', 'contain'); setLiveStyle(panel, 'touch-action', 'pan-y'); } return true; } function bindLiveChatScroll() { if (!isLiveRoomPage() || bindLiveChatScroll._done) return; if (!forceLiveChatSize()) { setTimeout(bindLiveChatScroll, 400); return; } bindLiveChatScroll._done = true; // 站内随时重写行内尺寸 / 重渲染,盯着补写 const panel = document.querySelector('.chat-history-panel'); const list = document.querySelector('#chat-history-list'); const obs = new MutationObserver(function () { if (obs._t) clearTimeout(obs._t); obs._t = setTimeout(forceLiveChatSize, 60); }); if (list) obs.observe(list, { attributes: true, attributeFilter: ['style', 'class'] }); if (panel) obs.observe(panel, { attributes: true, attributeFilter: ['style', 'class'] }); window.addEventListener('resize', function () { setTimeout(forceLiveChatSize, 120); }); window.addEventListener('orientationchange', function () { setTimeout(forceLiveChatSize, 300); }); // v131.99:地址栏收放 / 键盘弹出只改 visualViewport,不触发 window.resize, // 这里单独盯住,视口一变立刻按新的可视高度重算「距底 36px」 if (window.visualViewport) { const vv = window.visualViewport; const onVV = function () { setTimeout(forceLiveChatSize, 80); }; vv.addEventListener('resize', onVV); vv.addEventListener('scroll', onVV); } // 首屏 dvh 常滞后一拍,多补几次让高度尽快收敛 [0, 150, 400, 900, 1800].forEach(function (ms) { setTimeout(forceLiveChatSize, ms); }); let active = false, hijack = false, lastY = 0, startTop = 0, moved = 0; const inChat = function (t) { return !!(t && t.closest && t.closest('.chat-history-panel, #aside-area-vm')); }; document.addEventListener('touchstart', function (e) { if (e.touches.length !== 1 || !inChat(e.target)) { active = false; return; } forceLiveChatSize(); // 每次手势前先确认列表被钉住 const l = document.querySelector('#chat-history-list'); if (!l) { active = false; return; } active = true; hijack = false; moved = 0; lastY = e.touches[0].clientY; startTop = l.scrollTop; }, { capture: true, passive: true }); document.addEventListener('touchmove', function (e) { if (!active || e.touches.length !== 1) return; const l = document.querySelector('#chat-history-list'); if (!l) return; const y = e.touches[0].clientY; const dy = lastY - y; // 手指上滑 dy>0 → scrollTop 变大 lastY = y; moved += Math.abs(dy); const max = l.scrollHeight - l.clientHeight; if (max <= 2) return; // 列表还是没被限高,滚不了 if (e.defaultPrevented) hijack = true; else if (!hijack && moved > 12 && Math.abs(l.scrollTop - startTop) < 2) hijack = true; if (hijack) { const next = Math.max(0, Math.min(max, l.scrollTop + dy)); if (next !== l.scrollTop) l.scrollTop = next; if (e.cancelable) e.preventDefault(); // 掐掉页面滚动,避免两头一起动 } }, { capture: true, passive: false }); const reset = function () { active = false; hijack = false; }; document.addEventListener('touchend', reset, { capture: true, passive: true }); document.addEventListener('touchcancel', reset, { capture: true, passive: true }); } /* 控制栏最右侧那个全屏键 —— 只在兜底时才用(见 liveEnterFullscreen 说明) */ function liveFindFullscreenButton() { const wrap = document.querySelector('#fullscreen-container') || document.body; const ctrl = wrap.querySelector('#web-player-controller-wrap-el') || wrap.querySelector('.web-player-controller-wrap') || wrap.querySelector('[class*="web-player-controller"]'); if (!ctrl) return null; // 探针「按键」实测:控制栏 = .control-area > .left-area / .right-area, // 全屏键在 .right-area 最右端(right=777,与 .right-area 右边缘齐平) const area = ctrl.querySelector('.right-area') || ctrl.querySelector('[class*="right-area"]') || ctrl; let best = null, bestScore = -1, bestRight = -Infinity; const nodes = area.querySelectorAll( 'button, [role="button"], [class*="tip-wrap"], [class*="btn"], [class*="icon"], ' + '[class*="full"], [class*="screen"]' ); Array.prototype.forEach.call(nodes, function (el) { const tag = (el.tagName || '').toLowerCase(); if (tag === 'svg' || tag === 'path' || tag === 'g') return; // 图标内部节点,点了不触发 const r = el.getBoundingClientRect(); // 只认图标级小元素,排除整条 .right-area(597 宽) if (r.width < 8 || r.height < 8 || r.width > 80 || r.height > 80) return; const cls = (typeof el.className === 'string' ? el.className : '') || ''; const aria = (el.getAttribute && el.getAttribute('aria-label')) || ''; const key = cls + ' ' + aria + ' ' + (el.textContent || ''); let score = 0; if (/full|screen|全屏/i.test(key)) score += 4; // 明确是全屏键 if (tag === 'button' || el.getAttribute('role') === 'button') score += 2; if (/tip-wrap|btn|button/i.test(cls)) score += 1; // 按钮外层,比内部 span 稳 if (score > bestScore || (score === bestScore && r.right > bestRight)) { best = el; bestScore = score; bestRight = r.right; } }); return best; } /* ===== 直播间:双击 = 进出「原生全屏」 ===== 目标行为(v131.89 收紧为**严格二态**): · 未开全屏 → 双击进入**原生全屏**(没有浏览器地址栏) · 已开原生全屏 → 双击退出全屏,回到普通态(播放器 16:9 + 评论区在下) 为什么不再点站内那个键: 实测它切出来的是「网页全屏」body.player-full-win —— 带浏览器地址栏, 底部还留着给礼物栏的 84px 空档,而且会把播放器写死成 668px 定宽。 上一版正是"无条件点那个键",才出现 · 未开全屏双击没反应(控制栏未渲染时找不到键,退回的 API 调用也没生效) · 全屏中双击在"正常全屏 ↔ 带地址栏的全屏"之间来回跳 v131.90 的三条修复(v131.89 只做了第 2 条,判定没改,所以现象"没变化"): 1) ★根因★ isLiveFullscreen 只认原生全屏,删掉"尺寸启发式" —— 旧版一看播放器贴满视口就判"全屏",于是退出原生全屏后站内补的 假全屏被当成全屏、还被写成 100%/100%,真就铺满视口(带地址栏)。 现在假全屏一律判"非全屏",被强制压回 16:9,双击自然回到普通态。 2) 退出原生全屏的瞬间,站内有概率补 class / 写行内 fixed 定位, 由 liveExitFullscreen 连清几拍 + bindLiveWebFullscreenGuard 常驻清理, 行内 position/inset 也被写回 relative/auto(行内 !important 只能这样顶) 3) 返回键交给浏览器自身:它本来就会用第一次返回退出全屏, 假全屏被压回普通态后,"第一次=退全屏、第二次=离开页面"自动成立 进全屏仍带一条自愈链:依次试 #fullscreen-container / #live-player / .player-section,并对每个候选做结果复核 —— 有些浏览器是 promise 不 reject 但实际压根没进全屏,400ms 后复查一次,没进就换下一个候选; 三个都失败才退回点站内那个键(老浏览器没有 Fullscreen API 时的最后退路)。 —— 状态判断、事件拦截、触发点击,CSS 都做不到,这一处只能 JS。 ---- */ // 由 fullscreenchange 置位:用来区分"请求失败"和"进来又被人手动退出了" let liveFsSawFs = false; // 只有 iOS Safari 这类不支持元素级 requestFullscreen 的浏览器才会置位: // 表示"当前的全屏其实是站内自造的假全屏",此时仍要按全屏铺满(否则双击等于没反应) let liveFsViaButton = false; function liveIsNativeFs() { return !!(document.fullscreenElement || document.webkitFullscreenElement); } function liveExitNativeFullscreen() { const exit = document.exitFullscreen || document.webkitExitFullscreen || document.webkitCancelFullScreen || document.msExitFullscreen; if (!exit) return false; try { const p = exit.call(document); if (p && p.catch) p.catch(function () {}); } catch (e) { return false; } return true; } /* 退出全屏:API 退出 + 把站内随后补上的假全屏清干净。 站内补发的时机不定(实测在下一帧到几百毫秒之间),所以连清几拍: · class(player-full-win) · 容器链的行内 fixed / inset / z-index(行内 !important,只能清行内) · 播放器链的行内尺寸(applyLivePlayerSize 写回 16:9) 每次清理后都要 syncLiveFullscreen(),好让 bili-live-fs 立刻摘掉。 */ function liveExitFullscreen() { liveFsViaButton = false; const clean = function () { const a = liveDropWebFullscreenClass(); const b = !liveIsNativeFs() ? resetLiveFakeFullscreenInline() : false; syncLiveFullscreen(); applyLivePlayerSize(); return a || b; }; clean(); const ok = liveExitNativeFullscreen(); [0, 60, 150, 300, 600, 1000, 1600].forEach(function (ms) { setTimeout(clean, ms); }); return ok; } function liveClickFsButton() { const btn = liveFindFullscreenButton(); if (!btn) return false; liveFsViaButton = true; // 这一路切出来的是站内假全屏,只能认它 btn.click(); return true; } function liveEnterFullscreen() { const cands = ['#fullscreen-container', '#live-player', '.player-section']; liveFsSawFs = false; let done = false; const tryOne = function (idx) { if (done) return; if (idx >= cands.length) { done = true; liveClickFsButton(); return; } const el = document.querySelector(cands[idx]); const req = el && (el.requestFullscreen || el.webkitRequestFullscreen || el.webkitRequestFullScreen || el.msRequestFullscreen); if (!req) { tryOne(idx + 1); return; } let p = null; try { p = req.call(el); } catch (e) { tryOne(idx + 1); return; } if (p && p.then) { p.then(function () { done = true; }, function () { if (!liveIsNativeFs()) tryOne(idx + 1); }); } // 复核:没收到过 fullscreenchange、现在也没在全屏,才算这次尝试失败 setTimeout(function () { if (done || liveFsSawFs || liveIsNativeFs()) return; tryOne(idx + 1); }, 400); }; tryOne(0); return true; } /* 严格二态:全屏中 -> 退出;否则 -> 进原生全屏。 中间的"站内假全屏"不是一个合法状态 —— 进之前先把它清掉, 免得 requestFullscreen 被站内的状态机带偏。 */ function liveToggleFullscreen() { if (liveIsNativeFs()) return liveExitFullscreen(); // 只有 iOS 兜底那条路会是真的假全屏,点站内键退出它 if (liveFsViaButton) { liveFsViaButton = false; const hit = liveClickFsButton(); setTimeout(function () { liveFsViaButton = false; syncLiveFullscreen(); applyLivePlayerSize(); }, 300); return hit; } liveDropWebFullscreenClass(); resetLiveFakeFullscreenInline(); return liveEnterFullscreen(); } // 切换后按站内重排的节奏复核几次:状态类 + 尺寸都要跟上 function liveAfterToggle() { [60, 200, 400, 900].forEach(function (ms) { setTimeout(function () { syncLiveFullscreen(); applyLivePlayerSize(); applyLiveControllerGeom(); // v132.05:切全屏后重新测偏移 }, ms); }); } function bindLiveDblclickFullscreen() { if (!isLiveRoomPage() || bindLiveDblclickFullscreen._done) return; bindLiveDblclickFullscreen._done = true; let lastTapT = 0, lastTapX = 0, lastTapY = 0, lastHandledT = 0, lastHandledSrc = ''; // 只认落在播放器画面上的操作:控制栏自己身上的双击不抢 const inPlayer = function (t) { if (!t || !t.closest) return false; // v132.02:探针(探测脚本 v3.4)在全屏时会被搬进 #fullscreen-container, // 它虽在播放器容器内却不是画面,双击它不该切换全屏 if (t.closest('#__probe_btn, #__probe_panel')) return false; if (!t.closest('#fullscreen-container, #live-player')) return false; if (t.closest('#web-player-controller-wrap-el, .web-player-controller-wrap, .control-area')) return false; return true; }; window.addEventListener('dblclick', function (e) { if (!inPlayer(e.target)) return; const now = Date.now(); // 手机上手势已经被 touchstart 那条处理过,浏览器紧跟着合成的 dblclick // 会让同一次双击被切换两次(等于没切 / 或切到另一个全屏态),这里挡掉 if (now - lastHandledT < 700 && lastHandledSrc === 'touch') return; e.preventDefault(); e.stopPropagation(); if (e.stopImmediatePropagation) e.stopImmediatePropagation(); lastHandledT = now; lastHandledSrc = 'dbl'; liveToggleFullscreen(); liveAfterToggle(); }, true); // 站内若走 touch 而非 dblclick,这里兜住;lastHandledT 防与 dblclick 重复触发 window.addEventListener('touchstart', function (e) { if (!e.touches || e.touches.length !== 1) return; if (!inPlayer(e.target)) return; const t = e.touches[0]; const now = Date.now(); if (now - lastHandledT < 700) return; if (now - lastTapT < 300 && Math.abs(t.clientX - lastTapX) < 40 && Math.abs(t.clientY - lastTapY) < 40) { lastTapT = 0; lastHandledT = now; lastHandledSrc = 'touch'; e.stopPropagation(); if (e.stopImmediatePropagation) e.stopImmediatePropagation(); liveToggleFullscreen(); liveAfterToggle(); return; } lastTapT = now; lastTapX = t.clientX; lastTapY = t.clientY; }, true); } /* ============================================================ ---- 首屏零闪(JS 兜底):元素一插进 DOM 就立刻藏 ---- 样式表第 12 段已经用不依赖 body class 的选择器把这些元素 display:none 了,理论上样式表在 document-start 注入、元素一解析 出来就是隐藏的。但实测仍有"先显示一下再隐藏",说明在部分 移动端脚本环境里脚本并不是真的在文档开始时执行 —— 页面已经画过一帧,CSS 再补就必然有闪。 CSS 管不到"脚本来晚了"这种情况,只能靠 JS 在**能跑的第一刻** 就动手,并且盯着 DOM:节点刚被插进来(哪怕还没画到屏幕) 就立刻写行内 display:none,把可见时间压到最短。 行内 !important 只用于"藏",不碰任何几何/动画属性, 不影响站内其它逻辑。 ---- */ const LIVE_CHROME_SEL = [ '#room-ssr-vm', '.link-navbar-ctnr', '.link-navbar-wrap', 'nav.link-navbar', '.link-navbar', '#head-info-vm', '#gift-control-vm', '#rank-list-vm', '#rank-list-ctnr-box', '#sections-vm', '#sidebar-vm', '#room-background-vm', '#gift-screen-animation-vm', '#guard-popup', 'footer.link-footer' ].join(','); function hideChromeEl(el) { if (!el || !el.style) return; const st = el.style; if (st.getPropertyValue('display') !== 'none') { st.setProperty('display', 'none', 'important'); } if (st.getPropertyValue('visibility') !== 'hidden') { st.setProperty('visibility', 'hidden', 'important'); } } /* main.app-content 的 padding-top:74px 是顶部栏留的位置, 顶部栏一藏它就是无来由的一块空白,顺手按当前页面状态归零。 */ function fixChromePadding() { const m = document.querySelector && document.querySelector('main.app-content'); if (!m || !m.style) return; let pt = 0; try { pt = parseFloat(window.getComputedStyle(m).paddingTop) || 0; } catch (e) {} if (pt > 40) m.style.setProperty('padding-top', '0px', 'important'); } function sweepLiveChrome() { if (!isLiveRoomPage()) return; if (!document.querySelectorAll) return; const list = document.querySelectorAll(LIVE_CHROME_SEL); for (let i = 0; i < list.length; i++) hideChromeEl(list[i]); fixChromePadding(); } function bindEarlyChromeHide() { if (!isLiveRoomPage() || bindEarlyChromeHide._done) return; bindEarlyChromeHide._done = true; let pending = false; const raf = window.requestAnimationFrame ? window.requestAnimationFrame.bind(window) : function (fn) { return setTimeout(fn, 16); }; const schedule = function () { if (pending) return; pending = true; raf(function () { pending = false; sweepLiveChrome(); }); }; const attach = function () { const target = document.documentElement; if (!target) { setTimeout(attach, 0); return; } sweepLiveChrome(); // 盯着整个文档:节点一被插入(含 SSR 解析、JS 后插)就立刻藏, // 不等下一帧布局,把可见窗口压到最短 const mo = new MutationObserver(schedule); mo.observe(target, { childList: true, subtree: true }); document.addEventListener('DOMContentLoaded', sweepLiveChrome, true); window.addEventListener('load', sweepLiveChrome, true); // 只是为了压住"首屏那一下"。稳定期交给样式表(CSS 一直在), // 15 秒后停掉监听,省得跟着弹幕插入一直空跑。 setTimeout(function () { try { mo.disconnect(); } catch (e) {} }, 15000); }; attach(); } function start() { installShadowRootPatch(); bindEarlyChromeHide(); // v132.07:能跑的第一刻就藏顶部栏等(先于样式表) injectStyle(); applyPageClassEarly(); fixViewport(); createSearchBar(); bindLiveFullscreenWatch(); bindLivePlayerSizeWatch(); bindLiveDblclickFullscreen(); bindLiveWebFullscreenGuard(); bindLiveBackExitFullscreen(); bindLiveControllerWatch(); bindLiveLongPressGuard(); bindLiveChatScroll(); bindLiveControllerCompLoop(); const runAll = () => { run(); setTimeout(run, 300); setTimeout(run, 800); setTimeout(run, 1500); setTimeout(run, 3000); setTimeout(run, 5000); setTimeout(run, 8000); setTimeout(run, 12000); }; if (document.readyState === 'loading') { document.addEventListener('DOMContentLoaded', runAll); } else { runAll(); } window.addEventListener('load', runAll); const observer = new MutationObserver(() => { if (observer._t) clearTimeout(observer._t); observer._t = setTimeout(() => { run(); }, 200); }); const observeStart = () => { if (!document.body) { setTimeout(observeStart, 50); return; } observer.observe(document.body, { childList: true, subtree: true }); }; observeStart(); } start(); })();