<!-- 视口 -->
<section class="viewport">
<header class="header flex-col">
<!-- 位置信息 -->
<div class="location flex-col">
<span class="label">我的位置</span>
<span class="value">上海市</span>
</div>
<!-- 总结 -->
<div class="summary">12° | 有风</div>
<!-- 当前温度 -->
<div class="temperature">12</div>
<!-- 最低温和最高温 -->
<div class="temperature-range">
<div>
<span class="label">最高</span>
<span class="value">15°</span>
</div>
<div>
<span class="label">最低</span>
<span class="value">7°</span>
</div>
</div>
<!-- 天气状况 -->
<div class="condition">有风</div>
</header>
<section class="grid">
<div class="placeholder"></div>
<article style="aspect-ratio: 5/2">
<h2>每小时天气预报</h2>
</article>
<article style="aspect-ratio: 1">
<h2>10日天气预报</h2>
</article>
<article style="aspect-ratio: 1">
<h2>空气质量地图</h2>
</article>
<article class="tile">
<h2>紫外线指数</h2>
</article>
<article class="tile">
<h2>日落</h2>
</article>
<article style="aspect-ratio: 5/2">
<h2>风</h2>
</article>
<article class="tile">
<h2>体感温度</h2>
</article>
<article class="tile">
<h2>降水</h2>
</article>
<article class="tile">
<h2>能见度</h2>
</article>
<article class="tile">
<h2>湿度</h2>
</article>
<article style="aspect-ratio: 5/2">
<h2>上弦月</h2>
</article>
<article class="tile">
<h2>平均</h2>
</article>
<article class="tile">
<h2>气压</h2>
</article>
<footer>
<h2>中国上海市的天气</h2>
<p>进一步了解<a href="">天气数据</a>和<a href="">地图数据</a></p>
</footer>
</section>
</section>
html {
height: 100%;
}
body {
height: 100%;
display: flex;
align-items: center;
justify-content: center;
font-family: system-ui;
}
* {
box-sizing: border-box;
}
a {
color: inherit;
}
.flex-col {
display: flex;
flex-direction: column;
}
.viewport {
width: 390px;
height: 80vh;
padding: 0 16px;
border: 3px solid black;
overflow: hidden auto;
border-radius: 16px;
}
.header {
position: sticky;
z-index: 2;
top: 16px;
margin: 48px 0;
text-align: center;
}
.header::before {
content: "";
position: absolute;
z-index: -1;
top: -16px;
left: 0;
right: 0;
height: 96px;
background: linear-gradient(to bottom, white 50%, transparent);
}
.location > .label {
font-size: 28px;
}
.location > .value {
font-size: 12px;
margin-top: 8px;
}
.summary {
position: absolute;
left: 0;
right: 0;
top: 56px;
opacity: 0;
}
.temperature {
margin-top: 8px;
position: relative;
font-size: 80px;
font-weight: 300;
}
/* 单独处理温度符号,确保数字是居中的 */
.temperature::after {
content: "°";
position: absolute;
top: 0;
}
.temperature-range {
margin-top: 8px;
display: flex;
align-items: center;
justify-content: center;
gap: 16px;
}
.temperature-range > div {
display: flex;
}
.temperature-range .label {
margin-right: 4px;
writing-mode: vertical-lr;
}
.temperature-range .value {
font-size: 32px;
font-weight: 300;
}
.condition {
margin-top: 8px;
}
@supports (animation-timeline: scroll()) {
.summary {
animation: linear fade-in both;
animation-timeline: scroll();
animation-range: 144px 160px;
}
.temperature {
animation: linear fade-out both;
animation-timeline: scroll();
animation-range: 96px 144px;
}
.temperature-range {
animation: linear fade-out both;
animation-timeline: scroll();
animation-range: 64px 96px;
}
.condition {
animation: linear fade-out both;
animation-timeline: scroll();
animation-range: 32px 64px;
}
}
@keyframes fade-out {
to {
opacity: 0;
}
}
@keyframes fade-in {
to {
opacity: 1;
}
}
.grid {
display: grid;
grid-template-columns: repeat(2, 1fr);
gap: 16px;
margin-top: -112px;
}
.grid > .placeholder {
position: sticky;
z-index: 1;
top: 0;
grid-column: span 2;
height: 112px;
background-color: white;
}
.grid > article {
position: relative;
background-color: hsl(0, 0%, 92%);
border-radius: 16px;
}
.grid > article > h2 {
position: sticky;
top: 96px;
z-index: 1;
padding: 8px 16px;
background-color: inherit;
border-radius: inherit;
}
.grid > article:not(.tile) {
grid-column: span 2;
}
.grid > .tile {
aspect-ratio: 1;
}
.grid > footer {
grid-column: span 2;
text-align: center;
margin-bottom: 48px;
}
.grid > footer > h2 {
font-weight: 600;
}
.grid > footer > p {
margin-top: 8px;
font-size: 12px;
}
This Pen doesn't use any external CSS resources.
This Pen doesn't use any external JavaScript resources.