claude fable 5 天气卡片测试

gl6 2026-06-10 01:47 1

以 iOS 18 的设计风格做一个带有动画效果的天气卡片,要求是使用 HTML、CSS 和基础 JavaScript,使用横板天气页面(拥有 4 个天气卡片 (晴天,大风,暴雨,暴雪))。应足够美观,实现一定的交互效果。

总花费5m41s



效果图:




html

`



天气 · iOS 18

* { margin: 0; padding: 0; box-sizing: border-box; -webkit-tap-highlight-color: transparent; }

html, body { min-height: 100vh; }


body {

font-family: -apple-system, BlinkMacSystemFont, “SF Pro Display”, “SF Pro Text”,

“PingFang SC”, “Helvetica Neue”, “Microsoft YaHei”, sans-serif;

color: #fff;

display: flex;

flex-direction: column;

overflow-x: hidden;

background: #0e1322;

}


/* ---------- 全局氛围背景(点击卡片交叉淡入) ---------- /

.bg {

position: fixed; inset: 0; z-index: -2;

opacity: 0;

transition: opacity 1.2s ease;

pointer-events: none;

}

.bg.visible { opacity: 1; }

.bg[data-w=“default”] {

background: linear-gradient(165deg, #0f1020 0%, #1c2541 55%, #2a3550 100%);

}

.bg[data-w=“sunny”] {

background:

radial-gradient(1100px 620px at 82% -8%, rgba(255, 187, 92, .50), transparent 62%),

linear-gradient(168deg, #1a3a66 0%, #2c5a9e 52%, #6f9fd4 100%);

}

.bg[data-w=“windy”] {

background:

radial-gradient(900px 500px at 15% 8%, rgba(173, 226, 219, .22), transparent 60%),

linear-gradient(168deg, #14303a 0%, #2b5f63 55%, #4f8a7c 100%);

}

.bg[data-w=“rain”] {

background:

radial-gradient(900px 540px at 75% 0%, rgba(120, 132, 220, .25), transparent 60%),

linear-gradient(168deg, #090f20 0%, #18233f 55%, #2c3a5e 100%);

}

.bg[data-w=“snow”] {

background:

radial-gradient(1000px 560px at 50% -10%, rgba(225, 238, 252, .28), transparent 65%),

linear-gradient(168deg, #1b2940 0%, #38536e 55%, #7795ae 100%);

}

body::after { /
轻微暗角,增强层次 */

content: “”; position: fixed; inset: 0; z-index: -1; pointer-events: none;

background: radial-gradient(120% 90% at 50% 40%, transparent 55%, rgba(0,0,0,.35) 100%);

}


/* ---------- 顶部栏 ---------- */

header {

display: flex; justify-content: space-between; align-items: flex-end;

padding: 38px 52px 6px;

}

header h1 { font-size: 36px; font-weight: 700; letter-spacing: .5px; }

.date { margin-top: 6px; font-size: 15px; color: rgba(255,255,255,.65); }

.clock-wrap { text-align: right; }

.clock { font-size: 32px; font-weight: 200; font-variant-numeric: tabular-nums; letter-spacing: 1px; }

.status {

margin-top: 4px; font-size: 13px; color: rgba(255,255,255,.6);

}

.status.swap { animation: status-in .5s ease; }

@keyframes status-in {

from { opacity: 0; transform: translateY(6px); }

to { opacity: 1; transform: translateY(0); }

}


/* ---------- 横板卡片区 ---------- */

.cards {

flex: 1;

display: flex; align-items: center;

gap: 26px;

padding: 26px 52px 18px;

perspective: 1500px;

overflow-x: auto;

scroll-snap-type: x proximity;

}

.cards::-webkit-scrollbar { display: none; }


.card {

position: relative;

flex: 1;

min-width: 252px;

height: 460px;

border-radius: 32px;

overflow: hidden;

cursor: pointer;

scroll-snap-align: center;

background: rgba(255,255,255,.08);

-webkit-backdrop-filter: blur(30px) saturate(160%);

backdrop-filter: blur(30px) saturate(160%);

border: .5px solid rgba(255,255,255,.22);

box-shadow: 0 22px 55px rgba(0,0,0,.38);

transition: transform .8s cubic-bezier(.22,1,.36,1),

box-shadow .45s ease, opacity .6s ease, filter .6s ease;

animation: enter .9s cubic-bezier(.22,1,.36,1) backwards;

animation-delay: calc(var(–i) * 110ms);

outline: none;

}

@keyframes enter {

from { opacity: 0; transform: translateY(46px) scale(.96); }

to { opacity: 1; transform: translateY(0) scale(1); }

}

.card:focus-visible { box-shadow: 0 0 0 2.5px rgba(255,255,255,.8), 0 22px 55px rgba(0,0,0,.38); }

.card.active {

transform: translateY(-10px) scale(1.04);

box-shadow: 0 0 0 1.5px rgba(255,255,255,.6), 0 32px 75px rgba(0,0,0,.5);

}

.cards.has-active .card:not(.active) {

opacity: .58; filter: saturate(.8) brightness(.9);

}


/* 每张卡的玻璃底色微调 */

.card.sunny { background: linear-gradient(180deg, rgba(255,178,84,.20), rgba(255,255,255,.05) 60%); }

.card.windy { background: linear-gradient(180deg, rgba(150,225,210,.16), rgba(255,255,255,.05) 60%); }

.card.rain { background: linear-gradient(180deg, rgba(86,110,190,.24), rgba(255,255,255,.04) 60%); }

.card.snow { background: linear-gradient(180deg, rgba(214,233,252,.20), rgba(255,255,255,.05) 60%); }


/* 鼠标高光(随光标移动的镜面反射) */

.glare {

position: absolute; inset: 0; z-index: 5; pointer-events: none;

border-radius: inherit;

opacity: 0; transition: opacity .4s ease;

background: radial-gradient(380px circle at var(–mx, 50%) var(–my, 50%),

rgba(255,255,255,.22), transparent 62%);

}

.card:hover .glare { opacity: 1; }


/* ---------- 卡片文字内容 ---------- */

.card-content {

position: relative; z-index: 3;

height: 100%;

padding: 24px 22px 22px;

display: flex; flex-direction: column;

}

.card-top { display: flex; justify-content: space-between; align-items: flex-start; }

.city { font-size: 19px; font-weight: 600; letter-spacing: .3px; }

.cond { margin-top: 3px; font-size: 13px; color: rgba(255,255,255,.72); }

.badge {

font-size: 17px; line-height: 1;

background: rgba(255,255,255,.14);

border: .5px solid rgba(255,255,255,.18);

border-radius: 100px; padding: 7px 9px;

}

.spacer { flex: 1; }

.temp { font-size: 68px; font-weight: 200; line-height: 1; letter-spacing: -2px; }

.temp sup { font-size: 36px; font-weight: 300; vertical-align: 18px; letter-spacing: 0; }

.range { margin-top: 8px; font-size: 13px; color: rgba(255,255,255,.72); }

.metrics {

margin-top: 16px;

display: grid; grid-template-columns: 1fr 1fr 1fr;

gap: 4px;

background: rgba(255,255,255,.10);

border: .5px solid rgba(255,255,255,.14);

border-radius: 18px;

padding: 11px 8px;

}

.metric { text-align: center; }

.metric b { display: block; font-size: 14px; font-weight: 600; }

.metric span {

display: block; margin-top: 3px;

font-size: 10px; letter-spacing: .6px;

color: rgba(255,255,255,.55);

}


/* ---------- 动画舞台 ---------- */

.scene {

position: absolute; inset: 0; z-index: 1;

border-radius: inherit; overflow: hidden;

-webkit-mask-image: linear-gradient(to bottom, transparent 0, #000 26px);

mask-image: linear-gradient(to bottom, transparent 0, #000 26px);

pointer-events: none;

}


/* ===== 晴天 ===== /

.sun {

position: absolute; top: 58px; left: 50%;

width: 92px; height: 92px; margin-left: -46px;

border-radius: 50%;

background: radial-gradient(circle at 35% 35%, #fff6d8, #ffd76e 45%, #ffae34 78%);

animation: sun-pulse 4.5s ease-in-out infinite;

}

@keyframes sun-pulse {

0%, 100% { box-shadow: 0 0 55px 18px rgba(255,190,80,.50); transform: scale(1); }

50% { box-shadow: 0 0 90px 32px rgba(255,190,80,.72); transform: scale(1.05); }

}

.sun-rays {

position: absolute; top: 104px; left: 50%;

width: 0; height: 0;

animation: spin 26s linear infinite;

}

@keyframes spin { to { transform: rotate(360deg); } }

.sun-rays i {

position: absolute; left: -2.5px; top: -16px;

width: 5px; height: 32px; border-radius: 3px;

background: linear-gradient(to top, rgba(255,205,100,0), rgba(255,218,128,.95));

animation: ray-flick 2.6s ease-in-out infinite;

}

@keyframes ray-flick {

0%, 100% { opacity: .55; } 50% { opacity: 1; }

}

.sun-rays i:nth-child(1) { transform: rotate(0deg) translateY(-88px); }

.sun-rays i:nth-child(2) { transform: rotate(45deg) translateY(-88px); animation-delay: .3s; }

.sun-rays i:nth-child(3) { transform: rotate(90deg) translateY(-88px); animation-delay: .6s; }

.sun-rays i:nth-child(4) { transform: rotate(135deg) translateY(-88px); animation-delay: .9s; }

.sun-rays i:nth-child(5) { transform: rotate(180deg) translateY(-88px); animation-delay: 1.2s; }

.sun-rays i:nth-child(6) { transform: rotate(225deg) translateY(-88px); animation-delay: 1.5s; }

.sun-rays i:nth-child(7) { transform: rotate(270deg) translateY(-88px); animation-delay: 1.8s; }

.sun-rays i:nth-child(8) { transform: rotate(315deg) translateY(-88px); animation-delay: 2.1s; }

.mote { /
漂浮的光尘 */

position: absolute;

border-radius: 50%;

background: rgba(255, 226, 160, .9);

filter: blur(.5px);

animation: mote linear infinite;

}

@keyframes mote {

0% { transform: translateY(30px); opacity: 0; }

25% { opacity: .85; }

100% { transform: translateY(-160px); opacity: 0; }

}


/* ===== 云(大风 / 暴雨 / 暴雪共用基础形状) ===== */

.cloud {

position: absolute;

width: 96px; height: 32px; border-radius: 32px;

background: rgba(255,255,255,.85);

}

.cloud::before, .cloud::after {

content: “”; position: absolute; border-radius: 50%;

background: inherit;

}

.cloud::before { width: 44px; height: 44px; left: 13px; top: -21px; }

.cloud::after { width: 30px; height: 30px; right: 15px; top: -12px; }


/* ===== 大风 ===== */

.windy .cloud.c1 { top: 86px; left: -120px; animation: drift 13s linear infinite; }

.windy .cloud.c2 {

top: 142px; left: -120px; opacity: .65; transform: scale(.62);

animation: drift 8.5s linear infinite; animation-delay: -4s;

}

@keyframes drift {

from { translate: 0 0; } to { translate: 560px 0; }

}

.gust {

position: absolute; left: -160px;

width: 130px; height: 3.5px; border-radius: 4px;

background: linear-gradient(90deg, transparent, rgba(255,255,255,.9), rgba(255,255,255,0));

animation: gust 2.4s ease-in infinite;

}

@keyframes gust {

0% { transform: translateX(0); opacity: 0; }

18% { opacity: .95; }

80% { opacity: .9; }

100% { transform: translateX(620px); opacity: 0; }

}

.windy .gust.g1 { top: 70px; }

.windy .gust.g2 { top: 122px; animation-delay: .8s; animation-duration: 2s; }

.windy .gust.g3 { top: 176px; animation-delay: 1.5s; width: 90px; }

.leaf {

position: absolute; top: 120px; left: -36px;

font-size: 17px;

animation: leaf 4.2s ease-in infinite;

}

@keyframes leaf {

0% { transform: translate(0, 0) rotate(0deg); opacity: 0; }

12% { opacity: 1; }

60% { transform: translate(300px, 52px) rotate(420deg); opacity: 1; }

100% { transform: translate(540px, 22px) rotate(760deg); opacity: 0; }

}


/* ===== 暴雨 ===== */

.storm-cloud {

position: absolute; top: -34px; left: -8%;

width: 116%; height: 120px;

background: radial-gradient(62% 86% at 50% 24%,

rgba(72, 84, 112, .96), rgba(42, 50, 74, .65) 62%, transparent 100%);

filter: blur(2px);

animation: cloud-bob 6s ease-in-out infinite;

}

.storm-cloud.back {

top: -20px; left: 20%; width: 90%; height: 90px;

opacity: .7; animation-delay: -3s;

}

@keyframes cloud-bob {

0%, 100% { transform: translateY(0); } 50% { transform: translateY(6px); }

}

.storm-cloud.snowy {

background: radial-gradient(62% 86% at 50% 24%,

rgba(212, 222, 236, .8), rgba(160, 176, 198, .45) 62%, transparent 100%);

}

.drop {

position: absolute; top: -26px;

width: 2px;

border-radius: 2px;

background: linear-gradient(to bottom, rgba(173,216,255,0), rgba(173,216,255,.85));

animation: drop-fall linear infinite;

}

@keyframes drop-fall {

from { transform: translate3d(0, 0, 0) rotate(12deg); }

to { transform: translate3d(-120px, 560px, 0) rotate(12deg); }

}

.flash {

position: absolute; inset: 0; z-index: 2;

background: radial-gradient(80% 60% at 50% 18%, rgba(255,255,255,.95), rgba(210,220,255,.35) 70%);

opacity: 0;

animation: flash 7s linear infinite;

}

@keyframes flash {

0%, 50.8%, 54.6%, 58.5%, 100% { opacity: 0; }

51.6%, 53.4% { opacity: .85; }

56.5% { opacity: .4; }

}

.bolt {

position: absolute; top: 64px; left: 50%;

width: 58px; height: 96px; margin-left: -29px;

background: linear-gradient(180deg, #fff4cd, #ffd966);

clip-path: polygon(42% 0, 68% 0, 50% 36%, 66% 36%, 30% 100%, 43% 52%, 26% 52%);

filter: drop-shadow(0 0 14px rgba(255, 226, 140, .95));

opacity: 0;

animation: bolt 7s linear infinite;

}

@keyframes bolt {

0%, 51.2%, 53.8%, 100% { opacity: 0; }

51.8%, 53.2% { opacity: 1; }

}


/* ===== 暴雪 ===== */

.flake {

position: absolute; top: -14px;

border-radius: 50%;

background: #fff;

animation: flake-fall linear infinite;

}

@keyframes flake-fall {

from { transform: translate3d(0, 0, 0); }

to { transform: translate3d(var(–drift, -60px), 545px, 0); }

}

.snow .gust { opacity: .6; }

.snow .gust.g1 { top: 150px; animation-delay: .4s; }

.snow .gust.g2 { top: 235px; animation-delay: 1.6s; animation-duration: 1.9s; }

.frost {

position: absolute; left: 0; right: 0; bottom: 0; height: 96px;

background: linear-gradient(to top, rgba(255,255,255,.16), transparent);

}


/* ---------- 底部提示 ---------- */

footer {

text-align: center;

padding: 4px 0 26px;

font-size: 13px; color: rgba(255,255,255,.45);

}


@media (max-width: 720px) {

header { padding: 28px 26px 4px; }

.cards { padding: 22px 26px 14px; }

.clock { font-size: 24px; }

}

@media (prefers-reduced-motion: reduce) {

*, *::before, *::after { animation: none !important; transition: none !important; }

}










天气





--:--:--

点击卡片,沉浸感受四种天气



<!-- 晴天 -->
<article class="card sunny" data-weather="sunny" style="--i:0" tabindex="0"
role="button" aria-pressed="false" aria-label="北京,晴朗,28度">
<div class="scene">
<div class="sun-rays"><i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i></div>
<div class="sun"></div>
<div class="mote-layer"></div>
</div>
<div class="glare"></div>
<div class="card-content">
<div class="card-top">
<div>
<div class="city">北京</div>
<div class="cond">晴朗</div>
</div>
<div class="badge">☀️</div>
</div>
<div class="spacer"></div>
<div class="temp"><span class="temp-num" data-temp="28">28</span><sup>°</sup></div>
<div class="range">最高 32° · 最低 21°</div>
<div class="metrics">
<div class="metric"><b>32%</b><span>湿度</span></div>
<div class="metric"><b>6 km/h</b><span>风速</span></div>
<div class="metric"><b>很强</b><span>紫外线</span></div>
</div>
</div>
</article>

<!-- 大风 -->
<article class="card windy" data-weather="windy" style="--i:1" tabindex="0"
role="button" aria-pressed="false" aria-label="大连,大风,22度">
<div class="scene">
<span class="gust g1"></span>
<span class="gust g2"></span>
<span class="gust g3"></span>
<div class="cloud c1"></div>
<div class="cloud c2"></div>
<span class="leaf">🍃</span>
</div>
<div class="glare"></div>
<div class="card-content">
<div class="card-top">
<div>
<div class="city">大连</div>
<div class="cond">大风</div>
</div>
<div class="badge">💨</div>
</div>
<div class="spacer"></div>
<div class="temp"><span class="temp-num" data-temp="22">22</span><sup>°</sup></div>
<div class="range">最高 24° · 最低 17°</div>
<div class="metrics">
<div class="metric"><b>64 km/h</b><span>阵风</span></div>
<div class="metric"><b>西北</b><span>风向</span></div>
<div class="metric"><b>45%</b><span>湿度</span></div>
</div>
</div>
</article>

<!-- 暴雨 -->
<article class="card rain" data-weather="rain" style="--i:2" tabindex="0"
role="button" aria-pressed="false" aria-label="广州,暴雨,24度">
<div class="scene">
<div class="bolt"></div>
<div class="storm-cloud back"></div>
<div class="storm-cloud"></div>
<div class="rain-layer"></div>
<div class="flash"></div>
</div>
<div class="glare"></div>
<div class="card-content">
<div class="card-top">
<div>
<div class="city">广州</div>
<div class="cond">暴雨</div>
</div>
<div class="badge">⛈️</div>
</div>
<div class="spacer"></div>
<div class="temp"><span class="temp-num" data-temp="24">24</span><sup>°</sup></div>
<div class="range">最高 26° · 最低 22°</div>
<div class="metrics">
<div class="metric"><b>48 mm</b><span>降水</span></div>
<div class="metric"><b>93%</b><span>湿度</span></div>
<div class="metric"><b>1.2 km</b><span>能见度</span></div>
</div>
</div>
</article>

<!-- 暴雪 -->
<article class="card snow" data-weather="snow" style="--i:3" tabindex="0"
role="button" aria-pressed="false" aria-label="哈尔滨,暴雪,零下12度">
<div class="scene">
<div class="storm-cloud snowy back"></div>
<div class="storm-cloud snowy"></div>
<div class="snow-layer"></div>
<span class="gust g1"></span>
<span class="gust g2"></span>
<div class="frost"></div>
</div>
<div class="glare"></div>
<div class="card-content">
<div class="card-top">
<div>
<div class="city">哈尔滨</div>
<div class="cond">暴雪</div>
</div>
<div class="badge">🌨️</div>
</div>
<div class="spacer"></div>
<div class="temp"><span class="temp-num" data-temp="-12">-12</span><sup>°</sup></div>
<div class="range">最高 -8° · 最低 -19°</div>
<div class="metrics">
<div class="metric"><b>26 cm</b><span>降雪</span></div>
<div class="metric"><b>-19°</b><span>体感</span></div>
<div class="metric"><b>0.4 km</b><span>能见度</span></div>
</div>
</div>
</article>


移动鼠标查看光影 · 点击卡片切换全局氛围

`
最新回复 (15)
  • Madlifer 06-10 01:51
    1

    L站依旧新模型一出就天气卡片这一块

  • gl6 楼主 06-10 01:51
    2

    说实话做的还可以,点击不同卡片会切换全局光影

  • gl6 楼主 06-10 01:54
    3

    opus4.8


    deepseekv4pro:

  • Eevee 06-10 01:54
    4

    这张效果就很不错


    色彩用得非常舒服

  • gl6 楼主 06-10 01:55
    5

    我也觉得,claude这个审美前端最近一直在前列的

  • Takeapocket 06-10 01:55
    6

    哇,这个比隔壁佬测的那个好看多了呀 ^-^

  • 咖啡泡橘猫 06-10 01:55
    7

    牛逼啊哥!牛逼啊哥!居然让他写完了!我测了一个小游戏,连写都没给我写,就额度就用没了

  • Galaxy_Ron 06-10 01:57
    8

    看起来还不错

    明天测试一下说话方式,希望能有 opus 4.6 的水平

  • 胖次糕 06-10 01:58
    9

    4.8和fable5居然差这么多,不愧神话级模型

  • gl6 楼主 06-10 02:00
    10

    max5x干了我5h的18%,太贵了就这一个卡片 ^-^

  • 哈雷彗星 06-10 02:09
    11

    不得不贴张 传奇 Sonnet 3.7


  • beautifulrem 06-10 02:10
    12

    按照A社的表格来看这个模型开xhigh就完全够用了,max纯纯边缘递减效应

  • kevechang 06-10 02:10
    13

    希望撑得住

  • mascot 06-10 02:13
    14

    感觉 ds 的也很好看了,是提示词写的好吗^-^?


    我自己跑的前端经常很糟糕^-^

  • 吃风筝的人 06-10 02:14
    15

    天气卡片已经看不出来明显效果了。


    需要找一找能高下立判的的测试才行

* 帖子来源Linux.do
返回