绝对定位引用滑块的文本自适应垂直居中问题
问题:滑块引用文本垂直居中适配问题
我找到一个滑块并做了小幅修改提升响应性,但遇到个问题:想让引用框内的文本垂直居中,但滑块用了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内部的文本自动垂直居中,适配固定高度容器:
- 修改
.slider li的样式:
.slider li { top: -325px; position: absolute; /* 新增Flex布局 */ display: flex; flex-direction: column; justify-content: center; /* 保留原固定高度 */ height: 170px; box-sizing: border-box; /* 避免padding撑高容器 */ }
- 调整
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动态计算容器高度,同步更新动画位移值:
- 移除固定高度设置,改为最小高度:
/* 删除原有固定高度规则 */ .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; }
- 添加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`);
- 修改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
相关产品推荐
相关产品推荐

