简单·易上手·自认为挺好看的洛谷 UI 优化教程
AstralBrahma · · 科技·工程
:::warning[叠甲]{open}
作者并没有了解过这个行业的行情,因此,做出来的状物仅供分享。做出来的状物也是按照作者自己的喜好,并没有做过市场调研,如果有问题的地方请大家多多包涵,感谢各位。( •̀ ω •́ )✧
:::
下面的一切操作都是在 Stylus 中进行,这是一个插件,可以在 Edge 或者 Google 中下载,至于其他的浏览器就不知道啦,可以自己搜索一下。
我们知道,洛谷的首页 UI 确实已经更新过一次了,但是还是有不小的问题,即使现在的图片背景已经可以覆盖题目,比赛等处,但是仍然有很大一部分是没有的。得益于之前 6 月末,新 UI 上线的时候的一堆 bug,我从 Super_Masarada 那里知道了可以通过 Stylus 进行修复,然后在昨天(9 月 20 日)我莫名其妙又想起来了这个插件,同时又因为自己换了背景,感觉不能在很多地方显示背景很亏,因此,我选择 GPT 出马(由于你谷主页 UI 确实一坨,导致了 GPT 大神也会有失足的情况,具体的过程可以看我最后的分享)
下面是一些优化前后的对比图(此处使用的号为 Aesthete)
:::info[首页]{open}
:::
:::info[首页讨论区]{open}
:::
::::info[首页犇犇]{open}
:::warning[叠甲]{open} 这里只是做一个演示,还请 albertting 同志别骂我 (╥﹏╥)。 :::
::::
:::info[个人主页]{open}
:::
::::info[个人练习情况]{open}
:::warning[叠甲]{open} 这里依旧只是做一个演示,还请 albertting 同志别骂我 (╥﹏╥)。 :::
::::
::::info[专栏]{open} :::warning[叠甲]{open} 这里使用的是 LCA 老师的文章,感谢 LCA 老师对 OI 的贡献 orz。 :::
::::info[用户浮窗]{open}
:::warning[叠加]{open}
这里使用的是 chen_zhe 老师的账户 完了我居然没有关注 chen_zhe 老师,他不会记仇吧,一会补上 (つ﹏⊂)。
:::
:::info[左右侧栏]{open}
| |
|---|
:::info[顶部]{open}
基本上的效果展示就是上述部分,接下来就是配置的环节。首先你需要一个 Stylus。
安装好 Stylus 的插件之后,回到洛谷首页,点击插件。
请注意这里一定要点击 [www.luogu.com.cn](),而不是 [luogu.com.cn](),否则,在结束之后,你就会得到一个残破的网校以及帮助中心。
点击之后,会有一个编辑的界面,如下图。
左侧我们只会用到保存键(Save),右侧请注意需要选中 URLs on the domain,如果是中文版的话应该就是域名,然后右侧就是我们编辑的地方了。
我们需要建立两个代码,分别作用于洛谷主站和洛谷的文章(article)部分,如图:
请注意,第二个我们需要选择 URLs matching the regexp,也就是正则表达式,应该是下拉栏里面的最后一个,然后后面的连接应该是 [^https://www\.luogu\.com\.cn/article/.*]() 不要打漏了。
接下来把下面的两个代码分别填到上下的两个代码框内,点击 Save 即可。
:::success[Code 1]
/* Luogu Glass UI - Refactored v2 */
:root {
--page-bg: url("https://cdn.luogu.com.cn/upload/image_hosting/ciebmdnk.png");
--page-fallback: #142338;
--nav-glass: rgba(20, 35, 56, 0.28);
--panel-glass: rgba(255, 255, 255, 0.40);
--section-glass: rgba(236, 242, 248, 0.27);
--card-glass: rgba(238, 243, 248, 0.30);
--feed-glass: rgba(240, 245, 250, 0.55);
--editor-glass: rgba(236, 242, 248, 0.42);
--tab-panel-glass: rgba(236, 242, 248, 0.38);
--profile-card-glass: rgba(238, 243, 248, 0.48);
--profile-inner-glass: rgba(245, 248, 252, 0.36);
--profile-frame-glass: rgba(245, 248, 252, 0.16);
--profile-rating-glass: rgba(238, 243, 248, 0.62);
--blur-nav: blur(12px);
--blur-card: blur(18px);
--radius-card: 8px;
--radius-panel: 10px;
--radius-section: 13px;
}
/* 1. 新版页面:基础背景与导航 */
html,
body {
background: var(--page-fallback) !important;
}
.theme-page {
background: transparent !important;
}
.theme-page::before {
position: fixed !important;
inset: 0 !important;
width: 100vw !important;
height: 100vh !important;
background-position: center center !important;
background-size: cover !important;
background-repeat: no-repeat !important;
-webkit-mask-image: none !important;
mask-image: none !important;
pointer-events: none !important;
}
.sidebar,
.lside.bar {
background: var(--nav-glass) !important;
-webkit-backdrop-filter: var(--blur-nav) !important;
backdrop-filter: var(--blur-nav) !important;
border: none !important;
box-shadow: none !important;
transform: translate3d(0, 0, 0);
}
top-bar,
.top-bar {
background: linear-gradient( to bottom, rgba(20, 35, 56, 0.24) 0%, rgba(20, 35, 56, 0.20) 55%, rgba(20, 35, 56, 0.12) 82%, rgba(20, 35, 56, 0.06) 100% ) !important;
-webkit-backdrop-filter: var(--blur-nav) !important;
backdrop-filter: var(--blur-nav) !important;
border: none !important;
box-shadow: none !important;
}
top-bar::after,
.top-bar::after {
content: "";
position: absolute;
left: 0;
right: 0;
bottom: -16px;
height: 16px;
background: linear-gradient( to bottom, rgba(20, 35, 56, 0.06), transparent );
pointer-events: none;
}
/* 题库、题目页、个人主页共用同一套右上角玻璃 */
.user-nav {
background: transparent !important;
isolation: isolate;
}
.user-nav::before {
content: "";
position: absolute;
inset: 0;
z-index: -1;
background: var(--nav-glass);
-webkit-backdrop-filter: var(--blur-nav);
backdrop-filter: var(--blur-nav);
pointer-events: none;
}
/* 2. 旧版首页:背景与导航 */
html:has(#app-old),
html:has(#app-old) body,
body:has(#app-old) #app {
background-image: var(--page-bg) !important;
background-position: center center !important;
background-size: cover !important;
background-repeat: no-repeat !important;
background-attachment: fixed !important;
background-color: var(--page-fallback) !important;
}
body:has(#app-old) #app-old,
body:has(#app-old) main.lfe-body,
body:has(#app-old) .main-wrapper.lfe-body,
body:has(#app-old) .main-container,
body:has(#app-old) .main-container > main,
body:has(#app-old) .main-container > div,
body:has(#app-old) .background {
background: transparent !important;
}
body:has(#app-old) .background {
filter: none !important;
}
body:has(#app-old) #app > nav.lfe-body {
background: var(--nav-glass) !important;
-webkit-backdrop-filter: var(--blur-nav) !important;
backdrop-filter: var(--blur-nav) !important;
border: none !important;
box-shadow: none !important;
}
body:has(#app-old) #app > nav.lfe-body > div:first-child {
background: transparent !important;
}
body:has(#app-old) #app > .top-bar,
body:has(#app-old) > .header,
body:has(#app-old) .header-layout.tiny {
background: var(--nav-glass) !important;
-webkit-backdrop-filter: var(--blur-nav) !important;
backdrop-filter: var(--blur-nav) !important;
border: none !important;
outline: none !important;
box-shadow: none !important;
}
body:has(#app-old) .header,
body:has(#app-old) .header-layout,
body:has(#app-old) header.theme-bg {
border: none !important;
outline: none !important;
box-shadow: none !important;
}
body:has(#app-old) header.theme-bg {
background-color: transparent !important;
background-image: none !important;
}
/* 旧首页不使用新版顶栏下方渐隐 */
body:has(#app-old) top-bar::after,
body:has(#app-old) .top-bar::after,
body:has(#app-old) #app > .top-bar::before,
body:has(#app-old) #app > .top-bar::after {
display: none !important;
}
/* 3. 旧版首页:普通卡片 */
body:has(#app-old) .lg-article,
body:has(#app-old) .lg-summary,
body:has(#app-old) .lg-article-sub,
body:has(#app-old) .card {
background: var(--panel-glass) !important;
-webkit-backdrop-filter: blur(12px) !important;
backdrop-filter: blur(12px) !important;
border: none !important;
border-radius: var(--radius-panel) !important;
box-shadow: 0 4px 16px rgba(0, 0, 0, 0.08) !important;
overflow: hidden !important;
}
/* 4. 旧版首页:近期比赛 / 最近讨论 */
body:has(#app-old) .lg-article:has(.lg-index-contest.am-panel) {
background: var(--section-glass) !important;
-webkit-backdrop-filter: var(--blur-card) saturate(120%) brightness(1) !important;
backdrop-filter: var(--blur-card) saturate(120%) brightness(1) !important;
border: none !important;
border-radius: var(--radius-section) !important;
box-shadow: 0 5px 18px rgba(0, 0, 0, 0.08) !important;
overflow: hidden !important;
}
body:has(#app-old) .lg-index-contest {
background: var(--card-glass) !important;
-webkit-backdrop-filter: var(--blur-card) saturate(115%) brightness(0.98) !important;
backdrop-filter: var(--blur-card) saturate(115%) brightness(0.98) !important;
border: none !important;
border-radius: var(--radius-card) !important;
box-shadow: 0 4px 16px rgba(0, 0, 0, 0.09) !important;
color: rgba(35, 40, 47, 0.92) !important;
overflow: hidden !important;
text-shadow: none !important;
}
body:has(#app-old) .lg-index-contest * {
text-shadow: none !important;
}
body:has(#app-old) .lg-index-contest .am-panel-bd,
body:has(#app-old) .lg-index-contest .lg-inline-up {
background: transparent !important;
}
body:has(#app-old) .lg-index-contest .am-panel-bd {
color: rgba(40, 45, 52, 0.90) !important;
}
body:has(#app-old) .lg-index-contest.am-panel-success .am-panel-hd,
body:has(#app-old) .lg-index-contest.am-panel-danger .am-panel-hd {
background: rgba(226, 241, 224, 0.48) !important;
}
body:has(#app-old) .lg-index-contest.am-panel-primary .am-panel-hd {
background: transparent !important;
}
body:has(#app-old) .lg-index-contest .am-text-grey,
body:has(#app-old) .lg-index-contest .am-text-default,
body:has(#app-old) .lg-index-contest small {
color: rgba(45, 50, 58, 0.82) !important;
}
/* 5. 旧版首页:犇犇 */
body:has(#app-old) .lg-index-benben,
body:has(#app-old) #feed,
body:has(#app-old) #feed > li,
body:has(#app-old) #feed .am-comment {
background: transparent !important;
-webkit-backdrop-filter: none !important;
backdrop-filter: none !important;
border: none !important;
box-shadow: none !important;
}
/* 发射犇犇 */
body:has(#app-old) .lg-article:has(#feed-content) {
background: var(--editor-glass) !important;
-webkit-backdrop-filter: var(--blur-card) saturate(120%) !important;
backdrop-filter: var(--blur-card) saturate(120%) !important;
border: none !important;
border-radius: var(--radius-section) !important;
box-shadow: 0 5px 18px rgba(0, 0, 0, 0.08) !important;
padding: 26px 28px !important;
overflow: hidden !important;
}
body:has(#app-old) .lg-article:has(#feed-content) > h2 {
background: transparent !important;
}
body:has(#app-old) #feed-content {
background: rgba(255, 255, 255, 0.64) !important;
-webkit-backdrop-filter: blur(10px) !important;
backdrop-filter: blur(10px) !important;
border: 1px solid rgba(255, 255, 255, 0.62) !important;
border-radius: var(--radius-card) !important;
color: rgba(30, 34, 40, 0.94) !important;
box-shadow: none !important;
}
body:has(#app-old) #feed-submit {
border-radius: var(--radius-card) !important;
}
/* 我关注的 / 我发布的 */
body:has(#app-old) .lg-article:has(#home-center-nav) {
background: var(--tab-panel-glass) !important;
-webkit-backdrop-filter: var(--blur-card) saturate(120%) !important;
backdrop-filter: var(--blur-card) saturate(120%) !important;
border: none !important;
border-radius: var(--radius-section) !important;
box-shadow: 0 5px 18px rgba(0, 0, 0, 0.08) !important;
padding: 18px !important;
overflow: hidden !important;
}
body:has(#app-old) #home-center-nav {
background: rgba(255, 255, 255, 0.18) !important;
-webkit-backdrop-filter: blur(10px) !important;
backdrop-filter: blur(10px) !important;
border: none !important;
border-radius: 11px !important;
overflow: hidden !important;
}
body:has(#app-old) #home-center-nav > li > a {
background: transparent !important;
border: none !important;
border-radius: var(--radius-card) !important;
}
body:has(#app-old) #home-center-nav > li.am-active > a {
background: rgba(104, 153, 215, 0.78) !important;
color: #fff !important;
}
/* 每一条犇犇 */
body:has(#app-old) #feed .am-comment-main {
background: var(--feed-glass) !important;
-webkit-backdrop-filter: var(--blur-card) saturate(120%) brightness(0.99) !important;
backdrop-filter: var(--blur-card) saturate(120%) brightness(0.99) !important;
border: none !important;
border-radius: var(--radius-panel) !important;
box-shadow: 0 5px 18px rgba(0, 0, 0, 0.08) !important;
overflow: hidden !important;
text-shadow: none !important;
}
body:has(#app-old) #feed .am-comment-main * {
text-shadow: none !important;
}
body:has(#app-old) #feed .am-comment-hd,
body:has(#app-old) #feed .am-comment-bd {
background: transparent !important;
}
body:has(#app-old) #feed .am-comment-hd {
border-bottom: 1px solid rgba(255, 255, 255, 0.20) !important;
color: rgba(65, 70, 78, 0.66);
}
body:has(#app-old) #feed .am-comment-hd span {
color: rgba(65, 70, 78, 0.66);
}
body:has(#app-old) #feed .am-comment-bd {
color: rgba(32, 37, 44, 0.92) !important;
}
body:has(#app-old) #feed .am-comment-main::before,
body:has(#app-old) #feed .am-comment-main::after {
display: none !important;
}
/* 6. 个人主页:使用已确认的 main > full-container > l-card > 头图结构识别页面。 */
html:has(:where(main > .full-container.columba-content-wrap > .l-card) > .user-header-top),
html:has(:where(main > .full-container.columba-content-wrap > .l-card) > .user-header-top) body,
body:has(:where(main > .full-container.columba-content-wrap > .l-card) > .user-header-top) #app {
background-image: var(--page-bg) !important;
background-position: center center !important;
background-size: cover !important;
background-repeat: no-repeat !important;
background-attachment: fixed !important;
background-color: var(--page-fallback) !important;
}
body:has(:where(main > .full-container.columba-content-wrap > .l-card) > .user-header-top) main,
body:has(:where(main > .full-container.columba-content-wrap > .l-card) > .user-header-top) .lcolor-bg-grey-1,
body:has(:where(main > .full-container.columba-content-wrap > .l-card) > .user-header-top) .columba-content-wrap,
body:has(:where(main > .full-container.columba-content-wrap > .l-card) > .user-header-top) .full-container {
background: transparent !important;
}
/* 个人主页头图 / 用户浮窗:仅修改卡片本身,不触发整页样式。 */
body .l-card:has(> .user-header-top) {
background: var(--profile-frame-glass) !important;
-webkit-backdrop-filter: blur(18px) saturate(135%) !important;
backdrop-filter: blur(18px) saturate(135%) !important;
border: 1px solid rgba(255, 255, 255, 0.32) !important;
border-radius: 14px !important;
box-shadow: 0 10px 32px rgba(0, 0, 0, 0.16), inset 0 1px 0 rgba(255, 255, 255, 0.24) !important;
overflow: hidden !important;
}
/* 封面与用户名区域不额外虚化;不覆盖 user-header-top 的背景图 */
body .l-card > .user-header-top {
-webkit-backdrop-filter: none !important;
backdrop-filter: none !important;
border: none !important;
box-shadow: none !important;
}
body .l-card:has(> .user-header-top) .user-info {
background-color: transparent !important;
-webkit-backdrop-filter: none !important;
backdrop-filter: none !important;
border: none !important;
box-shadow: none !important;
}
/* 主页 / 动态 / 练习 / 关注等底栏 */
body:has(:where(main > .full-container.columba-content-wrap > .l-card) > .user-header-top) .user-header-bottom {
background: rgba(238, 243, 248, 0.20) !important;
-webkit-backdrop-filter: blur(18px) saturate(120%) !important;
backdrop-filter: blur(18px) saturate(120%) !important;
border: none !important;
box-shadow: none !important;
}
/* 下方普通内容卡片 */
body:has(:where(main > .full-container.columba-content-wrap > .l-card) > .user-header-top) main .l-card:not(:has(> .user-header-top)) {
background: var(--profile-card-glass) !important;
-webkit-backdrop-filter: blur(18px) saturate(115%) brightness(0.99) !important;
backdrop-filter: blur(18px) saturate(115%) brightness(0.99) !important;
border: none !important;
border-radius: 11px !important;
box-shadow: 0 6px 20px rgba(0, 0, 0, 0.10) !important;
overflow: hidden !important;
}
body:has(:where(main > .full-container.columba-content-wrap > .l-card) > .user-header-top) main .inner-card {
background: var(--profile-inner-glass) !important;
-webkit-backdrop-filter: blur(12px) saturate(110%) !important;
backdrop-filter: blur(12px) saturate(110%) !important;
border: none !important;
border-radius: var(--radius-card) !important;
box-shadow: none !important;
}
/* 热度图:提高底色,降低背景干扰 */
body:has(:where(main > .full-container.columba-content-wrap > .l-card) > .user-header-top) main .l-card:has(.heatmap),
body:has(:where(main > .full-container.columba-content-wrap > .l-card) > .user-header-top) main .l-card:has([class*="heatmap"]) {
background: rgba(248, 250, 252, 0.82) !important;
-webkit-backdrop-filter: blur(8px) saturate(105%) !important;
backdrop-filter: blur(8px) saturate(105%) !important;
color: rgba(40, 44, 50, 0.94) !important;
border-radius: 11px !important;
box-shadow: 0 6px 20px rgba(0, 0, 0, 0.08) !important;
}
body:has(:where(main > .full-container.columba-content-wrap > .l-card) > .user-header-top) main .l-card:has(.heatmap) text,
body:has(:where(main > .full-container.columba-content-wrap > .l-card) > .user-header-top) main .l-card:has([class*="heatmap"]) text {
fill: rgba(70, 74, 82, 0.82) !important;
}
/* 7. 个人主页:Rating 图表专用修复 */
/* Rating 提示框沿用原生坐标系:卡片禁用背景模糊;勿增加 transform / position,勿修改 tooltip 的定位或显隐。 */
body:has(:where(main > .full-container.columba-content-wrap > .l-card) > .user-header-top) main .l-card:has(#rating-chart) {
background: var(--profile-rating-glass) !important;
-webkit-backdrop-filter: none !important;
backdrop-filter: none !important;
border: none !important;
border-radius: 11px !important;
box-shadow: 0 6px 20px rgba(0, 0, 0, 0.10) !important;
overflow: visible !important;
}
/* 只提高层级,不碰 tooltip 自己的定位和显隐逻辑 */
body:has(:where(main > .full-container.columba-content-wrap > .l-card) > .user-header-top) #rating-chart + .tooltip {
z-index: 2147483647 !important;
pointer-events: none !important;
}
/* 避免上层容器裁剪 tooltip */
body:has(:where(main > .full-container.columba-content-wrap > .l-card) > .user-header-top) main:has(#rating-chart),
body:has(:where(main > .full-container.columba-content-wrap > .l-card) > .user-header-top) .columba-content-wrap:has(#rating-chart),
body:has(:where(main > .full-container.columba-content-wrap > .l-card) > .user-header-top) .full-container:has(#rating-chart) {
overflow: visible !important;
}
/* 8. Footer */
/* 个人主页 Footer 延续背景图 */
body:has(:where(main > .full-container.columba-content-wrap > .l-card) > .user-header-top) footer {
background-image: var(--page-bg) !important;
background-position: center center !important;
background-size: cover !important;
background-repeat: no-repeat !important;
background-attachment: fixed !important;
background-color: transparent !important;
border: none !important;
box-shadow: none !important;
}
body:has(:where(main > .full-container.columba-content-wrap > .l-card) > .user-header-top) footer > * {
background: transparent !important;
}
/* 其他新版页面去掉 Footer 的额外模糊 */
body:not(:has(#app-old)):not(:has(:where(main > .full-container.columba-content-wrap > .l-card) > .user-header-top)) footer {
background: transparent !important;
-webkit-backdrop-filter: none !important;
backdrop-filter: none !important;
filter: none !important;
border: none !important;
box-shadow: none !important;
}
body:not(:has(#app-old)):not(:has(:where(main > .full-container.columba-content-wrap > .l-card) > .user-header-top)) footer::before,
body:not(:has(#app-old)):not(:has(:where(main > .full-container.columba-content-wrap > .l-card) > .user-header-top)) footer::after {
content: none !important;
background: transparent !important;
-webkit-backdrop-filter: none !important;
backdrop-filter: none !important;
filter: none !important;
}
/* 专栏 / 文章页兼容:保留原有匹配范围与覆盖顺序。 */
body:has(:is(.md-blog, .markdown-body, .blog-content)),
body:has(article) {
background-image: url("你所需的背景的链接") !important;
background-position: center center !important;
background-size: cover !important;
background-repeat: no-repeat !important;
background-attachment: fixed !important;
}
/* 先把专栏页外围各种底板清掉 */
body:has(:is(.md-blog, .markdown-body, .blog-content)) main,
body:has(article) main,
body:has(:is(.md-blog, .markdown-body, .blog-content)) .columba-content-wrap,
body:has(article) .columba-content-wrap,
body:has(:is(.md-blog, .markdown-body, .blog-content)) .l-container,
body:has(article) .l-container,
body:has(:is(.md-blog, .markdown-body, .blog-content)) .container,
body:has(article) .container,
body:has(:is(.md-blog, .markdown-body, .blog-content)) .row,
body:has(article) .row {
background: transparent !important;
box-shadow: none !important;
border: none !important;
}
/* 去掉文章页底部可能残留的深色/模糊块 */
body:has(:is(.md-blog, .markdown-body, .blog-content)) footer,
body:has(article) footer,
body:has(:is(.md-blog, .markdown-body, .blog-content)) .l-footer,
body:has(article) .l-footer,
body:has(:is(.md-blog, .markdown-body, .blog-content)) .l-footer-bg-background,
body:has(article) .l-footer-bg-background {
background: transparent !important;
-webkit-backdrop-filter: none !important;
backdrop-filter: none !important;
filter: none !important;
box-shadow: none !important;
border: none !important;
}
/* 专栏正文主卡片:大气泡 */
body:has(.md-blog) .l-card:has(.md-blog),
body:has(.markdown-body) .l-card:has(.markdown-body),
body:has(.blog-content) .l-card:has(.blog-content),
body:has(article) .l-card:has(article),
body:has(.md-blog) article,
body:has(.markdown-body) article,
body:has(.blog-content) .blog-content {
background: rgba(248, 251, 255, 0.92) !important;
-webkit-backdrop-filter: blur(18px) saturate(120%) !important;
backdrop-filter: blur(18px) saturate(120%) !important;
border: none !important;
border-radius: 12px !important;
box-shadow: 0 8px 28px rgba(0, 0, 0, 0.10) !important;
overflow: hidden !important;
}
/* 正文内部不要再自己铺底 */
body:has(.md-blog) .l-card:has(.md-blog) > *,
body:has(.markdown-body) .l-card:has(.markdown-body) > *,
body:has(.blog-content) .l-card:has(.blog-content) > *,
body:has(article) .l-card:has(article) > *,
body:has(.md-blog) .md-blog,
body:has(.markdown-body) .markdown-body,
body:has(.blog-content) .blog-content {
background: transparent !important;
}
/* 正文文字颜色加深,保证可读性 */
body:has(.md-blog) .md-blog,
body:has(.markdown-body) .markdown-body,
body:has(.blog-content) .blog-content,
body:has(article) article {
color: rgba(32, 36, 42, 0.96) !important;
}
/* 标题和元信息也不要太淡 */
body:has(:is(.md-blog, .markdown-body, .blog-content)) h1,
body:has(article) h1,
body:has(:is(.md-blog, .markdown-body, .blog-content)) h2,
body:has(article) h2,
body:has(:is(.md-blog, .markdown-body, .blog-content)) .header {
color: rgba(28, 32, 38, 0.96) !important;
}
/* 代码块、引用块单独浅底,否则正文会发飘 */
body:has(:is(.md-blog, .markdown-body, .blog-content)) pre,
body:has(article) pre,
body:has(:is(.md-blog, .markdown-body, .blog-content)) blockquote,
body:has(article) blockquote {
background: rgba(243, 246, 250, 0.88) !important;
border-radius: 10px !important;
border: none !important;
}
/* 行内 code 也稍微补一点底 */
body:has(:is(.md-blog, .markdown-body, .blog-content)) code,
body:has(article) code {
background: rgba(240, 244, 248, 0.92) !important;
border-radius: 6px !important;
}
/* 左侧点赞/收藏这一列,也改成小玻璃 */
body:has(:is(.md-blog, .markdown-body, .blog-content)) .side,
body:has(article) .side {
background: rgba(246, 249, 253, 0.78) !important;
-webkit-backdrop-filter: blur(14px) saturate(120%) !important;
backdrop-filter: blur(14px) saturate(120%) !important;
border: none !important;
border-radius: 12px !important;
box-shadow: 0 6px 20px rgba(0, 0, 0, 0.08) !important;
}
/* 右侧栏保持玻璃,但不要比正文更重 */
body:has(:is(.md-blog, .markdown-body, .blog-content)) aside .l-card,
body:has(article) aside .l-card,
body:has(:is(.md-blog, .markdown-body, .blog-content)) .right-wrap .l-card,
body:has(article) .right-wrap .l-card {
background: rgba(244, 248, 252, 0.82) !important;
-webkit-backdrop-filter: blur(14px) saturate(118%) !important;
backdrop-filter: blur(14px) saturate(118%) !important;
border: none !important;
border-radius: 12px !important;
box-shadow: 0 6px 20px rgba(0, 0, 0, 0.08) !important;
}
/* 避免正文区域下方再出现额外深色叠层 */
body:has(:is(.md-blog, .markdown-body, .blog-content)) .l-card::before,
body:has(article) .l-card::before,
body:has(:is(.md-blog, .markdown-body, .blog-content)) .l-card::after,
body:has(article) .l-card::after {
box-shadow: none !important;
}
:::
:::success[Code 2]
/* 洛谷专栏毛玻璃样式:合并版。所有规则仅在存在 #article-title 时生效。 */
/* 页面背景 */
html:has(#article-title),
html:has(#article-title) body {
background-image: url("你所需背景的链接") !important;
background-position: center center !important;
background-size: cover !important;
background-repeat: no-repeat !important;
background-attachment: fixed !important;
background-color: #142338 !important;
}
/* 页面外围透明 */
body:has(#article-title) #app,
body:has(#article-title) .main-container.lside-nav,
body:has(#article-title) main.lcolor-bg-background.main {
background: transparent !important;
}
/* 清除正文外层白底 */
body:has(#article-title) main.lcolor-bg-background.main > div[style*="background-color: rgb(255, 255, 255)"] {
background: transparent !important;
}
/* 标题玻璃:上方 16px,下方 20px */
body:has(#article-title) .article-banner.columba-content-wrap.wrapper {
background: rgba(238, 244, 250, 0.32) !important;
-webkit-backdrop-filter: blur(16px) saturate(120%) !important;
backdrop-filter: blur(16px) saturate(120%) !important;
border: none !important;
border-radius: 13px !important;
box-shadow: 0 8px 26px rgba(0, 0, 0, 0.10) !important;
overflow: visible !important;
margin-bottom: 20px !important;
margin-top: 16px !important;
}
/* 标题内部透明 */
body:has(#article-title) .article-banner .banner-content {
background: transparent !important;
}
/* 标题文字 */
body:has(#article-title) #article-title {
color: rgb(25, 28, 33) !important;
opacity: 1 !important;
text-shadow: none !important;
}
/* 作者、发布时间与分类 */
body:has(#article-title) .article-banner .meta,
body:has(#article-title) .article-banner .meta span,
body:has(#article-title) .article-banner .meta time {
color: rgb(50, 54, 61) !important;
opacity: 1 !important;
text-shadow: none !important;
}
/* 正文外层:清除顶部和左右留白 */
body:has(#article-title) .article-content.columba-content-wrap.wrapper {
background: transparent !important;
-webkit-backdrop-filter: none !important;
backdrop-filter: none !important;
border: none !important;
box-shadow: none !important;
overflow: visible !important;
box-sizing: border-box !important;
padding-left: 0 !important;
padding-right: 0 !important;
margin-top: 0 !important;
padding-top: 0 !important;
}
/* 清除正文外壳伪元素 */
body:has(#article-title) .article-content.columba-content-wrap.wrapper::before,
body:has(#article-title) .article-content.columba-content-wrap.wrapper::after {
content: none !important;
display: none !important;
}
/* 正文玻璃:左右内边距 24px */
body:has(#article-title) .article-content > .lfe-marked-wrap {
box-sizing: border-box !important;
padding: 28px 24px !important;
background: rgba(242, 247, 252, 0.55) !important;
-webkit-backdrop-filter: blur(18px) saturate(115%) !important;
backdrop-filter: blur(18px) saturate(115%) !important;
border: none !important;
border-radius: 13px 13px 0 0 !important;
box-shadow: 0 8px 28px rgba(0, 0, 0, 0.09) !important;
overflow: visible !important;
width: 100% !important;
max-width: none !important;
min-width: 0 !important;
margin-left: 0 !important;
margin-right: 0 !important;
margin-top: 0 !important;
}
/* 正文内容 */
body:has(#article-title) .article-content > .lfe-marked-wrap > .lfe-marked {
background: transparent !important;
margin: 0 !important;
width: auto !important;
max-width: none !important;
min-width: 0 !important;
}
/* 下方信息:与正文玻璃衔接 */
body:has(#article-title) .article-content > .update-info {
box-sizing: border-box !important;
padding: 12px 24px 24px !important;
background: rgba(242, 247, 252, 0.55) !important;
-webkit-backdrop-filter: blur(18px) saturate(115%) !important;
backdrop-filter: blur(18px) saturate(115%) !important;
border: none !important;
border-radius: 0 0 13px 13px !important;
margin-top: -1px !important;
box-shadow: 0 8px 28px rgba(0, 0, 0, 0.09) !important;
color: rgb(70, 74, 81) !important;
text-shadow: none !important;
width: 100% !important;
max-width: none !important;
margin-left: 0 !important;
margin-right: 0 !important;
}
/* 正文文字 */
body:has(#article-title) .article-content .lfe-marked,
body:has(#article-title) .article-content .lfe-marked p,
body:has(#article-title) .article-content .lfe-marked li {
color: rgb(25, 29, 35) !important;
opacity: 1 !important;
text-shadow: none !important;
}
/* 正文各级标题 */
body:has(#article-title) .article-content .lfe-marked h1,
body:has(#article-title) .article-content .lfe-marked h2,
body:has(#article-title) .article-content .lfe-marked h3,
body:has(#article-title) .article-content .lfe-marked h4,
body:has(#article-title) .article-content .lfe-marked h5,
body:has(#article-title) .article-content .lfe-marked h6 {
color: rgb(20, 23, 28) !important;
opacity: 1 !important;
text-shadow: none !important;
}
/* 收藏与点赞:向左偏移 28px */
body:has(#article-title) .article-content > .actions.left-mode {
z-index: 50 !important;
translate: -28px 0 !important;
background: rgba(248, 250, 253, 0.86) !important;
-webkit-backdrop-filter: blur(12px) saturate(115%) !important;
backdrop-filter: blur(12px) saturate(115%) !important;
border: none !important;
border-radius: 10px !important;
box-shadow: 0 5px 16px rgba(0, 0, 0, 0.10) !important;
}
/* 操作按钮内部透明 */
body:has(#article-title) .article-content > .actions.left-mode .button-2line {
background: transparent !important;
border: none !important;
box-shadow: none !important;
}
/* 隐藏底部重复操作按钮 */
body:has(#article-title) .article-content > .actions:not(.left-mode) {
display: none !important;
}
/* 目录外壳:向右偏移 16px */
body:has(#article-title) .article-content > .toc-wrapper {
background: transparent !important;
-webkit-backdrop-filter: none !important;
backdrop-filter: none !important;
border: none !important;
border-radius: 0 !important;
box-shadow: none !important;
overflow: visible !important;
translate: 16px 0 !important;
}
/* 清除目录外壳伪元素 */
body:has(#article-title) .article-content > .toc-wrapper::before,
body:has(#article-title) .article-content > .toc-wrapper::after {
content: none !important;
display: none !important;
}
/* 目录玻璃:加宽 8px,透明度 0.7 */
body:has(#article-title) .article-content > .toc-wrapper > .toc.with-top {
box-sizing: border-box !important;
padding: 18px 20px !important;
background: rgba(241, 246, 251, 0.7) !important;
-webkit-backdrop-filter: blur(14px) saturate(112%) !important;
backdrop-filter: blur(14px) saturate(112%) !important;
border: none !important;
border-radius: 10px !important;
box-shadow: 0 5px 18px rgba(0, 0, 0, 0.08) !important;
color: rgb(45, 49, 56) !important;
text-shadow: none !important;
width: calc(100% + 8px) !important;
max-width: none !important;
}
/* 清除目录玻璃伪元素 */
body:has(#article-title) .article-content > .toc-wrapper > .toc.with-top::before,
body:has(#article-title) .article-content > .toc-wrapper > .toc.with-top::after {
content: none !important;
display: none !important;
box-shadow: none !important;
}
/* 目录列表 */
body:has(#article-title) .article-content > .toc-wrapper > .toc.with-top > ul {
background: transparent !important;
-webkit-backdrop-filter: none !important;
backdrop-filter: none !important;
border: none !important;
box-shadow: none !important;
margin: 0 !important;
padding: 0 !important;
}
/* 目录项目 */
body:has(#article-title) .article-content > .toc-wrapper > .toc.with-top li {
background: transparent !important;
border: none !important;
box-shadow: none !important;
color: rgb(49, 53, 60) !important;
text-shadow: none !important;
}
/* 目录链接与文字 */
body:has(#article-title) .article-content > .toc-wrapper > .toc.with-top li span,
body:has(#article-title) .article-content > .toc-wrapper > .toc.with-top li a {
color: rgb(49, 53, 60) !important;
opacity: 1 !important;
text-shadow: none !important;
}
/* 评论区 */
body:has(#article-title) .article-comment.columba-content-wrap.wrapper {
background: rgba(242, 247, 252, 0.55) !important;
-webkit-backdrop-filter: blur(16px) saturate(115%) !important;
backdrop-filter: blur(16px) saturate(115%) !important;
border: none !important;
border-radius: 13px !important;
box-shadow: 0 8px 28px rgba(0, 0, 0, 0.09) !important;
margin-top: 20px !important;
}
/* 页脚 */
body:has(#article-title) footer {
background: transparent !important;
-webkit-backdrop-filter: none !important;
backdrop-filter: none !important;
filter: none !important;
border: none !important;
box-shadow: none !important;
}
/* 清除页脚伪元素 */
body:has(#article-title) footer::before,
body:has(#article-title) footer::after {
content: none !important;
}
/* 页脚内容透明 */
body:has(#article-title) footer > * {
background: transparent !important;
}
/* 窄窗口允许横向滚动 */
body:has(#article-title) {
overflow-x: auto !important;
}
:::
使用是简单的,这里的代码也是公示了,各位也可以拿着继续去开发,当然如果可以给我挂个名那就是最好的啦,我在此感谢各位了。
下面是一些闲话:
:::success[闲话]
这次对洛谷页面的改造,一开始其实没有打算做得这么大。最初的需求只有两个:把自己选的背景图完整铺到页面底部,以及让左侧导航栏变成毛玻璃。最开始遇到的问题也比较简单,背景虽然能显示出来,但页面高度变化之后底部会重新露出洛谷自己的底色,于是先从 html、body 和 .theme-page 入手,把背景固定到整个 viewport,用 background-size: cover 和 background-attachment: fixed 保证页面无论滚多长,最底下仍然是同一张背景图。左侧栏则直接给 .sidebar 增加半透明背景和 backdrop-filter: blur(...)。
做完左侧以后,很自然又开始处理顶部导航栏和右侧用户栏。顶部一开始直接使用和侧边栏相同的玻璃效果,但很快发现顶部和左右两侧的视觉区别很大,会出现一条很明显的横向边界。于是顶部改成带透明度渐变的玻璃,并在底边额外增加一段渐隐,让它不要像一块独立的矩形压在背景上。右上角的 .user-nav 也做了同样的处理,但这里后来反复出现过黑色遮罩和额外深色块,原因主要是原页面自己的 ::before、父级背景和我们增加的玻璃层叠到了一起。后面逐渐形成了一个比较重要的原则:能保留洛谷原本布局的地方尽量不重写布局,只处理真正负责显示背景的那一层。
接下来开始适配旧版首页。首页和题目页并不是同一套 DOM,旧首页有 #app-old,而且自身有大量灰白、深蓝色底板。最开始只是给首页也换上相同背景,然后清掉 #app-old、main.lfe-body、.main-wrapper 等外层的实色背景,再给顶部和左侧套上毛玻璃。之后才发现首页真正麻烦的不是大背景,而是内部大量不同结构的卡片。
第一次统一给 .lg-article、.lg-summary、.lg-article-sub 和 .card 加玻璃以后,页面虽然“玻璃化”了,但近期比赛、最近讨论这一类区域出现了很大的灰白底板。这里后来改成了两层逻辑:外层区域透明,真正的小卡片才负责玻璃。比如近期比赛最终定位到了 .lg-index-contest,而它的 .am-panel-bd 需要清掉原本白底,标题区 .am-panel-hd 则保留一点半透明的绿色。这样背景可以透过大区域,而每一场比赛仍然是一张独立的小卡片。
最近讨论也是类似的过程。一开始选择器定位错了,把整个区域做成了玻璃,效果反而像在页面上铺了一块大磨砂板。后来重新通过 F12 确认 DOM,只给实际讨论条目本身做圆角和毛玻璃。期间还碰到一个纯语法问题:Stylus 对多行 selector 的解析比较严格,像把 body:has(...) 和后面的 .xxx 拆成两行,会报 Line break in selector without "," or indent。后面所有选择器都改成完整的一行,多个 selector 才使用逗号换行,这类报错才彻底消失。
犇犇区域的问题更典型。最开始只给 #feed .am-comment-main 做玻璃,但外层仍然有白板;把外层全部透明以后,又发现“发射犇犇”的输入区域没有底板,看起来直接漂在背景上。后来通过 F12 确认了它前面实际上是两个相邻的 .lg-article:第一个包含输入框和“发射犇犇”按钮,第二个包含“我关注的 / 我发布的”切换栏。最终这两块重新做成独立玻璃面板,而每条犇犇仍然只给 .am-comment-main 加圆角玻璃。这样就避免了“圆角卡片外面还套着一块方形模糊层”的问题。
首页做完以后,又处理了右侧的本站公告、任务计划、友情链接等区域。这里基本延续同样的规则:真正的信息面板做玻璃和圆角,最外层布局容器保持透明。期间对文字可读性也做过几次调整。最开始尝试用浅色文字阴影提高复杂背景下的可读性,但实际效果很怪,特别是蓝色链接和灰色小字会有一种发光感,所以后来取消了文字阴影,改成直接提高文字本身的颜色对比度。这个经验后来也直接用到了专栏页:玻璃可以很透明,但文字颜色不应该跟着变浅。
在这一阶段代码已经积累了很多重复规则,同一个 .lg-article、.user-nav、.sidebar 在不同位置被反复覆盖。于是做过一次比较大的重构,把背景、导航栏、首页、个人主页等规则重新合并。后续版本又继续缩小圆角,最初偏大的卡片圆角大约整体减少了四成。另一条「专栏宽度修正」里也继续做过一次清理,当时把 CSS 中大量重复段落重新合并,规则块从大约 39 段收敛到 29 段,主样式文件也从约 890 行压到了约 663 行。不过当时主要是静态检查,并没有把所有页面逐一实际跑完,所以后面还是暴露出了一些布局问题。
之后开始处理个人主页。个人主页比首页复杂的一点是它自己还有一张用户头图,所以这里不能简单把所有 .l-card 都做成毛玻璃。最上面的用户头图要保留原图,只在整个用户信息区域外面增加类似苹果气泡玻璃的边框;下面的主页导航、做题热度图、Rating 趋势、右侧用户信息等才使用半透明卡片。
这里首先出现的问题是顶部右侧用户导航再次出现黑色遮罩,左侧和右侧侧边栏也有一部分透明过头。后来把首页和题目页已经验证过的 .user-nav 处理逻辑搬过来,避免重新写一套。个人主页底部导航 .user-header-bottom 也单独做了玻璃处理,因为它原本是一整块实色白板。热度图又有另一个问题:它虽然在玻璃上,但小色块和灰色说明文字对比度不足,所以没有继续提高整个玻璃的不透明度,而是对这一块单独提高了背景和文字对比度。
底部 footer 也反复处理过。最开始直接把 footer 背景清透明,但个人主页底部还是会露出一截白色;后面确认真实 DOM 就是 footer 本身,于是统一把 footer、它的伪元素以及内部额外底色全部清掉,让固定背景直接延伸到底部。另一方面,在题目页等普通页面上还存在一段底部模糊,因此又专门限制了 footer 规则的作用范围,避免个人主页的修复影响其他页面。
个人主页还有一个比较隐蔽的问题:练习页面 Rating 图表上的 tooltip 消失了。最开始一直从 CSS 猜是 overflow: hidden、z-index 或玻璃造成的,但后来 F12 找到了真实结构:canvas#rating-chart 后面就是一个 .tooltip,本身由脚本动态修改 opacity / left / top。这类问题最后的结论也是一样——不要随便在图表父级加 overflow: hidden 或建立新的定位上下文,否则原本正常的浮层会被裁掉。
最后进入专栏页以后,问题复杂度明显又上了一个档次。
最开始看到专栏整页还是白色,就按照之前首页的经验去猜 .md-blog、.markdown-body、.blog-content 和 article 等选择器,结果几乎完全没有变化。后来通过 F12 才确认了真实结构:页面主体是 main.lcolor-bg-background.main,标题区是 .article-banner.columba-content-wrap.wrapper,正文区域是 .article-content.columba-content-wrap.wrapper。正文内部又不是单纯一个 article,而是由 .lfe-marked-wrap、.update-info、两套 .actions 和 .toc-wrapper 组成。
确认真实 DOM 以后,先把专栏外围的纯白层清掉,让统一背景图露出来;标题区和正文再分别做玻璃。标题和正文之间后来固定留了大约 20px 的间隔,因为两块紧贴在一起时看起来像一个被硬切成两半的大卡片。
这里很快碰到了一个很明显的问题:玻璃透明度一降,黑色文字看起来也会“变灰”。实际上并不是文字真的变透明,而是背景透过以后整体视觉对比变弱。因此后来不再通过不断提高玻璃不透明度解决,而是直接把标题、元信息、正文、标题等文字颜色固定到接近纯黑的 RGB,并清掉 text-shadow。这样标题玻璃即使只有约 0.3 的不透明度,文字仍然能保持清楚;正文大约保持在 0.55 左右,也可以兼顾背景存在感和阅读体验。
左侧收藏、点赞、不推荐也是一段反复踩坑的地方。真实 DOM 是:
<div class="actions left-mode ...">
<div class="button-2line">...</div>
...
</div>
一开始正文父级使用 overflow: hidden,导致它的位置被裁剪;后来又尝试 position: sticky 和负 margin,结果它直接跑进正文中间。恢复洛谷自己的定位后,只给 .actions.left-mode 做玻璃视觉,并轻微向左平移约 12px。正文底部还有另一套 .actions,所以桌面端直接隐藏非 left-mode 的版本,避免同样三个按钮在文章末尾再出现一遍。
右侧目录的问题折腾得更多。一开始一直误以为它是 aside 或 nav,所以出现过“目录文字直接裸在背景上”“三层玻璃叠在一起”“目录把正文压住”等情况。最后通过 F12 找到了准确结构:
<div class="toc-wrapper">
<div class="toc with-top">
<ul>
<li class="title-0">...</li>
<li class="title-1">...</li>
...
</ul>
</div>
</div>
从这以后目录逻辑才稳定下来:.toc-wrapper 只负责洛谷原本的定位,本身完全透明,不加 blur、不加圆角、不加阴影;真正的 .toc.with-top 才是唯一的玻璃卡片;内部 ul / li 保持透明。这样目录后面不会再莫名其妙多一块第二层玻璃。
期间还尝试过把整个 .article-content 改成 Grid,想实现“正文 1fr + 16px gap + 自适应目录”的标准两栏布局。理论上结构很干净,但实际上洛谷的 .actions 和 .toc-wrapper 都依赖它自己的布局与定位,Grid 一套上去以后,标题与正文不再对齐,点赞栏挤进正文,目录被卡到屏幕外,还引入了横向滚动。这个方案最终直接放弃,重新回到“保留洛谷原生布局,只修改视觉”的路线。
当时专栏看起来明显偏窄,所以先尝试清正文外层的横向 padding,让正文玻璃吃满自身可用宽度,正文内边距改到大约 28px 24px,并清除内部内容额外的宽度限制。随后又调整了左侧操作栏和目录的位置:点赞栏额外向左拉开,目录向右移动一点,再把目录宽度略微增加。标题与顶栏之间增加约 16px,标题与正文之间保持 20px,同时清掉页面里额外的顶部空白。
但是宽度调整后来又走进了另一个坑。先后试过 1480px、1320px、82vw、1180px、1260px、clamp(...) 等方案,看起来是在“自适应”,实际却不断覆盖洛谷原生 .columba-content-wrap 的宽度逻辑。结果就是有时候仍然偏窄,有时候又几乎铺满整个屏幕,目录也会因为强制宽度把页面向右撑出去。后面已经确认,单纯猜一个 max-width 数字并不可靠;真正稳妥的办法应该是在“那版偏窄但布局正常”的代码上,通过浏览器 Computed 样式先确认 .article-content、.article-banner 和 .toc-wrapper 原本实际算出来的 width / max-width / margin,然后只在真实原值上增加少量宽度,而不是重新定义一套宽度系统。然后此时就发现 5.6 sol 有点力竭了,于是乎请出 Astra,好吧,Astra 确实很厉害。
回头看整个过程,真正反复出问题的地方基本都有同一个原因:一开始不知道洛谷真实 DOM 时,用过于宽泛的选择器或者自己重写布局,很容易让一个原本只想改视觉的规则影响到定位、宽度、overflow 和 stacking context。后面越来越稳定的做法反而比较简单:先用 F12 找到真实节点;外层布局尽量透明并保留原生行为;只有真正承担视觉的那一层加 background + backdrop-filter + border-radius;不要给同一组件的父层和子层同时加玻璃;浮动工具栏、tooltip、目录等原本依赖定位的元素尤其不要随便改父级 overflow、position 和 transform。
到现在,这套样式已经从最初只有“背景铺满 + 左侧毛玻璃”,扩展到了首页、题目页、个人主页、专栏页、顶部导航、左右侧栏、比赛卡片、讨论、犇犇、个人信息卡、热度图、Rating 图表、文章正文、文章操作栏、目录和 footer。视觉风格也基本统一成了同一套:固定背景图、低透明度浅色玻璃、适度 blur、较小圆角、尽量不使用文字阴影,同时优先保证正文和数据类内容的可读性。剩下真正值得继续处理的已经不是“再加几个毛玻璃”,而是一些个人用户使用起来的问题了。
:::
貌似新 UI 的首页左侧侧边栏在截图的时候有点问题,具体的请依据实际情况,目前只能保证 Edge 和 Google 是没有什么问题的,其他的浏览器要自行尝试哦。