fix(single): fill slide and video cover media like the image cover
Slide-mode images rendered at intrinsic ratio, top-aligned inside the swiper chain (--pc-height:auto left .swiper-wrapper content-sized), so the taller box showed a gap at the bottom and never center-cropped like the image cover. The video cover had the same problem through video-player.js (height:auto, capped at 70vh). - aksrt_render_slider scale mode emits --pc-height/--m-height 100% so the wrapper/slide/img chain fills the ratio box and object-fit: cover center-crops inside it (same pattern as the .scale-height widgets) - video-player.js renders the video at height:100% + object-fit:cover; with an undimensioned container height:100% degrades to auto, matching the previous behavior - drop the dead .single-cover padding-bottom rules (every producer owns its height inline, and the rule squeezed the absolutely positioned slide inner) and the orphaned --single-cover-scale var in tokens.css/compat-vars.css/main.css/InlineStyleBuilder - rebuild public bundles; extend the single-cover-height contract
This commit is contained in:
@@ -214,7 +214,6 @@ Full admin panel preserved (settings, OAuth, content tools, etc).
|
||||
--color-primary-dark: var(--color-primary-active);
|
||||
--shadow-md: var(--shadow);
|
||||
--mini-radius: calc(var(--radius) / 1.4);
|
||||
--single-cover-scale: 35%;
|
||||
|
||||
/* ===== Avatar size system — legacy --this-size 等价 ===== */
|
||||
--aksrt-avatar-size-xs: 24px;
|
||||
|
||||
Vendored
+1
-1
File diff suppressed because one or more lines are too long
@@ -189,7 +189,6 @@
|
||||
--color-primary-dark: var(--color-primary-active);
|
||||
--shadow-md: var(--shadow);
|
||||
--mini-radius: calc(var(--radius) / 1.4);
|
||||
--single-cover-scale: 35%;
|
||||
|
||||
/* ===== Avatar size system — legacy --this-size 等价 ===== */
|
||||
--aksrt-avatar-size-xs: 24px;
|
||||
|
||||
@@ -62,7 +62,6 @@
|
||||
/* Cards — 对齐 legacy 70% */
|
||||
--posts-card-scale: 70%;
|
||||
--posts-list-scale: 70%;
|
||||
--single-cover-scale: 35%;
|
||||
}
|
||||
|
||||
/* legacy --this-* context-coloring DEFAULTS live with the .but system in
|
||||
|
||||
@@ -4,14 +4,14 @@
|
||||
* ============================================================ */
|
||||
|
||||
/* ===== Cover (in-column ratio box) — legacy .single-cover ===== */
|
||||
/* 高度由各模式的内联 padding-bottom 决定;此处不得再声明 padding-bottom,
|
||||
* 否则会挤压绝对定位轮播内层(同样挂 .single-cover 类)的 content box。 */
|
||||
.single-cover {
|
||||
position: relative;
|
||||
overflow: hidden;
|
||||
border-radius: var(--main-radius, var(--radius, 8px));
|
||||
box-shadow: 0 0 10px var(--main-shadow, rgba(116, 116, 116, 0.08));
|
||||
margin-bottom: 20px;
|
||||
/* legacy: padding-bottom: calc(var(--single-cover-scale) + 50px) */
|
||||
padding-bottom: calc(var(--single-cover-scale, 35%) + 50px);
|
||||
}
|
||||
|
||||
.single-cover > .fit-cover,
|
||||
|
||||
@@ -2,7 +2,6 @@ body {
|
||||
--mian-max-width: 1200px;
|
||||
--posts-card-scale: 70%;
|
||||
--posts-list-scale: 70%;
|
||||
--single-cover-scale: 35%;
|
||||
|
||||
--theme-color: #f04494;
|
||||
--focus-color: var(--theme-color);
|
||||
@@ -8497,10 +8496,6 @@ body.modal-open .float-btn.wait-pay-btn .hover-show-con {
|
||||
margin-left: 50px;
|
||||
}
|
||||
|
||||
.single-cover {
|
||||
padding-bottom: calc(var(--single-cover-scale) + 50px);
|
||||
}
|
||||
|
||||
.single-cover-con {
|
||||
color: #fff;
|
||||
padding: 15px 15px 10px 15px;
|
||||
|
||||
Vendored
+1
-1
File diff suppressed because one or more lines are too long
@@ -28,7 +28,9 @@
|
||||
style.id = STYLE_ID;
|
||||
style.textContent =
|
||||
'.aksrt-video{position:relative;background:#000;border-radius:12px;overflow:hidden;cursor:pointer;}' +
|
||||
'.aksrt-video video{display:block;width:100%;height:auto;max-height:70vh;}' +
|
||||
// 组件容器(文章封面比例盒)有确定高度:视频铺满并居中裁切,对齐单图封面;
|
||||
// 容器无确定高度时 height:100% 退化为 auto,行为与原 height:auto 一致。
|
||||
'.aksrt-video video{display:block;width:100%;height:100%;object-fit:cover;}' +
|
||||
'.aksrt-video__overlay{position:absolute;inset:0;display:flex;align-items:center;justify-content:center;background:rgba(0,0,0,0.3);transition:opacity 0.3s;pointer-events:none;}' +
|
||||
'.aksrt-video.is-playing .aksrt-video__overlay{opacity:0;}' +
|
||||
'.aksrt-video__play{width:60px;height:60px;border-radius:50%;background:rgba(255,255,255,0.9);display:flex;align-items:center;justify-content:center;font-size:24px;color:#1a1a2e;box-shadow:0 4px 20px rgba(0,0,0,0.3);transition:transform 0.2s;}' +
|
||||
|
||||
@@ -96,13 +96,16 @@ function aksrt_render_slider(array $args = []): string {
|
||||
$scale_padding = '';
|
||||
if ($args['scale_height']) {
|
||||
// padding-bottom percentage for ratio box (legacy graphic cover style).
|
||||
// 内层 .new-swiper 为绝对定位铺满 wrapper,高度完全由 wrapper 的 padding-bottom 决定。
|
||||
// 内层 .new-swiper 绝对定位铺满 wrapper,wrapper 决定盒子高度;
|
||||
// pc/m-height 100% 让 .swiper-wrapper/.swiper-slide 铺满盒子,
|
||||
// 使 object-fit: cover 在确定的盒内居中裁切(对齐单图封面)。
|
||||
$ratio_pct = max(10, min(100, (float) $args['scale_ratio'] * 100));
|
||||
$scale_padding = $ratio_pct . '%';
|
||||
$scale_extra = trim((string) $args['scale_extra']);
|
||||
if ($scale_extra !== '') {
|
||||
$scale_padding = 'calc(' . $scale_padding . ' + ' . $scale_extra . ')';
|
||||
}
|
||||
$height_style = '--pc-height:100%;--m-height:100%;';
|
||||
} else {
|
||||
$height_style = sprintf('--pc-height:%s;--m-height:%s;', esc_attr($args['pc_height']), esc_attr($args['m_height']));
|
||||
}
|
||||
@@ -120,7 +123,7 @@ function aksrt_render_slider(array $args = []): string {
|
||||
|
||||
// 渲染 HTML
|
||||
$html = '<div class="' . esc_attr($wrapper_class_str) . '"' . ($args['scale_height'] ? ' style="position:relative;padding-bottom:' . esc_attr($scale_padding) . ';"' : '') . '>';
|
||||
$html .= '<div class="' . esc_attr($slider_class_str) . '" ' . implode(' ', $data_attrs) . ($args['scale_height'] ? ' style="position:absolute;inset:0;width:100%;height:100%;"' : ' style="' . esc_attr($height_style) . '"') . '>';
|
||||
$html .= '<div class="' . esc_attr($slider_class_str) . '" ' . implode(' ', $data_attrs) . ' style="' . esc_attr($height_style . ($args['scale_height'] ? 'position:absolute;inset:0;width:100%;height:100%;' : '')) . '">';
|
||||
$html .= '<div class="swiper-wrapper">';
|
||||
|
||||
foreach ($slides as $slide) {
|
||||
|
||||
@@ -76,7 +76,6 @@ class InlineStyleBuilder {
|
||||
'--font-heading' => $font_stacks['ui'],
|
||||
'--aksrt-logo-width' => $logo_width . 'px',
|
||||
'--nav-height' => '60px',
|
||||
'--single-cover-scale' => '35%',
|
||||
'--posts-list-scale' => (class_exists('\AKSRT\Settings\Settings') ? (\AKSRT\Settings\Settings::get_post_list_style_settings()['list_list_option']['scale'] ?? 70) : 70) . '%',
|
||||
'--posts-card-scale' => (class_exists('\AKSRT\Settings\Settings') ? (\AKSRT\Settings\Settings::get_post_list_style_settings()['list_card_option']['scale'] ?? 70) : 70) . '%',
|
||||
];
|
||||
|
||||
@@ -68,14 +68,66 @@ test('single cover: the dead static slide fallback is gone', () => {
|
||||
);
|
||||
});
|
||||
|
||||
test('slider scale mode: inner swiper carries no dead inline height styles', () => {
|
||||
test('slider scale mode: completes the definite height chain for cover cropping', () => {
|
||||
assert.doesNotMatch(
|
||||
sliderHelper,
|
||||
/--scale-ratio/,
|
||||
'--scale-ratio 无任何 CSS 消费方,禁止输出'
|
||||
);
|
||||
const scaleMode = sliderHelper.split("if ($args['scale_height']) {")[1] || '';
|
||||
assert.ok(scaleMode.includes("position:absolute;inset:0;width:100%;height:100%;"));
|
||||
// wrapper 决定盒子高度;pc/m-height 100% 让 .swiper-wrapper/.swiper-slide
|
||||
// 铺满比例盒,使 object-fit: cover 在确定的盒内居中裁切(对齐单图封面)。
|
||||
assert.match(
|
||||
sliderHelper,
|
||||
/\$height_style = '--pc-height:100%;--m-height:100%;';/
|
||||
);
|
||||
assert.match(
|
||||
sliderHelper,
|
||||
/esc_attr\(\$height_style \. \(\$args\['scale_height'\] \? 'position:absolute;inset:0;width:100%;height:100%;' : ''\)\)/,
|
||||
'内层 .new-swiper 必须绝对定位铺满 wrapper'
|
||||
);
|
||||
});
|
||||
|
||||
test('video cover: the player video fills and center-crops like the image cover', () => {
|
||||
const player = read('assets/js/video-player.js');
|
||||
assert.match(
|
||||
player,
|
||||
/\.aksrt-video video\{display:block;width:100%;height:100%;object-fit:cover;\}/,
|
||||
'视频必须铺满封面比例盒并居中裁切'
|
||||
);
|
||||
assert.doesNotMatch(
|
||||
player,
|
||||
/max-height:70vh/,
|
||||
'封面盒高度由比例盒决定,不得再套 70vh 截断'
|
||||
);
|
||||
});
|
||||
|
||||
test('single cover css owns no fallback padding and the scale var is gone', () => {
|
||||
for (const file of [
|
||||
'assets/css/frontend/single-post/cover.css',
|
||||
'assets/css/main.css',
|
||||
'assets/css/main.min.css',
|
||||
'assets/css/core/tokens.css',
|
||||
'assets/css/frontend/compat-vars.css',
|
||||
'assets/css/build/public.css',
|
||||
'assets/css/build/public.min.css',
|
||||
]) {
|
||||
const css = read(file);
|
||||
assert.doesNotMatch(
|
||||
css,
|
||||
/\.single-cover\s*\{[^}]*padding-bottom/,
|
||||
`${file} 的 .single-cover 不得声明 padding-bottom(高度归内联样式)`
|
||||
);
|
||||
assert.doesNotMatch(
|
||||
css,
|
||||
/--single-cover-scale/,
|
||||
`${file} 不得再包含孤儿变量 --single-cover-scale`
|
||||
);
|
||||
}
|
||||
assert.doesNotMatch(
|
||||
read('src/Frontend/InlineStyleBuilder.php'),
|
||||
/--single-cover-scale/,
|
||||
'运行时 CSS 变量不得再输出孤儿 --single-cover-scale'
|
||||
);
|
||||
});
|
||||
|
||||
test('dead cover css is removed from every stylesheet surface', () => {
|
||||
|
||||
Reference in New Issue
Block a user