Files
AboutMe/src/styles/banner.css
2026-02-02 22:47:52 +03:00

483 lines
13 KiB
CSS
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
/*
* Banner 组件样式
* Banner Component Styles
* 包含 Banner 模式下的所有响应式样式和动画效果
*/
/**
* 基础样式
*/
/* 淡入上移动画 */
@keyframes fadeInUp {
from {
opacity: 0;
translate: 0 30px;
}
to {
opacity: 1;
translate: 0 0;
}
}
/* 初始加载中且未开始恢复时,高度归零;退出 Banner 模式时,高度归零 */
html.is-loading:not(.banner-restoring) #banner-wrapper,
html.banner-transitioning #banner-wrapper,
html.banner-hiding #banner-wrapper {
height: 0 !important;
}
/* 退出动画时,强制子组件同步上移,避免主内容区域出现“两段式”位移 */
html.banner-hiding #main-grid {
translate: none !important;
}
html.banner-hiding #top-row {
height: 0 !important;
}
html.banner-hiding #sidebar-sticky {
top: 1rem !important;
}
/* 切换模式时隐藏标题,以便后续触发动画 */
html.banner-transitioning .banner-title,
html.banner-transitioning .banner-subtitle {
opacity: 0 !important;
}
/* 标题样式 */
.banner-title {
text-shadow: 0px 3px 12px rgba(0, 0, 0, 0.36), 0 0 24px color-mix(in srgb, var(--primary), transparent 48%);
font-weight: bold;
opacity: 0;
}
.banner-subtitle {
text-shadow: 0px 3px 6px rgba(0, 0, 0, 0.36), 0 0 12px color-mix(in srgb, var(--primary), transparent 48%);
opacity: 0;
}
/* 标题动画 */
.show-initial-animation .banner-title,
.show-banner-animation .banner-title {
animation: fadeInUp 1s ease-out forwards;
}
.show-initial-animation .banner-subtitle,
.show-banner-animation .banner-subtitle {
animation: fadeInUp 1s ease-out 0.3s both;
}
/* 动画结束后的状态 */
html:not(.is-loading):not(.show-initial-animation):not(.show-banner-animation) .banner-title,
html:not(.is-loading):not(.show-initial-animation):not(.show-banner-animation) .banner-subtitle {
opacity: 1;
}
/* 页面背景平滑过渡Fullscreen 与 Banner 模式切换时) */
body {
transition: background-color 0.6s ease, background-image 0.6s ease;
}
html.is-wallpaper-transitioning body {
transition: background-color 0.6s ease, background-image 0.6s ease !important;
}
/**
*
*/
/* Ken Burns 效果 */
@keyframes ken-burns {
from {
scale: 1.0;
translate: 0 0 0;
}
to {
scale: 1.2;
translate: 0 0 0;
}
}
/* 桌面端 */
@media (min-width: 1280px) {
.banner-text-overlay {
align-items: center !important; /* 垂直居中 */
justify-content: center !important; /* 水平居中 */
padding: 2rem !important;
text-align: center !important; /* 文字居中对齐 */
}
.banner-text-overlay > div {
margin-bottom: 0 !important;
width: 75% !important;
text-align: center !important; /* 确保文字居中 */
}
/* 确保轮播容器有正确的 overflow 设置 */
#banner-carousel {
overflow: hidden !important;
}
/* 图片容器 */
.carousel-item img,
#banner img {
object-position: center center !important; /* 确保图片居中显示 */
transition: transform 1.2s ease-out !important;
}
/* 轮播图片过渡 */
.carousel-item {
transition: opacity 1.2s ease-in-out !important;
}
.carousel-item.ken-burns-enabled {
transform-origin: center center !important; /* 确保缩放从中心开始 */
scale: 1.0;
translate: 0 0 0;
}
.carousel-item.ken-burns-enabled.is-animating {
animation: ken-burns 12s linear forwards !important;
}
.carousel-item:not(.ken-burns-enabled) {
scale: 1.0;
translate: 0 0 0; /* 取消默认缩放 */
}
/* 当前图片缩放效果 */
.carousel-item.opacity-100 {
opacity: 1 !important;
}
/* 非当前图片缩放效果 */
.carousel-item.opacity-0 {
opacity: 0 !important;
}
}
/* 移动端轮播图片 */
@media (max-width: 1279px) {
/* 确保轮播容器有正确的 overflow 设置 */
#banner-carousel {
overflow: hidden !important;
}
/* 图片容器 */
.carousel-item img,
#banner img {
object-position: center center !important; /* 确保图片居中显示 */
transition: transform 1.2s ease-out !important;
}
/* 轮播图片过渡 */
.carousel-item {
transition: opacity 1.2s ease-in-out !important;
}
.carousel-item.ken-burns-enabled {
transform-origin: center center !important; /* 确保缩放从中心开始 */
scale: 1.0;
}
.carousel-item.ken-burns-enabled.is-animating {
animation: ken-burns 12s linear forwards !important;
}
.carousel-item:not(.ken-burns-enabled) {
scale: 1.0; /* 取消默认缩放 */
}
/* 当前图片缩放效果 */
.carousel-item.opacity-100 {
opacity: 1 !important;
}
/* 非当前图片缩放效果 */
.carousel-item.opacity-0 {
opacity: 0 !important;
}
}
/* 移动端 banner 性能 */
@media (max-width: 1279px) {
.banner-container {
/* 启用硬件加速 */
translate: 0 0 0;
will-change: transform, opacity;
/* 渲染性能 */
contain: layout style paint;
/* 减少重绘 */
backface-visibility: hidden;
-webkit-backface-visibility: hidden;
}
/* 图片 */
.banner-container img {
/* 图片渲染 */
image-rendering: -webkit-optimize-contrast;
image-rendering: crisp-edges;
/* 防止图片拖拽 */
-webkit-user-drag: none;
-khtml-user-drag: none;
-moz-user-drag: none;
-o-user-drag: none;
/* 触摸 */
pointer-events: none;
}
.banner-text-overlay {
/* 文字渲染 */
-webkit-font-smoothing: antialiased;
-moz-osx-font-smoothing: grayscale;
text-rendering: optimizeLegibility;
/* 减少重排 */
contain: layout style;
}
.carousel-item.ken-burns-enabled {
/* 硬件加速与缩放维持 */
scale: 1.0;
translate: 0 0 0;
will-change: transform, opacity;
/* 触摸响应 */
touch-action: pan-y;
-webkit-touch-callout: none;
-webkit-user-select: none;
user-select: none;
}
.carousel-item:not(.ken-burns-enabled) {
scale: 1.0;
translate: 0 0 0;
will-change: transform, opacity;
/* 触摸响应 */
touch-action: pan-y;
-webkit-touch-callout: none;
-webkit-user-select: none;
user-select: none;
}
/* 轮播指示器 */
.carousel-indicators {
position: absolute;
bottom: 20px;
left: 50%;
translate: -50% 0;
display: flex;
gap: 8px;
z-index: 10;
}
.carousel-indicator {
width: 8px;
height: 8px;
border-radius: 50%;
background: rgba(255, 255, 255, 0.5);
transition: all 0.3s ease;
cursor: pointer;
}
.carousel-indicator.active {
background: rgba(255, 255, 255, 0.9);
scale: 1.2;
}
}
/* 移动端暗色模式 */
@media (max-width: 1279px) and (prefers-color-scheme: dark) {
.banner-text-overlay {
background: linear-gradient(
to top,
rgba(0, 0, 0, 0.8) 0%,
rgba(0, 0, 0, 0.4) 50%,
transparent 100%
);
}
}
/* 移动端横屏 */
@media (max-width: 1279px) and (orientation: landscape) {
.banner-text-overlay {
padding: 1rem 1.5rem;
align-items: center !important; /* 垂直居中 */
justify-content: center !important; /* 水平居中 */
text-align: center !important; /* 文字居中对齐 */
}
.banner-title {
font-size: 2.2rem !important; /* 增大字体大小 */
line-height: 1.3;
}
.banner-subtitle {
font-size: 0.9rem;
margin-top: 0.5rem;
}
}
/* 平板 */
@media (min-width: 768px) and (max-width: 1279px) {
/* 横幅文本覆盖层 */
.banner-text-overlay {
align-items: center !important; /* 垂直居中 */
justify-content: center !important; /* 水平居中 */
padding: 2rem !important;
text-align: center !important; /* 文字居中对齐 */
}
/* 文本容器 */
.banner-text-overlay > div {
margin-bottom: 0 !important; /* 移除底部边距,保持居中 */
width: 85% !important;
text-align: center !important; /* 确保文字居中 */
}
/* 标题文本 */
.banner-title {
font-size: 4rem !important;
line-height: 1.1 !important;
margin-bottom: 1rem !important;
}
/* 副标题文本 */
.banner-subtitle {
font-size: 1.5rem !important;
line-height: 1.4 !important;
}
}
/* 中屏手机 */
@media (min-width: 513px) and (max-width: 768px) {
/* 横幅文本覆盖层 */
.banner-text-overlay {
align-items: center !important; /* 垂直居中 */
justify-content: center !important; /* 水平居中 */
padding: 1.5rem !important;
text-align: center !important; /* 文字居中对齐 */
}
/* 文本容器 */
.banner-text-overlay > div {
margin-bottom: 0 !important; /* 移除底部边距,保持居中 */
width: 90% !important;
text-align: center !important; /* 确保文字居中 */
}
/* 标题文本 */
.banner-title {
font-size: 3.8rem !important; /* 增大字体大小 */
line-height: 1.1 !important;
margin-bottom: 0.75rem !important;
}
/* 副标题文本 */
.banner-subtitle {
font-size: 1.125rem !important;
line-height: 1.4 !important;
}
}
/* 小屏手机 */
@media (max-width: 512px) {
/* 横幅文本覆盖层 */
.banner-text-overlay {
align-items: center !important; /* 垂直居中 */
justify-content: center !important; /* 水平居中 */
padding: 1rem !important;
text-align: center !important; /* 文字居中对齐 */
}
/* 文本容器 */
.banner-text-overlay > div {
margin-bottom: 0 !important; /* 移除底部边距,保持居中 */
width: 95% !important; /* 增加文本宽度利用率 */
text-align: center !important; /* 确保文字居中 */
}
/* 标题文本 */
.banner-title {
font-size: 3.2rem !important; /* 增大字体大小 */
line-height: 1.1 !important;
margin-bottom: 0.5rem !important;
}
/* 副标题文本 */
.banner-subtitle {
font-size: 1rem !important;
line-height: 1.3 !important;
}
}
/**
* 波浪
*/
/* 波浪动画 */
@keyframes wave {
0% {
translate: -90px 0 0;
}
100% {
translate: 85px 0 0;
}
}
/* 波浪与背景同步切换 */
#header-waves {
/* 确保波浪容器与页面背景在同一合成层 */
isolation: isolate;
/* 优化渲染性能 - 移除 strict containment 改用 none */
contain: none;
/* 精确对齐 */
margin-bottom: -1px;
}
/* 统一波浪动画 */
#header-waves .parallax use {
animation-name: wave;
animation-duration: 25s;
animation-timing-function: cubic-bezier(0.5, 0.5, 0.45, 0.5);
animation-iteration-count: infinite;
transform: translateZ(0);
will-change: transform;
backface-visibility: hidden;
}
/* 分层动画时序(替代内联 style */
#header-waves .parallax use:nth-child(1) {
animation-duration: 7s;
animation-delay: -2s;
}
#header-waves .parallax use:nth-child(2) {
animation-duration: 10s;
animation-delay: -3s;
}
#header-waves .parallax use:nth-child(3) {
animation-duration: 13s;
animation-delay: -4s;
}
#header-waves .parallax use:nth-child(4) {
animation-duration: 20s;
animation-delay: -5s;
}
#header-waves .waves {
/* 确保 SVG 完整渲染svg 本身即为 .waves */
width: 100%;
height: 100%;
display: block;
/* 确保水波纹完整显示 */
overflow: visible;
z-index: 5;
/* 硬件加速,确保与背景同步渲染 */
transform: translateZ(0);
will-change: transform;
backface-visibility: hidden;
/* 优化渲染性能 - 移除 strict containment 改用 none */
contain: none;
}
/* 波浪填充色主题切换 */
#header-waves .waves use {
/* 确保填充色与页面背景同步更新 */
will-change: fill;
}
/* 主题切换时的额外保护 */
.theme-changing #header-waves,
.theme-changing #header-waves svg,
.theme-changing #header-waves use {
/* 在主题切换期间禁用所有可能的渲染延迟 */
will-change: auto;
transform: translateZ(0);
backface-visibility: hidden;
}
/* 移动端水波纹特殊 */
@media (max-width: 1023px) {
#header-waves {
/* 确保水波纹容器不被裁剪 */
overflow: visible;
z-index: 5;
}
#header-waves .waves {
/* 移动端SVG */
min-height: 60px;
}
}