blog/themes/stack/assets/scss/partials/layout/list.scss
2026-07-31 15:38:57 +08:00

158 lines
4.5 KiB
SCSS

.section-card {
@include card-style;
padding: var(--small-card-padding);
display: flex;
align-items: center;
gap: var(--spacing-lg);
--separation: 15px;
.section-term {
font-size: 2.2rem;
margin: 0;
color: var(--card-text-color-main);
}
.section-description {
font-weight: normal;
color: var(--card-text-color-secondary);
font-size: 1.6rem;
margin: 0;
}
.section-details {
flex-grow: 1;
display: flex;
flex-direction: column;
gap: 8px;
}
.section-image {
img {
width: 60px;
height: 60px;
object-fit: cover;
}
}
.section-count {
color: var(--card-text-color-tertiary);
font-size: 1.4rem;
margin: 0;
font-weight: bold;
text-transform: uppercase;
}
}
@property --left-edge-fade-size {
syntax: "<length>";
inherits: false;
initial-value: 0px;
}
@property --right-edge-fade-size {
syntax: "<length>";
inherits: false;
initial-value: 64px;
}
.subsection-list {
--shadow-overlap-x: calc(var(--shadow-l2-blur) + 4px);
--shadow-overlap-y: calc(var(--shadow-l2-blur) + var(--shadow-l2-y) + 4px);
--edge-fade-size: 64px;
--left-edge-fade-size: 0px;
--right-edge-fade-size: var(--edge-fade-size);
overflow-x: auto;
/// Limit the horizontal overlap to the container padding to prevent page overflow on mobile.
/// On desktop, it still allows the full shadow to be visible.
--overlap-x: min(var(--shadow-overlap-x), var(--container-padding));
/// These values are computed from the shadow of the article-list--tile (which uses shadow-l1 and shadow-l2)
/// so that the shadow is not cut off, while staying within the viewport on small screens.
/// Clamp both sides to prevent page-level horizontal overflow.
margin-left: calc(var(--overlap-x) * -1);
margin-right: calc(var(--overlap-x) * -1);
margin-bottom: calc(var(--shadow-overlap-y) * -1);
/// Smooth fade on both horizontal edges to avoid hard cuts where shadows are clamped.
--subsection-mask-image: linear-gradient(
to right,
transparent 0%,
rgb(0 0 0 / 0.06) calc(var(--left-edge-fade-size) * 0.12),
rgb(0 0 0 / 0.2) calc(var(--left-edge-fade-size) * 0.3),
rgb(0 0 0 / 0.45) calc(var(--left-edge-fade-size) * 0.52),
rgb(0 0 0 / 0.72) calc(var(--left-edge-fade-size) * 0.76),
black var(--left-edge-fade-size),
black calc(100% - var(--right-edge-fade-size)),
rgb(0 0 0 / 0.72) calc(100% - (var(--right-edge-fade-size) * 0.76)),
rgb(0 0 0 / 0.45) calc(100% - (var(--right-edge-fade-size) * 0.52)),
rgb(0 0 0 / 0.2) calc(100% - (var(--right-edge-fade-size) * 0.3)),
rgb(0 0 0 / 0.06) calc(100% - (var(--right-edge-fade-size) * 0.12)),
transparent 100%
);
-webkit-mask-image: var(--subsection-mask-image);
mask-image: var(--subsection-mask-image);
[dir="rtl"] & {
margin-left: calc(var(--overlap-x) * -1);
margin-right: calc(var(--overlap-x) * -1);
}
.article-list--tile {
display: flex;
padding: var(--spacing-xs) var(--overlap-x) var(--shadow-overlap-y) var(--overlap-x);
width: max-content;
gap: var(--spacing-lg);
[dir="rtl"] & {
padding: var(--spacing-xs) var(--overlap-x) var(--shadow-overlap-y) var(--overlap-x);
}
article {
flex-shrink: 0;
.article-title {
margin: 0;
font-size: 1.8rem;
}
.article-details {
padding: var(--spacing-lg);
}
}
}
}
// Only apply scroll-driven edge fades in browsers that support scroll timelines.
// Browsers without support (e.g. Firefox) fall back to the static right-edge fade
// defined by the explicit CSS variable declarations above.
@supports (animation-timeline: scroll(self inline)) {
.subsection-list {
animation: subsection-left-fade linear both, subsection-right-fade linear both;
animation-timeline: scroll(self inline);
animation-range: 1px 24px, 0% 100%;
animation-timing-function: ease-out, linear;
}
}
@keyframes subsection-left-fade {
from {
--left-edge-fade-size: 0px;
}
to {
--left-edge-fade-size: var(--edge-fade-size);
}
}
@keyframes subsection-right-fade {
0%,
92% {
--right-edge-fade-size: var(--edge-fade-size);
}
100% {
--right-edge-fade-size: 0px;
}
}