Video yükleniyor...

Video Yüklenemedi

Ana Sayfaya Dön

CSS only balance sliders 🤙 @​keyframes sync { to { --value: 1; }} .slider { animation: sync; animation-timeline: --thumb; } .track { scale: var(--value) 1; } ::-webkit-slider-thumb { view-timeline: --thumb inline; } Scroll-animated input [type=range] in disguise 🥸

276,038 görüntüleme • 2 yıl önce •via X (Twitter)

10 Yorum

Sam Rose profil fotoğrafı
Sam Rose2 yıl önce

What fucking sorcery is this and where can I learn it?

Simon Lind profil fotoğrafı
Simon Lind2 yıl önce

Very cool! Do you think there’s a way to make the small effect from iOS when the slider value is extending beyond its max with css?

jhey ▲🐻🎈 profil fotoğrafı
jhey ▲🐻🎈2 yıl önce

Ahh - Thank you for sending me a clip of this. There was a comment about it and I don't have an iPhone to see it in action. Can totally give this a touch of progressive enhancement 💯

˗ˏˋ rogie ˎˊ˗ profil fotoğrafı
˗ˏˋ rogie ˎˊ˗2 yıl önce

This is hot

Nick Taylor profil fotoğrafı
Nick Taylor2 yıl önce

This is so sick and slick. 🔥🔥🔥

Shantanu Sutar profil fotoğrafı
Shantanu Sutar2 yıl önce

Simple and sleek 😎

MVED profil fotoğrafı
MVED2 yıl önce

Can you share the codepen? I want to try on iphone to see how the feeling compares to the native animation

〽️ɪɢᴜᴇʟ 🎃 profil fotoğrafı
〽️ɪɢᴜᴇʟ 🎃2 yıl önce

This is a genius use of delegator pattern.

Mery profil fotoğrafı
Mery2 yıl önce

Yes 100% @Apple needs to take some notes

Parker Rex profil fotoğrafı
Parker Rex2 yıl önce

Got damn this is nice

Benzer Videolar

CSS in 2024 🤯 You can create a range slider with updating value tooltip and color changing track without using any JavaScript 🤯 ::-webkit-slider-thumb{ view-timeline: --thumb inline; } Scroll animation on the slider thumb that animates a number between the "min" and "max" of the range 😅 @​property --value { syntax: ' '; } @​keyframes sync { to { --value: 100; }} Tie that up to the contain animation-range ⚡️ .control { animation: sync both linear reverse; animation-timeline: --thumb; animation-range: contain; } Hoist the view timeline so the tooltip can use the value too! :root { timeline-scope: --thumb; } Then use it in the counter which goes in the tooltip 😇 .tooltip { counter-reset: val var(--value); } .tooltip::after { content: counter(val); } Then the accent color is based on the value too 🎨 [type=range] { accent-color: hsl(var(--value) 90% 65%); } The magic from the quoted post is using anchor positioning on the range thumb to position that tooltip 👏 Never thought of that when working on the spec for this API. This API lets you tether elements to other elements. Using the pseudo is a clever move! ::-webkit-slider-thumb { anchor-name: --thumb; } .tooltip { position: absolute; anchor-default: --thumb; left: anchor(50%); bottom: calc(anchor(top) + 25%); } The last piece is the little bounce transition... OK. I used a line or two of JavaScript for that 🙏😬 const updateDelta = ({ movementX }) => { document​.documentElement​.style.setProperty('--delta-x', movementX) } document.body.addEventListener('pointermove', updateDelta) But only so you can pass the movement delta to CSS and then reset the position with linear() to get that bouncy transition 😎 .hint { rotate: calc(clamp(-60, var(--delta-x) * -1, 60) * 1deg); transition: rotate 1s linear( 0, 0.2178 2.1%, 1.1144 8.49%, ... ); } Should probably do a video on this one. Lots of little tricks to break down with it for sure! 💯 As always, any questions, let me know! Also, this one only works in Chrome Canary with the Experimental Web Platform Features flag enabled ✅ This one almost feels like rocket science ha 🚀 CodePen.IO link below! 👇

jhey ʕ•ᴥ•ʔ

251,867 görüntüleme • 2 yıl önce

