You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

绝对定位引用滑块的文本自适应垂直居中问题

问题:滑块引用文本垂直居中适配问题

我找到一个滑块并做了小幅修改提升响应性,但遇到个问题:想让引用框内的文本垂直居中,但滑块用了absolute position,而且因为动画必须设固定高度,这就难办了。我知道无固定高度时绝对定位元素怎么垂直居中,但固定高度只能适配特定屏幕,我希望浏览器缩放时文本始终垂直居中,还能适配长短不一的引用。想请教能不能调整现有代码解决,或者有没有更合适的脚本方案。

HTML代码

<div class="content-slider">
    <div class="slider">
        <div class="mask">
            <ul>
                <li>
                    <h1>"The only way to prove that you’re a good sport is to lose."</h1>
                    <p>- Ernie Banks</p>
                </li>
                <li>
                    <h1>"Champions keep playing until they get it right."</h1>
                    <p>- Billie Jean King</p>
                </li>
                <li>
                    <h1>"You miss 100% of the shots you don’t take."</h1>
                    <p>- Wayne Gretzky</p>
                </li>
                <li>
                    <h1>"Success is where preparation and opportunity meet."</h1>
                    <p>- Bobby Unser</p>
                </li>
                <li>
                    <h1>"Sports do not build character. They reveal it."</h1>
                    <p>- Heywood Broun</p>
                </li>
            </ul>
        </div>
    </div>
</div>

CSS代码

.content-slider {
    align-items: center;
    background: #cb2026;
    display: flex;
    justify-content: center;
}

.slider,
.slider li {
    max-width: 900px;
    width: 100%;
}

.slider {
    overflow: visible;
    position: relative;
}

.content-slider,
.slider,
.slider li,
.mask {
    height: 170px;
}

.mask {
    overflow: hidden;
}

.slider ul {
    list-style-type: none;
    position: relative;
}

.slider li {
    top: -325px;
    position: absolute;
}

.slider h1 {
    color: #fff;
    font-size: 25px;
    font-weight: 500;
    line-height: 35px;
    padding: 20px 20px 0;
    text-align: center;
}

.slider p {
    color: #fff;
    font-size: 18px;
    padding: 20px;
    text-align: right;
}

.slider li:nth-child(1) {
    animation: cycle 15s linear infinite;
}

.slider li:nth-child(2) {
    animation: cycle2 15s linear infinite;
}

.slider li:nth-child(3) {
    animation: cycle3 15s linear infinite;
}

.slider li:nth-child(4) {
    animation: cycle4 15s linear infinite;
}

.slider li:nth-child(5) {
    animation: cycle5 15s linear infinite;
}

.slider:hover li {
    animation-play-state: paused;
}

@keyframes cycle {
    0% {
        top: 0;
    }
    4% {
        top: 0;
    }
    16% {
        top: 0;
        opacity: 1;
        z-index: 0;
    }
    20% {
        top: 325px;
        opacity: 0;
        z-index: 0;
    }
    21% {
        top: -325px;
        opacity: 0;
        z-index: -1;
    }
    50% {
        top: -325px;
        opacity: 0;
        z-index: -1;
     }
     92% {
         top: -325px;
         opacity: 0;
         z-index: 0;
     }
     96% {
         top: -325px;
         opacity: 0;
     }
     100% {
         top: 0;
         opacity: 1;
     }
}

@keyframes cycle2 {
    0% {
        top: -325px;
        opacity: 0;
    }
    16% {
        top: -325px;
        opacity: 0;
    }
    20% {
        top: 0;
        opacity: 1;
    }
    24% {
        top: 0;
        opacity: 1;
    }
    36% {
        top: 0;
        opacity: 1;
        z-index: 0;
    }
    40% {
        top: 325px;
        opacity: 0;
        z-index: 0;
    }
    41% {
        top: -325px;
        opacity: 0;
        z-index: -1;
    }
    100% {
        top: -325px;
        opacity: 0;
        z-index: -1;
    }
}

@keyframes cycle3 {
    0% {
        top: -325px;
        opacity: 0;
    }
    36% {
        top: -325px;
        opacity: 0;
    }
    40% {
        top: 0;
        opacity: 1;
    }
    44% {
        top: 0;
        opacity: 1;
    }
    56% {
        top: 0;
        opacity: 1;
        z-index: 0;
    }
    60% {
        top: 325px;
        opacity: 0;
        z-index: 0;
    }
    61% {
        top: -325px;
        opacity: 0;
        z-index: -1;
    }
    100% {
        top: -325px;
        opacity: 0;
        z-index: -1;
    }
}

