Loading video...

Video Failed to Load

Go Home

once you grasp CSS counters, then you can leverage the cascade ๐Ÿง‘โ€๐Ÿณ content: counters(section, '.', pad) var(--t, ' '); need a certain section to start at a different number? use scoped custom properties ๐Ÿซก

57,768 views โ€ข 1 year ago โ€ขvia X (Twitter)

3 Comments

Jidรฉ โœจ's profile picture
Jidรฉ โœจ1 year ago

That drag n drop โค๏ธ how is it done ?

Today's bread's profile picture
Today's bread1 year ago

Are you indirectly saying the drag and drop is just CSS?

Karan Rathod's profile picture
Karan Rathod1 year ago

This man never sleeps and never stops to amaze me with magic of css.

Related Videos

CSS Trick ๐Ÿงฒ You can create magnetic links with the power of custom properties and some JavaScript ๐Ÿ’ช a { translate: calc(clamp(-1, var(--x), 1) * var(--pad-x)) ...; transition: translate var(--s, 1s) var(--ease, var(--elastic)); } a:hover { --s: 0s; } The trick here is to pad out the list items wrapping your links and use that as a translation limit ๐Ÿ›‘ Start by using some JavaScript to calculate a value between -1 and 1 for both the x/y axis on pointermove for each list item, not the link! ๐Ÿ”— If your pointer was at the center of the item, you'd get [0,0]. If it was in the top right, you'd get [1,-1] โ˜๏ธ It's worth checking out the JavaScript snippet to see how the mapping function works. Essentially, you create a function that when given a value between two bounds, will give you a mapped value back ๐Ÿค™ const mapX = mapRange( item.offsetWidth * -0.5, item.offsetWidth * 0.5, 1, -1 ) Then, on pointermove, you plug the pointer position in to get the value back out and pass that into your CSS const x = mapX(item.centerX - event.x) documentโ€‹.documentElementโ€‹.style.setProperty(--x, x) When the pointer leaves the list item, you make sure to reset these values back to 0 โœจ Once CSS has your values, it's the trick of updating the translation of each part You know that in each axis, you only want to translate the link by the padding amount li a { translate: calc(clamp(-1, var(--x), 1) * var(--pad-x)) calc(clamp(-1, var(--y), 1) * var(--pad-y)); transition: translate var(--speed, 1s) var(--ease, var(--elastic)); } This will translate the link within the list item by the desired amount. The cool part here is that you can set an offset for the text inside the link and have that move at a different rate โญ๏ธ By only updating the --pad-x/y custom properties for the inside the link, you can control how much it moves nav a span { --pad-x: 0.25rem; --pad-y: 0.25rem; } And the last piece, how do you update the behavior for transition speeds? And so it springs back like that? Again, use custom properties โœจ a:hover { --s: 0s; } a { transition: translate var(--s, 1s) var(--ease, var(--elastic)); } By default, a link will use --elastic easing via linear() and have a transition-duration of 1s. When a link is hovered that speed becomes 0s because you want the link to magnetise to your pointer. How about that little gap between when your pointer enters the item but hasn't hovered the link? Set a different transition so it transitions to being hovered ๐Ÿซถ nav li:hover a { --ease: ease-out; --speed: 0.1s; } That's kinda it! ๐Ÿ™Œ Use JavaScript (~40 loc) to get the information and then let CSS do all the lifting for you ๐Ÿ’ช Any questions or suggestions, let me know ๐Ÿ™ If you want a walkthrough video, also let me know please ๐Ÿ™ CodePen.IO link below ๐Ÿ‘‡

jhey ส•โ€ขแดฅโ€ขส”

164,863 views โ€ข 2 years ago

CSS Trick ๐Ÿค™ You can create these tab bar controls by using :has() to count the number of tabs โญ๏ธ .tabs:has(input:nth-of-type(3)){--count: 3;} .tabs:has(:checked:nth-of-type(3)){--active: 200%;} .tabs::after{ translate:var(--active) 0;} Let's break it down in this ! ๐Ÿ“ผ Couple of CSS :has() tricks here combined with custom properties ๐Ÿ˜Ž First things first, lay out the tabs using display: grid. This gives you a way to create equal-width tabs ๐Ÿ™ .tabs { display: grid; grid-auto-flow: column; } Then you use :has() to count the number of tabs and store that in a custom property ๐Ÿค“ .tabs:has(input:nth-of-type(3)) { --count: 3; } .tabs:has(input:nth-of-type(4)) { --count: 4; } Using the cascade, the last valid :has() gives you the number of tabs ๐Ÿซถ Using the tab count, you can size the tab indicator. For the tab indicator, use the tabs pseudoelement: .tabs::after { content: ""; position: absolute; height: 100%; width: calc(100% / var(--count)); } See how you can use --count to determine its size ๐Ÿ“ Next, use :has() to determine which tab is active or :checked with input [type=radio] .tabs:has(:checked:nth-of-type(2)) { --active: 1; } .tabs:has(:checked:nth-of-type(3)) { --active: 2; } You can use a zero-indexed translation here. If the second input is :checked, set --active: 1, then translate the pseudoelement on the tabs to that position ๐Ÿ‘‰ .tabs::after { translate: calc(var(--active, 0) * 100%) 0; } Or you could set active to the translation: .tabs:has(:checked:nth-of-type(2)) { --active: 100%; } Setting the custom property allows you to use the index elsewhere if you need it ๐Ÿค™ The final piece is using mix-blend-mode ๐Ÿ‘€ The tabs have a black background-color, the pseudoelement is white, and the label text is white. When you use mix-blend-mode: difference on the pseudoelement it will give this effect that the text transitions from white to black sliding across ๐Ÿ˜Ž .tabs::after { color: hsl(0 0% 100%); mix-blend-mode: difference; } You can totally mix up the colors here though and go with a different effect. The mechanics of how you can use CSS :has() is the main point here ๐Ÿ™ As always, any questions, suggestions, etc. let me know CodePen.IO link below! ๐Ÿ‘‡ (There's even a Tailwind CSS play for this one too ๐Ÿ‘€)

jhey ส•โ€ขแดฅโ€ขส”

70,670 views โ€ข 2 years ago