fix(pagination): align the load-more skeleton width with the cards

首页「加载更多」的骨架比列表本身宽出一截:.posts-row 用
margin-left/right:-8px 抵消卡片的水平边距,而卡片边距规则是
`.posts-row > *:not(.post_ajax_loader)`,把骨架排除在补偿链之外,
于是骨架左右各宽出 8px(合计 16px)。移动端的 5px 覆盖块同理。

小工具的 .widget-ajaxpager / tab pane 也是一条独立的负边距补偿链
(margin: -8px 抵消 .posts-item 的 8px),骨架同样溢出。

修法是给骨架补上与卡片等同的水平边距,而不是写 inline display
(会盖过 .is-loading 类规则)。改了 main.css、post-card.css 的
8px / 5px 两组规则,用户中心面板另加一条归零规则,因为那里的
容器 margin 与卡片边距都已清零,不能再叠加补偿。

顺带补一条契约测试:删掉任一 gutter 规则即失败,防止回归。

Verification:
- node --test tests/**/*.test.cjs  471 passed / 0 failed
- php tests/widget-system/run.php  136 assertions
- php tools/audit-widget-system.php
- php tools/audit-admin-contracts.php  errors=0 (56 既有 baseline 警告)
- node tools/build-public-assets.mjs  CSS/JS 产物已重建

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
This commit is contained in:
kate522andClaude Fable 5 committed 2026-10-04 00:25:26 +08:00
1 parent cf4554e7c8
commit f61142ee9a
8 files changed
+153 -3

No files matched your search