@keyframes cycle4 {
    0% {
        top: -325px;
        opacity: 0;
    }
    56% {
        top: -325px;
        opacity: 0;
    }
    60% {
        top: 0;
        opacity: 1;
    }
    64% {
        top: 0;
        opacity: 1;
    }
    76% {
        top: 0;
        opacity: 1;
        z-index: 0;
    }
    80% {
        top: 325px;
        opacity: 0;
        z-index: 0;
    }
    81% {
        top: -325px;
        opacity: 0;
        z-index: -1;
    }
    100% {
        top: -325px;
        opacity: 0;
        z-index: -1;
    }
}

@keyframes cycle5 {
    0% {
        top: -325px;
        opacity: 0;
    }
    76% {
        top: -325px;
        opacity: 0;
    }
    80% {
        top: 0;
        opacity: 1;
    }
    84% {
        top: 0;
        opacity: 1;
    }
    96% {
        top: 0;
        opacity: 1;
        z-index: 0;
    }
    100% {
        top: 325px;
        opacity: 0;
        z-index: 0;
    }
}

解决方案

方案一:Flex布局实现文本垂直居中(无需修改动画核心)

利用Flex布局让每个li内部的文本自动垂直居中,适配固定高度容器:

  1. 修改.slider li的样式:
.slider li {
    top: -325px;
    position: absolute;
    /* 新增Flex布局 */
    display: flex;
    flex-direction: column;
    justify-content: center;
    /* 保留原固定高度 */
    height: 170px;
    box-sizing: border-box; /* 避免padding撑高容器 */
}
  1. 调整h1和p的内边距,避免上下间距过大:
.slider h1 {
    color: #fff;
    font-size: 25px;
    font-weight: 500;
    line-height: 35px;
    padding: 0 20px; /* 仅保留左右padding */
    text-align: center;
    margin: 0; /* 清除默认margin */
}

.slider p {
    color: #fff;
    font-size: 18px;
    padding: 10px 20px 0; /* 仅保留顶部和左右padding */
    text-align: right;
    margin: 0; /* 清除默认margin */
}

这样不管文本长短,都会在固定高度的li内垂直居中,浏览器缩放时也能保持居中状态。


方案二:动态适配容器高度(兼容长文本)

如果固定高度无法容纳长引用,可通过JS动态计算容器高度,同步更新动画位移值:

  1. 移除固定高度设置,改为最小高度:
/* 删除原有固定高度规则 */
.content-slider,
.slider,
.slider li,
.mask {
    height: 170px;
}

/* 替换为以下规则 */
.content-slider {
    min-height: 170px;
    align-items: center;
    background: #cb2026;
    display: flex;
    justify-content: center;
}

.slider, .mask {
    min-height: 170px;
}

.slider li {
    top: -100%; /* 用百分比代替固定值 */
    position: absolute;
    display: flex;
    flex-direction: column;
    justify-content: center;
    box-sizing: border-box;
}
  1. 添加JS动态计算高度并更新动画变量:
const sliderItems = document.querySelectorAll('.slider li');
const mask = document.querySelector('.mask');
let maxHeight = 0;

// 计算最高的引用项高度
sliderItems.forEach(item => {
    const height = item.offsetHeight;
    if (height > maxHeight) maxHeight = height;
});

// 设置容器高度为最高项的高度
mask.style.height = `${maxHeight}px`;
sliderItems.forEach(item => {
    item.style.height = `${maxHeight}px`;
});

// 定义CSS变量用于动画位移
document.documentElement.style.setProperty('--slide-height', `${maxHeight}px`);
  1. 修改CSS动画中的固定位移值为变量:
@keyframes cycle {
    0% {
        top: 0;
    }
    4% {
        top: 0;
    }
    16% {
        top: 0;
        opacity: 1;
        z-index: 0;
    }
    20% {
        top: var(--slide-height);
        opacity: 0;
        z-index: 0;
    }
    21% {
        top: calc(-1 * var(--slide-height));
        opacity: 0;
        z-index: -1;
    }
    /* 其他关键帧同理替换325px为var(--slide-height) */
}

其他动画(cycle2到cycle5)也需要做同样的变量替换,这样就能自动适配不同长度的引用,同时保持垂直居中。


内容的提问来源于stack exchange,提问作者joshmrodg

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.22 05:45:01