Video wird geladen...

Video konnte nicht geladen werden

Zur Startseite

CSS Trick! ⭐️ You can animate your gradient borders by defining types for your custom properties with @ property 🔥 1. Define a property @ property --angle { syntax: ' '; /* 👈 type angle*/ inherits: true; initial-value: 0deg; } 2. Animate the value article { animation: rotate 2s...

258,886 Aufrufe • vor 3 Jahren •via X (Twitter)

11 Kommentare

Profilbild von jhey ▲🐻🎈
jhey ▲🐻🎈vor 3 Jahren

Here's that @CodePen link! 🚀 (Which I may or may have not forgotten to post yesterday 👀) Got the "Final boss" border demo that people have been asking for tomorrow 🤞😅

Profilbild von Bill Criswell
Bill Criswellvor 3 Jahren

I think with this and :has I'll be pretty happy for a while. If I get a :stuck for position: sticky I will dance in the street.

Profilbild von Danny Clayden Chambers
Danny Clayden Chambersvor 3 Jahren

Now this really is something new to me.. banking this!

Profilbild von Shaun Levett
Shaun Levettvor 3 Jahren

Succulent

Profilbild von Янус Двуликий
Янус Двуликийvor 3 Jahren

Long time no see thnx

Profilbild von Blueming
Bluemingvor 3 Jahren

Oh wow that looks cool I need this ..thankuuuuuu

Profilbild von 🙊 Shady Sieo 👹
🙊 Shady Sieo 👹vor 3 Jahren

Yeah i tried it too to animate some buttons, works fine on nearly square items, as soon as you do more rectangle shapes, the animation seems to slow down on the corners and the shorts edges... Any tips on how to bypass that ? gg anyway !

Profilbild von jhey ▲🐻🎈
jhey ▲🐻🎈vor 3 Jahren

Got jus' the thing you need 🤙

Profilbild von lil uzi perf
lil uzi perfvor 3 Jahren

Sheesh

Profilbild von Lilesh Jadav
Lilesh Jadavvor 3 Jahren

Which tool was that for showing separate layers?

Profilbild von jhey ▲🐻🎈
jhey ▲🐻🎈vor 3 Jahren

Straight up CSS 🤙

Ähnliche Videos

CSS Trick! 🤙 You can create gradient borders on translucent elements using mask-clip and mask-composite with a pseudo-element 🔥 .gradient-border::after { mask-clip: padding-box, border-box; mask-composite: intersect; mask: linear-gradient(transparent, transparent), linear-gradient(white, white); } It's the same "Transparent border trick" from before. But, now you apply it to a pseudo-element 😎 The trick is to create a pseudo-element with a gradient background and then mask it so we only see the part we want, the border ✨ mask-clip defines the area affected by a mask. Similar to how you can define background-size. Using padding-box and border-box constrains the two masks. mask-composite is the magic part ✨ It defines a compositing operation for stacked mask layers. Using intersect means that the parts that overlap get replaced. And this seems to work in all browsers 🙌 As for the rest of the styles... – Make sure you set pointer-events: none on the pseudo-element – Make sure it fills the parent element. You can use position: absolute and inset: 0 – Make sure the background fills the space including the border-width. You can use calc to achieve that: --bg-size: calc(100% + (2px * var(--border))); background: var(--gradient) center center / var(--bg-size) var(--bg-size); That's it! 🚀 Gradient borders on translucent elements. You can set all the backdrop-filter: blur() you like! 😅 CodePen.IO link below! 👇

jhey ʕ•ᴥ•ʔ

269,966 Aufrufe • vor 3 Jahren

CSS Tip! 🤙 You can use mask-composite and some JavaScript to create this pointer proximity following glow border ✨ .glow { mask-composite: intersect; mask-clip: padding-box, border-box; mask: linear-gradient(#0000, #0000), conic-gradient(#0000 0deg, #​fff, #0000 45deg); } The trick is to mask a background-image with a combination of mask layers. mask-composite: intersect; means the mask used will be the intersection of the layers 🔥 use source-in, xor; in browsers that don't support intersect; In this demo, you can use pseudoelements and rely on scoped custom properties to do a lot of the heavy lifting for you 🙌 Once you've masked the background, you need to update the starting angle of the conic-gradient on pointermove 👆 You can work that out by getting the center point of each card and then calculating the angle between that and the pointer with Math.atan2 🤓 let ANGLE = Math.atan2( event?.y - CARD_CENTER[1], event?.x - CARD_CENTER[0] ) * 180 / Math.PI ANGLE = ANGLE < 0 ? ANGLE + 360 : ANGLE; CARD.​style.setProperty('--start', ANGLE + 90) You plug that into your conic-gradient mask as a custom property accounting for --spread ⚡️ conic-gradient(from calc((var(--angle) - (var(--spread) * 0.5)) * 1deg), #000 0deg, #​fff, #0000 calc(var(--spread) * 1deg)); To get the blur, you apply a blur to the glow container on each card 🤙 .glows { filter: blur(calc(var(--blur) * 1px); } That's it! Layers of masks that are clipped and composited before being blurred 😎 The added trick is to fade each one in when the pointer is in the defined proximity of the card. For example, don't show unless within 100px of a card. You can see that in the video. Check out the JavaScript code for that 🫶 Couldn't resist making this one 😁 CodePen.IO link below! 👇

jhey ʕ•ᴥ•ʔ

1,180,920 Aufrufe • vor 2 Jahren

CSS Tip! ✨ It's 2024 and you have a new way to make animated borders 🚀 .glow::after { offset-path: rect(0 100% 100% 0 round var(--radius)); animation: loop; } @​keyframes loop { to { offset-distance: 100%; }} Using the offset-* properties you can animate elements along the perimeter of others 😍 The rect() value gained support in Safari 17.2 🙌 To start, you create an element and put it inside your main element. For example, you put a span inside the button 🤙 Click me! Make the element fill its parent with absolute positioning and inset [data-glow] { position: absolute; inset: 0; } Now the good part, you use a pseudoelement on that element and define an offset-path [data-glow]::after { content: ""; offset-path: rect(0 auto auto 0 round var(--radius)); animation: loop 2.6s infinite linear; } With the rect value, you are saying the path fills the parent container: top: 0 right: auto || 100% bottom: auto || 100% left: 0 Then you can use round to make sure the path uses the same radius as whatever the parent has The @​keyframes animation merely animates the offset-distance of that pseudoelement to 100% @​keyframes loop { to { offset-distance: 100%; }} You can see this more clearly in the video 🫶 The offset-* properties also include an offset-anchor property. This allows you to dictate which point of the element follows the path. For example: anchor-offset: 100% 50%; This means that the "right, center" of the element will follow the perimeter of the parent element 🤙 Lastly, the visuals 🎨 For color, you can use a gradient such as a linear gradient to fill the pseudo-element. [data-glow]::after { background: radial-gradient( circle at right, hsl(320 90% 100%), transparent 50% ); } Then clip away everything so you only have the border and can still have translucent backgrounds, etc. Use a mask with mask-composite ✨ A little transparent border trick: [data-glow] { border: 2px solid transparent; mask: linear-gradient(transparent, transparent), linear-gradient(white, white); mask-clip: padding-box, border-box; mask-composite: intersect; } Bit of a long one. Hope you find it useful 🙏 CodePen.IO link below 👇

jhey ʕ•ᴥ•ʔ

283,498 Aufrufe • vor 2 Jahren

UI && CSS Tip! 🔥 You can create these dynamic glowing card effects with a single JavaScript event listener, some CSS tricks, and an HTML attribute 🤙 Here's how! 👇 You can use a combination of tricks from previous posts. Let's start with the JavaScript 📜 Use a function like this to send the pointer position via custom properties to the glows ✨ Attach this to the pointermove event 👆 const onPointermove = ({ x, y }) => { document​.documentElemen​t​.style.setProperty('--x', x) document.documentElement​.style.setProperty('--xp', x / innerWidth) document.documentElement​.style.setProperty('--y', y) document.documentElement​.style.setProperty('--yp', y / innerHeight) } Now for the styles 🎨 These custom properties define the border and spotlight size. The first trick is how you can change the color(--hue) based on the pointer position with calc 😎 [data-glow] { --border-size: 2px; --spotlight-size: 150px; --hue: calc(var(--base) + (var(--xp) * var(--spread))); } The magic is using the pointer position in a radial-gradient combined with background-attachment: fixed ✨ (Check the video for an exploding view 🎞️) [data-glow] { background-image: radial-gradient( var(--spotlight-size) var(--spotlight-size) at calc(var(--x, 0) * 1px) calc(var(--y, 0) * 1px), hsl(var(--hue) 100% 70% / 0.25), transparent ); background-attachment: fixed; } The last major piece is using mask-composite on the pseudoelements of the [data-glow] element and the same background-attachment: fixed trick 🫶 [data-glow]::before, [data-glow]::after { pointer-events: none; content: ""; position: absolute; inset: calc(var(--border-size) * -1); border: var(--border-size) solid transparent; background-attachment: fixed; background-size: calc(100% + (2 * var(--border-size))); background-position: 50% 50%; mask: linear-gradient(transparent, transparent), linear-gradient(white, white); mask-clip: padding-box, border-box; mask-composite: intersect; } This masks the elements so only a fake border is shown. That border is actually the spotlight background that moves around 👀 But now it's clipped to the border width 😎 Then it's a case of switching out the background-image for each pseudoelement based on purpose 🧐 For example, to get the white light, use your custom properties, make the light a little smaller and the color bright! [data-glow]::after { background-image: radial-gradient( calc(var(--spotlight-size) * 0.5) calc(var(--spotlight-size) * 0.5) at calc(var(--x, 0) * 1px) calc(var(--y, 0) * 1px), hsl(0 100% 100% / 1), transparent ); } These are the major pieces you need to get it done. Extras? Want the outer glow? Nest a glow! Give the inner glow a blur to create the outer glow 😅 [data-glow] > [data-glow] { filter: blur(10px); } It's worth digging in with this one. Have a play around with the demo and the custom properties. The code isn't perfect after introducing all the configuration pieces 😅 Will put together a reduced example for you! 🙏 Any questions, let me know! 💙 CodePen.IO link below! 👇

jhey ʕ•ᴥ•ʔ

382,535 Aufrufe • vor 2 Jahren

CSS Trick! ⚡️ You can use scroll-driven animation with background-attachment to create a dynamic glowing card scroller without JS 🔥 section { animation:vibe; animation-timeline:--list; } @​keyframes vibe { to{--hue:320;}} .glow {background: hsl(var(--hue) 80% 50%);} Here's how! 🤙 You can use the background-attachment trick used in other glow card demos 😎 article { background-attachment: fixed; } The difference here is that you aren't going to update the fixed background position with your pointer this time. It can remain fixed. The magic part is that as you scroll, the background will leave the card that's leaving and enter the card that's entering ✨ For the extra background glow, you can use a fixed pseudo element on the list container itself 💪 Once that's in place, you're only task is to change the color of the background as you scroll 🤔 Create a custom property declaration for the --hue @​property --base { inherits: true; syntax: ' '; initial-value: 0; } Then create an animation that updates this value @​keyframes accent { to { --hue: 320; }} The last piece is hooking it up to scroll and there is a little trick in here 👀 First, you need an inline scroll-timeline on the list ul { scroll-timeline: --list inline; } Then you can use timeline-scope to hoist that scroll-timeline up so a parent can use it. You then animate the custom property on this element and let the value cascade down to the places that need it 🔥 section { timeline-scope: --list; animation: accent both linear; animation-timeline: --list; } For example, the glow uses the --hue this way [data-glow] { background-image: radial-gradient( 150px 150px at 50% 50%, hsl(var(--hue) 100% 70% / 0.25), transparent ); } Lastly, scroll-snap is optional of course but plays nice with the scroll-driven animation demos ✨ The key for that is ul { scroll-snap-type: x mandatory; } li { scroll-snap-align: center; } That's it! Pretty fun trick to play with! 🤓 Any questions, let me know! Should we add it to the video walkthrough list? CodePen.IO link below! 👇

jhey ʕ•ᴥ•ʔ

116,797 Aufrufe • vor 2 Jahren

CSS Tip! 🍬 You can create a CSS-only sticky CTA using position: sticky or scroll-driven animations 🤙 .cta { position: sticky; margin-top: 110vh; bottom: 2rem; /* 👈 Stick! */ } This is one way 👀 This first way relies on you setting a layout on the body and putting the CTA in a zero-space part of the layout body { display: grid; grid-template-columns: auto 0; } The children of the body are an element with your content and then the CTA. You could also use display:flex too. .content { flex: 1 0 100%; } .cta { place-self: end; } As you scroll the body, the CTA comes into view and sticks in position 🙌 That's one way. If you want to take it further and do something like flip between showing or not, maybe scale it up, or add some special easing, etc. an animation is another way 📜 First, change the styles for your CTA. Note the translate property that's powered by a custom property .cta { position: fixed; bottom: 2rem; right: 2rem; translate: 0 calc(20vh - (var(--show) * 20vh)); transition: translate 0.875s var(--elastic); } Next you need a custom property that you're going to animate @​property --show { inherits: true; initial-value: 0; syntax: ' '; } Lastly, you animate this value on the body. As the property value changes, the value will trickle down to the CTA @​supports (animation-timeline: scroll()) { body { animation: show-cta both steps(1); animation-timeline: scroll(root); animation-range: 0 10vh; } @​keyframes show-cta { to { --show: 1; } } } Using @​supports you can use this as a progressive enhancement. If scroll-driven animations are supported, use them. Otherwise fallback to using position: sticky 🤙 That's it! As always, any questions or requests, hit me up! 🙏 CodePen.IO link below! 👇

jhey ʕ•ᴥ•ʔ

133,020 Aufrufe • vor 2 Jahren

CSS Tip! 💫 You can create this responsive perspective warp animation with 3D CSS and container queries ✨ (Video reveals trick 👀) .warp { container-type: size; perspective: 100px; transform-style: preserve-3d; resize: both; overflow: hidden; } Couple of tricks in this one 🤓 The main idea is to create a tunnel (an open-ended cube). On each side of the tunnel, use linear-gradient to create the grid lines ✨ .side { background: linear-gradient(#​fff 0 1px, transparent 1px 5%) 50% 0 / 5% 5%, linear-gradient(90deg, #​fff 0 1px, transparent 1px 5%) 50% 50% / 5% 5%; } To position each side, you rotate on the x-axis by 90deg. Each side would become invisible at this point. So you give the scene perspective 😉 .warp__side--top { width: 100cqi; height: 100cqmax; transform-origin: 50% 0%; transform: rotateX(-90deg); } The cool part here is that you want to make each side the same height. But the container is responsive. So you can use a container query and make sure each side is 100cqmax tall 🫶 Then the "beams". Each side contains "beams". They have different colors, sizes, and positions, and move at different speeds ⚡️ We can control that through scoped custom properties. .beam { width: 5%; position: absolute; top: 0; left: calc(var(--x, 0) * 5%); aspect-ratio: 1 / 2; background: linear-gradient( hsl(var(--hue) 80% 60%), transparent ); translate: 0 100%; animation: warp calc(var(--speed, 0) * 1s) calc(var(--delay, 0) * -1s) infinite linear; } The magic here is though that a beam's animation is as basic as translating it from the top of the side to the bottom. And you can get that distance with a container query again 🔥 @​keyframes warp { 0% { translate: -50% 100cqmax; } 100% { translate: -50% -100%; } } And that is pretty much it! A cool warp animation effect using 3D CSS and container queries ⚡️ If you have any questions, let me know ᵔᴥᵔ CodePen.IO link below! 👇

jhey ʕ•ᴥ•ʔ

187,474 Aufrufe • vor 2 Jahren

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,854 Aufrufe • vor 2 Jahren

CSS Tip! 📜 You can use scroll-driven animations to progressively enhance collapsing a floating call to action 🤏 .cta { animation: shrink; animation-timeline: scroll(); animation-range: 0 100px; } @​keyframes shrink { to { width: 48px; } } That's the gist of it. Use the body scroll position with animation-timeline: scroll(). Define the animation-range as when you have scrolled 100px. There's a little more though 🤓 That would "scrub" the width animation. Ideally, you want to trigger that animation. You could animate a custom property with steps() timing and use that to define the width ✨ @​property --scrub { syntax: ' '; inherits: true; initial-value: 0; } body { animation: scrub both steps(1, end); animation-timeline: scroll(); animation-range: 0 100px; } Then transition the --scrub property on the CTA and use it for the width 🤙 .cta { transition: --scrub 0.2s; width: calc(48px + (120px * (1 - (var(--scrub) / 100)))); } Other animations are a matter of preference and timing. For example, you could then make the hand wave, scale down the size, and then slide a gradient across 😉 They have the same structure and technique as the original concept. Waving the hand? 👋 Run it twice, offset the transform-origin. .hand { animation: wave both linear 2; animation-timeline: scroll(); animation-range: 30vh 50vh; transform-origin: 65% 75%; } @​keyframes wave { 50% { rotate: 20deg; } } How's it progressively enhanced? Wrap everything in a @​supports query and a @​media query. If there isn't support, users still get a good experience. It's a floating action button that's circular and already collapsed 🤙 @​supports(animation-timeline: scroll()) { @​media(prefers-reduced-motion: no-preference) {...} } Definitely have a play with the code. Amazing what we're going to be able to do with CSS alone! 🔥 CodePen.IO link below! 👇

jhey ʕ•ᴥ•ʔ

178,031 Aufrufe • vor 2 Jahren