CSS Tip! 🤯 You can create a CSS-only version of this balance slider using a scroll animation on the underlying input[type=range] 🚀 ::-webkit-slider-thumb { view-timeline: --thumb inline; } Scroll animation driven by the slider thumb animates a number between the "min" and "max" of the range 😅 @​property --value { inherits: true; initial-value: 0; syntax: ' '; } @​keyframes sync { to { --value: 100; }} Tie that up to the contain animation-range ⚡️ .control { animation: sync both linear reverse; animation-timeline: --thumb; animation-range: contain; } Hoist the view timeline so all the parts of the control can use it! .control { timeline-scope: --thumb; } Use that value in a counter which is used for the labels. Create a low and a high for each side 😇 .control__label { counter-reset: low var(--value) high calc(100 - var(--value)); } .control__label::before { content: "COFFEE " counter(low) "%"; } .control__label::after { content: counter(high) "% MILK"; } That's the magic of updating the label values ✨ For the big track, it's a fake track. You can make use of the same --value property and do some calc() to work out the width of each part. .control__track::before { width: calc(var(--value) * 1% - 0.5rem); background: var(--coffee); border-radius: 4px; transition: width 0.1s; } The width leaves a little gap for the indicator piece 🤙 The color calculation for --coffee isn't too wild but again you can use the same --value .control__track { --coffee: hsl(24 74% calc( 24% + (30% * ((100 - var(--value, 0)) / 100)) / 1 ) / 0.4); } Now for the last piece. Making the track change height. You could set up another custom property and animate its value using the --thumb timeline too 🔥 @​property --shift { initial-value: 0; inherits: true; syntax: ' '; } @​keyframes shift { 0%, 31%, 61%, 100% { --shift: 0; } 32%, 60% { --shift: 1; } } Then use that --shift to update the translation of the label and height of the track 🤓 .label { transform: translateY(calc(var(--shift) * 50%)); transition: transform var(--speed) var(--timing); } Cool part here is that you can use the control to work out the @​keyframes percentages 😅 Oh. And the timing for that little bounce? Use the linear() function 😎 :root { --timing: linear( 0, 0.5007 7.21%, 0.7803 12.29%, 0.8883 14.93%, 0.9724 17.63%, 1.0343 20.44%, 1.0754 23.44%, 1.0898 25.22%, 1.0984 27.11%, 1.1014 29.15%, 1.0989 31.4%, 1.0854 35.23%, 1.0196 48.86%, 1.0043 54.06%, 0.9956 59.6%, 0.9925 68.11%, 1 ); } Should probably do a video on this one. Lots of little custom property tricks for sure! 💯 It's not too far off the range slider with the tooltip that came up previously As always, any questions, let me know! Also, this one only works in Chrome currently ✅🥲 This one's a bit rocket science ha 🚀 CodePen.IO link below! 👇

jhey ʕ•ᴥ•ʔ

377,792 görüntüleme • 2 yıl önce

CSS Tip! 🚥 You can create these trending expanding scroll indicators with scroll-driven animations and flex 🤙 .indicator { animation: grow; animation-range: contain calc(50% - var(--size)...; animation-timeline: var(--card); } @​keyframes grow { 50% { flex: 3; }} What's the trick? Put the indicators in a container using flex layout and set a width larger than the number of indicators 😉 .indicators { aspect-ratio: 7 / 1; display: flex; } Importantly, set no gap 🤏 To mimic the gap set a transparent border on each indicator and set the background using padding-box .indicator { background: linear-gradient(#​fff, #​fff) padding-box; border-radius: 50px; border: 4px solid transparent; } Now for the animation. You want to create a view-timeline for each card that moves across 🤙 li:nth-of-type(1) { view-timeline: --one inline; } li:nth-of-type(2) { view-timeline: --two inline; } Make sure they use the inline axis too! The trick is hoisting these view-timeline so the indicators can use them with timeline-scope 👀 .track { timeline-scope: --one, --two, ...; } All that's left is for you to create the animation piece using some calc with the card size ⚡️ .indicator { --size: calc(var(--card-width) * 0.9); animation: grow both linear; animation-range: contain calc(50% - var(--size)) contain calc(50% + var(--size)); } .indicator:nth-of-type(1) { animation-timeline: --one; } .indicator:nth-of-type(2) { animation-timeline: --two; } @​keyframes grow { 50% { flex: 3; }} And there you have it, responsive scroll indicators using CSS scroll-driven animations 😎 Sprinkle a little JavaScript to make them clickable and scroll the the right card ✨ const shift = (event) => { if (event​.target.tagName === "BUTTON") { const index = [...event.target.parentNode.children].indexOf(event​.target); const item = document.querySelector(`li:nth-of-type(${index + 1})`); item.scrollIntoView({ behavior: "smooth", inline: "center" }); } }; As always, any questions or suggestions, let me know. I've put a JavaScript fallback in to use GSAP in browsers that don't have scroll-driven animations 🫶 CodePen.IO link below! 👇

jhey ʕ•ᴥ•ʔ

575,599 görüntüleme • 2 yıl önce