+28
View File
@@ -15,6 +15,13 @@
margin-left: 8px !important; margin-left: 8px !important;
} }
/* 骨架与真实卡片同宽:.posts-row 以 -8px 抵消卡片边距,loader 被上面的
:not() 排除在补偿外,会宽出 16px;这里补上等同的水平边距。 */
.posts-row > .post_ajax_loader {
margin-right: 8px;
margin-left: 8px;
}
.posts-item { .posts-item {
margin: 15px 0; margin: 15px 0;
padding: 20px; padding: 20px;
@@ -448,6 +455,15 @@
margin-left: 8px; margin-left: 8px;
} }
/* 骨架与卡片同宽同轴:.widget-ajaxpager / .tab-pane 用负边距抵消卡片的水平
边距,骨架被排除在补偿链外,于是左右各宽出一个 gutter。 */
.widget-main-post.style-list .widget-ajaxpager > .post_ajax_loader,
.widget-main-post.style-card .widget-ajaxpager > .post_ajax_loader,
.widget-tab-post .tab-content > .tab-pane > .widget-ajaxpager > .post_ajax_loader {
margin-right: 8px;
margin-left: 8px;
}
.posts-mini:hover img, .posts-mini:hover img,
.posts-item:hover .item-thumbnail img, .posts-item:hover .item-thumbnail img,
.posts-item.mult-thumb .thumb-items > span > img:hover { .posts-item.mult-thumb .thumb-items > span > img:hover {
@@ -518,6 +534,11 @@
margin-left: 5px !important; margin-left: 5px !important;
} }
.posts-row > .post_ajax_loader {
margin-right: 5px;
margin-left: 5px;
}
.posts-item .item-thumbnail { .posts-item .item-thumbnail {
width: 138px; width: 138px;
} }
@@ -564,6 +585,13 @@
margin-left: 5px; margin-left: 5px;
} }
.widget-main-post.style-list .widget-ajaxpager > .post_ajax_loader,
.widget-main-post.style-card .widget-ajaxpager > .post_ajax_loader,
.widget-tab-post .tab-content > .tab-pane > .widget-ajaxpager > .post_ajax_loader {
margin-right: 5px;
margin-left: 5px;
}
.swiper-scroll .posts-item { .swiper-scroll .posts-item {
margin-right: 10px !important; margin-right: 10px !important;
} }
+1 -1
View File
@@ -1 +1 @@
.posts-row{margin-right:-8px;margin-bottom:15px;margin-left:-8px}.posts-row>*:not(.post_ajax_loader){margin-right:8px!important;margin-left:8px!important}.posts-item{margin:15px 0;padding:20px;overflow:hidden;background:var(--main-bg-color, #fff);border-radius:var(--main-radius, 8px);box-shadow:0 0 10px var(--main-shadow, rgba(116, 116, 116, .08));transition:.2s}.posts-item.flex,.posts-item .flex,.posts-mini .flex{display:flex}.posts-item .flex.xx,.posts-mini .flex.xx{flex-direction:column}.posts-item .flex.ac,.posts-mini .flex.ac{align-items:center}.posts-item .flex.jsb,.posts-mini .flex.jsb{justify-content:space-between}.posts-item .flex1,.posts-mini .flex1{flex:1;overflow:hidden}.posts-item .post-graphic:not(.order1){margin-right:20px}.posts-item .order1.post-graphic{margin-right:0;margin-left:20px}.posts-item .item-thumbnail{position:relative;display:block;width:190px;height:0;padding-bottom:var(--posts-list-scale, 70%);overflow:hidden;border-radius:var(--main-radius, 8px)}.item-thumbnail.contain img{object-fit:contain}.swiper-slide.gradient-bg .dplayer-poster img,.swiper-slide.gradient-bg>*>img{object-fit:contain!important;border-radius:0!important}.item-thumbnail .swiper-wrapper{height:100%!important}.list .item-thumbnail .aksrt-slider,.list .item-thumbnail.new-swiper{position:absolute;width:100%;height:100%;margin:0!important}.item-thumbnail .dplayer.dplayer-thumb{position:absolute;inset:0;z-index:1;padding-bottom:var(--posts-list-scale, 70%);background:#000;opacity:0;transition:opacity .3s}.card .item-thumbnail .dplayer.dplayer-thumb{padding-bottom:var(--posts-card-scale, 70%)}.item-thumbnail .dplayer-thumb video,.item-thumbnail .swiper-wrapper,.item-thumbnail img{position:absolute;inset:0;width:100%;height:100%;object-fit:cover}.item-thumbnail .swiper-pagination{right:0!important;bottom:0!important;left:0!important;padding:0 2px!important;text-align:center!important}.posts-item.thumb-dplayer-playing .dplayer-thumb{opacity:1}.posts-item.thumb-dplayer-playing .abs-center{opacity:0}.posts-item .item-heading{display:-webkit-box;max-height:2.8em;margin-top:0;margin-bottom:5px;overflow:hidden;font-size:18px;line-height:1.4em;white-space:normal;-webkit-box-orient:vertical;-webkit-line-clamp:2}.font-bold{font-weight:700}.list.style2 .item-thumbnail{width:130px}.list.style2 .item-heading{display:unset;max-height:1.4em;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.posts-item .item-heading>a{color:var(--key-color, #333)}.posts-item .item-heading>a:hover{color:var(--focus-color, #f04494)}.posts-item .item-excerpt{margin:0 0 6px;overflow:hidden;color:var(--muted-color, #777);text-overflow:ellipsis;white-space:nowrap}.posts-item .item-meta item{margin-right:8px;font-size:13px}.posts-item .item-meta svg.icon,.posts-mini .item-meta svg.icon{display:inline-block;width:1em;height:1em;margin-right:2px;fill:currentColor;overflow:hidden;vertical-align:-.15em}.posts-item .meta-right item:last-child{margin-right:0}.item-meta .avatar-mini{width:20px;height:20px;border-radius:50%;transform:translateY(-1px)}.item-meta .meta-pay{padding:0 4px}.item-meta .meta-pay img{width:1em;height:1em;object-fit:contain;vertical-align:-.15em}.posts-item .item-meta a,.posts-mini .item-meta a{color:inherit}.posts-item .item-tags a{margin-right:5px;padding:2px 5px;font-size:11px}.posts-item .item-tags a .fa{font-size:1em}.posts-item.card{display:inline-block;width:calc(33.333% - 16px);margin:8px;padding:10px;vertical-align:top;transition:.3s}.posts-item.card:last-child{margin-bottom:20px}.posts-item.card .item-body{width:100%;margin:10px 0 0;padding:0}.posts-item.card .item-meta item{font-size:12px}.posts-mini-con .item-heading,.posts-item.card .item-heading{font-size:14px}.posts-item.card .item-heading{min-height:2.8em}.posts-item.card .item-tags{min-height:23px}.posts-item.card .item-thumbnail{width:100%;padding-bottom:var(--posts-card-scale, 70%)}.posts-item.card.style2{background:transparent;box-shadow:none}.posts-item.card.style2:hover{background:var(--main-bg-color, #fff);box-shadow:0 0 10px var(--main-shadow, rgba(116, 116, 116, .08))}.posts-item.card.style3{padding:0}.posts-item.card.style3 .item-thumbnail,.posts-item.card.style3 .item-thumbnail img{border-radius:var(--main-radius, 8px) var(--main-radius, 8px) 0 0}.posts-item.card.style3 .item-body{margin:0;padding:10px}.posts-item.mult-thumb .thumb-items{margin:0 -3px 6px}.posts-item.mult-thumb .thumb-items>span{position:relative;display:inline-block;width:calc(25% - 6px);height:0;margin:0 3px;padding-bottom:calc(var(--posts-list-scale, 70%) / 4)}.posts-item.mult-thumb .thumb-items>span>img{position:absolute;inset:0;width:100%;height:100%;object-fit:cover}.posts-item.mult-thumb .thumb-items.contain>span{overflow:hidden;background:var(--main-border-color, rgba(50, 50, 50, .06));border-radius:var(--main-radius, 8px)}.posts-item.mult-thumb .thumb-items.contain>span>img{object-fit:contain;border-radius:0}.posts-item.no_margin{margin:0;border-radius:0;box-shadow:none}.postsLine truncated .posts-row{margin-right:-8px;margin-bottom:15px;margin-left:-8px}.posts-row>*:not(.post_ajax_loader){margin-right:8px!important;margin-left:8px!important}.posts-row>.post_ajax_loader{margin-right:8px;margin-left:8px}.posts-item{margin:15px 0;padding:20px;overflow:hidden;background:var(--main-bg-color, #fff);border-radius:var(--main-radius, 8px);box-shadow:0 0 10px var(--main-shadow, rgba(116, 116, 116, .08));transition:.2s}.posts-item.flex,.posts-item .flex,.posts-mini .flex{display:flex}.posts-item .flex.xx,.posts-mini .flex.xx{flex-direction:column}.posts-item .flex.ac,.posts-mini .flex.ac{align-items:center}.posts-item .flex.jsb,.posts-mini .flex.jsb{justify-content:space-between}.posts-item .flex1,.posts-mini .flex1{flex:1;overflow:hidden}.posts-item .post-graphic:not(.order1){margin-right:20px}.posts-item .order1.post-graphic{margin-right:0;margin-left:20px}.posts-item .item-thumbnail{position:relative;display:block;width:190px;height:0;padding-bottom:var(--posts-list-scale, 70%);overflow:hidden;border-radius:var(--main-radius, 8px)}.item-thumbnail.contain img{object-fit:contain}.swiper-slide.gradient-bg .dplayer-poster img,.swiper-slide.gradient-bg>*>img{object-fit:contain!important;border-radius:0!important}.item-thumbnail .swiper-wrapper{height:100%!important}.list .item-thumbnail .aksrt-slider,.list .item-thumbnail.new-swiper{position:absolute;width:100%;height:100%;margin:0!important}.item-thumbnail .dplayer.dplayer-thumb{position:absolute;inset:0;z-index:1;padding-bottom:var(--posts-list-scale, 70%);background:#000;opacity:0;transition:opacity .3s}.card .item-thumbnail .dplayer.dplayer-thumb{padding-bottom:var(--posts-card-scale, 70%)}.item-thumbnail .dplayer-thumb video,.item-thumbnail .swiper-wrapper,.item-thumbnail img{position:absolute;inset:0;width:100%;height:100%;object-fit:cover}.item-thumbnail .swiper-pagination{right:0!important;bottom:0!important;left:0!important;padding:0 2px!important;text-align:center!important}.posts-item.thumb-dplayer-playing .dplayer-thumb{opacity:1}.posts-item.thumb-dplayer-playing .abs-center{opacity:0}.posts-item .item-heading{display:-webkit-box;max-height:2.8em;margin-top:0;margin-bottom:5px;overflow:hidden;font-size:18px;line-height:1.4em;white-space:normal;-webkit-box-orient:vertical;-webkit-line-clamp:2}.font-bold{font-weight:700}.list.style2 .item-thumbnail{width:130px}.list.style2 .item-heading{display:unset;max-height:1.4em;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.posts-item .item-heading>a{color:var(--key-color, #333)}.posts-item .item-heading>a:hover{color:var(--focus-color, #f04494)}.posts-item .item-excerpt{margin:0 0 6px;overflow:hidden;color:var(--muted-color, #777);text-overflow:ellipsis;white-space:nowrap}.posts-item .item-meta item{margin-right:8px;font-size:13px}.posts-item .item-meta svg.icon,.posts-mini .item-meta svg.icon{display:inline-block;width:1em;height:1em;margin-right:2px;fill:currentColor;overflow:hidden;vertical-align:-.15em}.posts-item .meta-right item:last-child{margin-right:0}.item-meta .avatar-mini{width:20px;height:20px;border-radius:50%;transform:translateY(-1px)}.item-meta .meta-pay{padding:0 4px}.item-meta .meta-pay img{width:1em;height:1em;object-fit:contain;vertical-align:-.15em}.posts-item .item-meta a,.posts-mini .item-meta a{color:inherit}.posts-item .item-tags a{margin-right:5px;padding:2px 5px;font-size:11px}.posts-item .item-tags a .fa{font-size:1em}.posts-item.card{display:inline-block;width:calc(33.333% - 16px);margin:8px;padding:10px;vertical-align:top;transition:.3s}.posts-item.card:last-child{margin-bottom:20px}.posts-item.card .item-body{width:100%;margin:10px 0 0;padding:0}.posts-item.card .item-meta item{font-size:12px}.posts-mini-con .item-heading,.posts-item.card .item-heading{font-size:14px}.posts-item.card .item-heading{min-height:2.8em}.posts-item.card .item-tags{min-height:23px}.posts-item.card .item-thumbnail{width:100%;padding-bottom:var(--posts-card-scale, 70%)}.posts-item.card.style2{background:transparent;box-shadow:none}.posts-item.card.style2:hover{background:var(--main-bg-color, #fff);box-shadow:0 0 10px var(--main-shadow, rgba(116, 116, 116, .08))}.posts-item.card.style3{padding:0}.posts-item.card.style3 .item-thumbnail,.posts-item.card.style3 .item-thumbnail img{border-radius:var(--main-radius, 8px) var(--main-radius, 8px) 0 0}.posts-item.card.style3 .item-body{margin:0;padding:10px}.posts-item.mult-thumb .thumb-items{margin:0 -3px 6px}.posts-item.mult-thumb .thumb-items>span{position:relative;display:inline-block;width:calc(25% - 6px);height:0;margin:0 3px;padding-bottom:calc(var(--posts-list-scale, 70%) / 4)}.posts-item.mult-thumb .thumb-items>span>img{position:absolute;inset:0;width:100%;height:100%;object-fit:cover}.posts-item.mult-thumb .thumb-items.contain>span{overflow:hidden;background:var(--main-border-color, rgba(50, 50, 50, .06));border-radius:var(--main-radius, 8px)}.posts-item.mult-thumb .thumb-items.contain>span>img{object-fit:contain;border-radius:0}.posts-Line truncated
+28
View File
@@ -14,6 +14,13 @@
margin-left: 8px !important; margin-left: 8px !important;
} }
/* 骨架与真实卡片同宽:.posts-row 以 -8px 抵消卡片边距,loader 被上面的
:not() 排除在补偿外,会宽出 16px;这里补上等同的水平边距。 */
.posts-row > .post_ajax_loader {
margin-right: 8px;
margin-left: 8px;
}
.posts-item { .posts-item {
margin: 15px 0; margin: 15px 0;
padding: 20px; padding: 20px;
@@ -447,6 +454,15 @@
margin-left: 8px; margin-left: 8px;
} }
/* 骨架与卡片同宽同轴:.widget-ajaxpager / .tab-pane 用负边距抵消卡片的水平
边距,骨架被排除在补偿链外,于是左右各宽出一个 gutter。 */
.widget-main-post.style-list .widget-ajaxpager > .post_ajax_loader,
.widget-main-post.style-card .widget-ajaxpager > .post_ajax_loader,
.widget-tab-post .tab-content > .tab-pane > .widget-ajaxpager > .post_ajax_loader {
margin-right: 8px;
margin-left: 8px;
}
.posts-mini:hover img, .posts-mini:hover img,
.posts-item:hover .item-thumbnail img, .posts-item:hover .item-thumbnail img,
.posts-item.mult-thumb .thumb-items > span > img:hover { .posts-item.mult-thumb .thumb-items > span > img:hover {
@@ -517,6 +533,11 @@
margin-left: 5px !important; margin-left: 5px !important;
} }
.posts-row > .post_ajax_loader {
margin-right: 5px;
margin-left: 5px;
}
.posts-item .item-thumbnail { .posts-item .item-thumbnail {
width: 138px; width: 138px;
} }
@@ -563,6 +584,13 @@
margin-left: 5px; margin-left: 5px;
} }
.widget-main-post.style-list .widget-ajaxpager > .post_ajax_loader,
.widget-main-post.style-card .widget-ajaxpager > .post_ajax_loader,
.widget-tab-post .tab-content > .tab-pane > .widget-ajaxpager > .post_ajax_loader {
margin-right: 5px;
margin-left: 5px;
}
.swiper-scroll .posts-item { .swiper-scroll .posts-item {
margin-right: 10px !important; margin-right: 10px !important;
} }
+29
View File
@@ -7486,6 +7486,13 @@ badge.top,
margin-right: 8px !important; margin-right: 8px !important;
} }
/* 骨架与真实卡片同宽同轴:.posts-row 用 -8px 抵消卡片边距,原 :not() 把骨架
排除在补偿外,骨架于是比卡片左右各宽 8px。补上等同边距。 */
.posts-row > .post_ajax_loader {
margin-left: 8px;
margin-right: 8px;
}
.posts-item { .posts-item {
padding: 20px; padding: 20px;
margin: 15px 0; margin: 15px 0;
@@ -7890,6 +7897,16 @@ badge.top,
margin-right: 8px; margin-right: 8px;
} }
/* 骨架与卡片同宽同轴:.widget-ajaxpager / .tab-pane 用负边距抵消卡片的水平
边距,骨架被排除在补偿链外,于是左右各宽出一个 gutter。这里补回等宽的
边距,让骨架与真实卡片对齐。tab pane 的 style-list / index-tab 都适用。 */
.widget-main-post.style-list .widget-ajaxpager > .post_ajax_loader,
.widget-main-post.style-card .widget-ajaxpager > .post_ajax_loader,
.widget-tab-post .tab-content > .tab-pane > .widget-ajaxpager > .post_ajax_loader {
margin-left: 8px;
margin-right: 8px;
}
.widget-tab-post.index-tab .list-inline { .widget-tab-post.index-tab .list-inline {
margin-bottom: 15px; margin-bottom: 15px;
} }
@@ -11213,6 +11230,13 @@ body.error404 {
margin-bottom: 30px; margin-bottom: 30px;
} }
.widget-main-post.style-list .widget-ajaxpager > .post_ajax_loader,
.widget-main-post.style-card .widget-ajaxpager > .post_ajax_loader,
.widget-tab-post .tab-content > .tab-pane > .widget-ajaxpager > .post_ajax_loader {
margin-left: 5px;
margin-right: 5px;
}
.posts-row { .posts-row {
margin-left: -5px; margin-left: -5px;
margin-right: -5px; margin-right: -5px;
@@ -11223,6 +11247,11 @@ body.error404 {
margin-right: 5px !important; margin-right: 5px !important;
} }
.posts-row > .post_ajax_loader {
margin-left: 5px;
margin-right: 5px;
}
.posts-item.card { .posts-item.card {
width: calc(50% - 10px); width: calc(50% - 10px);
margin: 5px; margin: 5px;
+1 -1
View File
@@ -1 +1 @@
body{--mian-max-width: 1200px;--posts-card-scale: 70%;--posts-list-scale: 70%;--theme-color: #f04494;--focus-color: var(--theme-color);--focus-shadow-color: rgba(253, 83, 161, .4);--key-color: #333;--main-color: #4e5358;--main-shadow: rgba(116, 116, 116, .08);--muted-color: #777;--muted-2-color: #999;--muted-3-color: #b1b1b1;--muted-4-color: #d2d2d2;--body-bg-color: #f5f6f7;--main-bg-color: #fff;--muted-bg-color: #eee;--muted-bg-2-color: #f6f7f8;--main-border-color: rgba(50, 50, 50, .06);--muted-border-color: rgba(0, 0, 0, .03);--main-radius: 8px;--mini-radius: calc(var(--main-radius) / 1.4);--blur-bg: rgba(255, 255, 255, .8);--float-btn-bg: rgba(200, 200, 200, .4);--header-bg: var(--blur-bg);--header-color: var(--main-color);--footer-bg: var(--main-bg-color);--footer-color: var(--muted-2-color)}.dark-theme{--key-color: #f8fafc;--main-color: #e5eef7;--main-shadow: rgba(24, 24, 24, .1);--muted-color: #b4b6bb;--muted-2-color: #888a8f;--muted-3-color: #636469;--muted-4-color: #43454a;--body-bg-color: #292a2d;--main-bg-color: #323335;--muted-bg-color: #2d2e31;--muted-bg-2-color: #37383a;--main-border-color: rgba(114, 114, 114, .1);--muted-border-color: rgba(184, 184, 184, .02);--blur-bg: rgba(50, 51, 53, .8);--float-btn-bg: rgba(70, 70, 70, .4);--header-bg: var(--blur-bg);--header-color: var(--main-color);--footer-bg: var(--main-bg-color);--footer-color: var(--muted-2-color)}::view-transition-old(root),::view-transition-new(root){animation:none;mix-blend-mode:normal}.dark::view-transition-old(root){z-index:1}.dark::view-transition-new(root){z-index:2147483646}::view-transition-old(root){z-index:2147483646}::view-transition-new(root){z-index:1}@supports not ((-webkit-backdrop-filter: blur(20px)) or (backdrop-filter: blur(20px))){body{--blur-bg: #ffffff}body.dark-theme{--blur-bg: #37383a}}body:has(.modal.in),body.modal-open{--blur-bg: #ffffff}body.dark-theme:has(.modal.in),body.dark-theme.modal-open{--blur-bg: #37383a}body.fps-accelerat{--blur-bg: #ffffff}body.fps-accelerat.dark-theme{--blur-bg: #37383a}body.fps-accelerat *{-webkit-backdrop-filter:unset!important;backdrop-filter:unset!important}a[href],.relates-thumb li a>.post-info,.more-posts a>span{transition:color .2s,background .3s,opacity .3s,box-shadow .3s,transform .3s}.main-shadow{transition:box-shadow .3s}.but:focus,.but:hover,.progress,.navbar-nav>li:before{transition:.3s}.navbar-top .sub-menu,.theme-popover,.hover-show .hover-show-con{opacity:0;transform:translateY(6px);transition:.4s}.navbar-top li:hover>.sub-menu,.hover-show:hover .hover-show-con,.hover-show:hover~.hover-show-con,.hover-show:hover~.sub-menu{opacity:1;transform:translateY(0)}.hover-show{position:relative;cursor:pointer;z-index:10}.hover-show .hover-show-con{position:absolute;visibility:hidden}.hover-show:hover .hover-show-con,.hover-show:hover~.hover-show-con,.hover-show:hover~.sub-menu{visibility:unset}.match-ok,.navbar-top .sub-menu li>a,.ic-close{transition:.3s}.ic-close:hover{transform:rotate(270deg);color:inherit}.social_loginbar a,.item-thumbnail img,.dosc-nav .fa{transition:.2s ease-out}.hover-zoom:hover,.hover-zoom-img:hover img,.social_loginbar .xh-social-item:hover,.social_loginbar .social-login-item:hover{transform:scale(1.05)}.hover-zoom-sm:hover,.hover-zoom-img-sm:hover img,.posts-mini:hover img,.posts-item:hover .item-thumbnail img,.posts-item.mult-thumb .thumb-items>span>img:hover{transform:scale(1.02)}.main-min-height{min-height:calc(100vh - 280px)}.main-shadow{box-shadow:0 0 10px var(--main-shadow)}.key-color{color:var(--key-color)}.focus-color{--this-color: var(--focus-color);color:var(--focus-color)}.muted-color{color:var(--muted-color)}.muted-2-color{color:var(--muted-2-color)}.muted-3-color{color:var(--muted-3-color)}.main-bg{background:var(--main-bg-color)}.placeholder{background:linear-gradient(118deg,#7979791a 25%,#79797933 37%,#7979791a 63%);opacity:1;border-radius:4px;-webkit-animation:placeholder 1.5s ease infinite!important;animation:placeholder 1.5s ease infinite!important;background-size:400% 100%!important}.placeholder.img{height:119px}.placeholder.t1{height:24px;width:80%}.placeholder.k1{height:20px;width:60%}.placeholder.k2{height:20px}.placeholder.k3{height:15px}.placeholder.s1{width:70px;height:15px;display:inline-block}@-webkit-keyframes placeholder{0%{background-position:100% 50%}to{background-position:0 50%}}@keyframes placeholder{0%{background-position:100% 50%}to{background-position:0 50%}}@-webkit-keyframes fade{0%{opacity:0}to{opacity:1}}@keyframes fade{0%{opacity:0}to{opacity:1}}.ani.shake{-webkit-animation:shake .3s ease-in!important;animation:shake .3s ease-in!important}@-webkit-keyframes shake{20%{transform:translate(2px)}40%{transform:translate(-4px)}60%{transform:translate(5px)}80%{transform:translate(3px)}to{transform:translate(0)}}@keyframes shake{20%{transform:translate(2px)}40%{transform:translate(-4px)}60%{transform:translate(5px)}80%{transform:translate(3px)}to{transform:translate(0)}}.obs-animate{opacity:0;transition:opacity .6sLine truncated body{--mian-max-width: 1200px;--posts-card-scale: 70%;--posts-list-scale: 70%;--theme-color: #f04494;--focus-color: var(--theme-color);--focus-shadow-color: rgba(253, 83, 161, .4);--key-color: #333;--main-color: #4e5358;--main-shadow: rgba(116, 116, 116, .08);--muted-color: #777;--muted-2-color: #999;--muted-3-color: #b1b1b1;--muted-4-color: #d2d2d2;--body-bg-color: #f5f6f7;--main-bg-color: #fff;--muted-bg-color: #eee;--muted-bg-2-color: #f6f7f8;--main-border-color: rgba(50, 50, 50, .06);--muted-border-color: rgba(0, 0, 0, .03);--main-radius: 8px;--mini-radius: calc(var(--main-radius) / 1.4);--blur-bg: rgba(255, 255, 255, .8);--float-btn-bg: rgba(200, 200, 200, .4);--header-bg: var(--blur-bg);--header-color: var(--main-color);--footer-bg: var(--main-bg-color);--footer-color: var(--muted-2-color)}.dark-theme{--key-color: #f8fafc;--main-color: #e5eef7;--main-shadow: rgba(24, 24, 24, .1);--muted-color: #b4b6bb;--muted-2-color: #888a8f;--muted-3-color: #636469;--muted-4-color: #43454a;--body-bg-color: #292a2d;--main-bg-color: #323335;--muted-bg-color: #2d2e31;--muted-bg-2-color: #37383a;--main-border-color: rgba(114, 114, 114, .1);--muted-border-color: rgba(184, 184, 184, .02);--blur-bg: rgba(50, 51, 53, .8);--float-btn-bg: rgba(70, 70, 70, .4);--header-bg: var(--blur-bg);--header-color: var(--main-color);--footer-bg: var(--main-bg-color);--footer-color: var(--muted-2-color)}::view-transition-old(root),::view-transition-new(root){animation:none;mix-blend-mode:normal}.dark::view-transition-old(root){z-index:1}.dark::view-transition-new(root){z-index:2147483646}::view-transition-old(root){z-index:2147483646}::view-transition-new(root){z-index:1}@supports not ((-webkit-backdrop-filter: blur(20px)) or (backdrop-filter: blur(20px))){body{--blur-bg: #ffffff}body.dark-theme{--blur-bg: #37383a}}body:has(.modal.in),body.modal-open{--blur-bg: #ffffff}body.dark-theme:has(.modal.in),body.dark-theme.modal-open{--blur-bg: #37383a}body.fps-accelerat{--blur-bg: #ffffff}body.fps-accelerat.dark-theme{--blur-bg: #37383a}body.fps-accelerat *{-webkit-backdrop-filter:unset!important;backdrop-filter:unset!important}a[href],.relates-thumb li a>.post-info,.more-posts a>span{transition:color .2s,background .3s,opacity .3s,box-shadow .3s,transform .3s}.main-shadow{transition:box-shadow .3s}.but:focus,.but:hover,.progress,.navbar-nav>li:before{transition:.3s}.navbar-top .sub-menu,.theme-popover,.hover-show .hover-show-con{opacity:0;transform:translateY(6px);transition:.4s}.navbar-top li:hover>.sub-menu,.hover-show:hover .hover-show-con,.hover-show:hover~.hover-show-con,.hover-show:hover~.sub-menu{opacity:1;transform:translateY(0)}.hover-show{position:relative;cursor:pointer;z-index:10}.hover-show .hover-show-con{position:absolute;visibility:hidden}.hover-show:hover .hover-show-con,.hover-show:hover~.hover-show-con,.hover-show:hover~.sub-menu{visibility:unset}.match-ok,.navbar-top .sub-menu li>a,.ic-close{transition:.3s}.ic-close:hover{transform:rotate(270deg);color:inherit}.social_loginbar a,.item-thumbnail img,.dosc-nav .fa{transition:.2s ease-out}.hover-zoom:hover,.hover-zoom-img:hover img,.social_loginbar .xh-social-item:hover,.social_loginbar .social-login-item:hover{transform:scale(1.05)}.hover-zoom-sm:hover,.hover-zoom-img-sm:hover img,.posts-mini:hover img,.posts-item:hover .item-thumbnail img,.posts-item.mult-thumb .thumb-items>span>img:hover{transform:scale(1.02)}.main-min-height{min-height:calc(100vh - 280px)}.main-shadow{box-shadow:0 0 10px var(--main-shadow)}.key-color{color:var(--key-color)}.focus-color{--this-color: var(--focus-color);color:var(--focus-color)}.muted-color{color:var(--muted-color)}.muted-2-color{color:var(--muted-2-color)}.muted-3-color{color:var(--muted-3-color)}.main-bg{background:var(--main-bg-color)}.placeholder{background:linear-gradient(118deg,#7979791a 25%,#79797933 37%,#7979791a 63%);opacity:1;border-radius:4px;-webkit-animation:placeholder 1.5s ease infinite!important;animation:placeholder 1.5s ease infinite!important;background-size:400% 100%!important}.placeholder.img{height:119px}.placeholder.t1{height:24px;width:80%}.placeholder.k1{height:20px;width:60%}.placeholder.k2{height:20px}.placeholder.k3{height:15px}.placeholder.s1{width:70px;height:15px;display:inline-block}@-webkit-keyframes placeholder{0%{background-position:100% 50%}to{background-position:0 50%}}@keyframes placeholder{0%{background-position:100% 50%}to{background-position:0 50%}}@-webkit-keyframes fade{0%{opacity:0}to{opacity:1}}@keyframes fade{0%{opacity:0}to{opacity:1}}.ani.shake{-webkit-animation:shake .3s ease-in!important;animation:shake .3s ease-in!important}@-webkit-keyframes shake{20%{transform:translate(2px)}40%{transform:translate(-4px)}60%{transform:translate(5px)}80%{transform:translate(3px)}to{transform:translate(0)}}@keyframes shake{20%{transform:translate(2px)}40%{transform:translate(-4px)}60%{transform:translate(5px)}80%{transform:translate(3px)}to{transform:translate(0)}}.obs-animate{opacity:0;transition:opacity .6sLine truncated
+7
View File
@@ -390,6 +390,13 @@
width: auto; /* 覆盖 vendored site-layout-1 的 width: calc(50% - 16px),让卡片填满网格单元 */ width: auto; /* 覆盖 vendored site-layout-1 的 width: calc(50% - 16px),让卡片填满网格单元 */
margin: 0 !important; /* 抵消 vendored .posts-row > * 的 8px !important 边距 */ margin: 0 !important; /* 抵消 vendored .posts-row > * 的 8px !important 边距 */
} }
/* 骨架跟随网格走:容器 margin 已归零、卡片边距已清零,
不能再叠加 .posts-row > .post_ajax_loader 的 8px 补偿。 */
.aksrt-user-home .aksrt-user-home__post-list[data-view="list"] > .post_ajax_loader {
margin-right: 0;
margin-left: 0;
}
} }
@media (max-width: 767px) { @media (max-width: 767px) {
@@ -92,6 +92,64 @@ test('skeleton loading ships one contract and no dead spinner stylesheets', () =
} }
}) })
test('skeleton blocks share the card gutter instead of overflowing it', () => {
// .posts-row pulls the container in with a negative margin and hands every
// card a matching gutter. The card rule is scoped
// `.posts-row > *:not(.post_ajax_loader)`, so the loader is excluded from the
// compensation chain and ends up wider than the cards by both gutters.
// Each gutter block therefore needs a sibling rule that gives the loader the
// same horizontal margin — otherwise 加载更多 shows a skeleton that spills
// outside the content column.
const blocks = [
{
file: 'assets/css/main.css',
selector: '.posts-row > .post_ajax_loader',
gutters: [8, 5],
},
{
file: 'assets/css/frontend/post-card.css',
selector: '.posts-row > .post_ajax_loader',
gutters: [8, 5],
},
]
for (const block of blocks) {
const css = fs.readFileSync(path.join(root, block.file), 'utf8')
const rules = (css.match(
new RegExp(`${block.selector.replace(/[.*+?^${}()|[\]\\]/g, '\\$&')}\\s*\\{[^}]*\\}`, 'g')
) || []).map((rule) => rule.replace(/\s+/g, ' '))
// One rule per gutter value in that file (desktop 8px, mobile 5px).
for (const gutter of block.gutters) {
const matched = rules.some(
(rule) =>
rule.includes(`margin-left: ${gutter}px`) &&
rule.includes(`margin-right: ${gutter}px`)
)
assert.ok(
matched,
`${block.file} must give .post_ajax_loader the ${gutter}px gutter in "${block.selector}"`
)
}
}
// The widget pagers apply their own negative-margin compensation chain
// (.widget-ajaxpager / .tab-pane), so the loader needs the same relief there.
for (const file of ['assets/css/main.css', 'assets/css/frontend/post-card.css']) {
const css = fs.readFileSync(path.join(root, file), 'utf8')
// Cover every style class the renderer can emit (.style-list / .style-card,
// and the tab pane which carries style-list or index-tab).
assert.match(css, /\.widget-main-post\.style-list \.widget-ajaxpager > \.post_ajax_loader/)
assert.match(css, /\.widget-main-post\.style-card \.widget-ajaxpager > \.post_ajax_loader/)
assert.match(css, /\.widget-tab-post \.tab-content > \.tab-pane > \.widget-ajaxpager > \.post_ajax_loader/)
}
// The user-home panel zeroes the container margin and the card gutters, so the
// loader must not pick up any leftover compensation there.
const userHome = fs.readFileSync(path.join(root, 'assets/css/routes/user-home.css'), 'utf8')
assert.match(userHome, /\.aksrt-user-home__post-list\[data-view="list"\] > \.post_ajax_loader \{\s*margin-right: 0;\s*margin-left: 0;/)
})
test('asset tables are InnoDB and operation keys are unique', () => { test('asset tables are InnoDB and operation keys are unique', () => {
const schema = fs.readFileSync(path.join(root, 'src', 'Core', 'DBMigratorPart2.php'), 'utf8') const schema = fs.readFileSync(path.join(root, 'src', 'Core', 'DBMigratorPart2.php'), 'utf8')
for (const table of ['asset_account', 'asset_transaction', 'asset_entry']) { for (const table of ['asset_account', 'asset_transaction', 'asset_entry']) {
+1 -1
View File
@@ -1,5 +1,5 @@
{ {
"generated_at": "2026-10-03T14:21:05+00:00", "generated_at": "2026-10-03T16:24:36+00:00",
"errors": [], "errors": [],
"warnings": [ "warnings": [
"customPage tools-update section 'tools/update' not in PHP schema (ok if pure operational page)", "customPage tools-update section 'tools/update' not in PHP schema (ok if pure operational page)",