Loading video...

Video Failed to Load

Go Home

Future CSS Tip! 🔮 (This one's close 🤏) You can use "subgrid" to give child elements access to a parent's grid tracks 👀 This is great when you want to make sure content lines up 🙌 Check those cards 👇 article { grid-row: span 4; display: grid; grid-template-rows: subgrid;...

507,746 views • 3 years ago •via X (Twitter)

11 Comments

jhey ▲🐻🎈's profile picture
jhey ▲🐻🎈3 years ago

Here's that @CodePen link! 🚀 Available in Firefox, Safari, and Chrome 117+ 🤙 Now go forth and show off your CSS Grid superpowers. Keen to see what people come up with. Found it tricky to find use cases when I presented this last year 🤓

Mohamed Ramadan's profile picture
Mohamed Ramadan3 years ago

That is really very interseting trick! But lets wait untill it become fully supported ⚠️

jhey ▲🐻🎈's profile picture
jhey ▲🐻🎈3 years ago

P.s I know these cards are ugly 😅

Simon Ramsay 🚀 🧞‍♂️ 𝕩's profile picture
Simon Ramsay 🚀 🧞‍♂️ 𝕩3 years ago

Seem so simple. Does it automatically work out the best heights for each row?

jhey ▲🐻🎈's profile picture
jhey ▲🐻🎈3 years ago

Yeah, the "magic" of implicit grid tracks at play there and working it out off the parent layout 😍 I had to present it at the back end of last year and was hunting around for ways to make use of it 😅

Estebandido's profile picture
Estebandido3 years ago

@Alejo_Gamboa

EREIAMJH's profile picture
EREIAMJH3 years ago

I *really* needed this a few months ago. Found subgrid, then cried when I saw the browser support. Ended up with Javascript workaround. Guess I'll revisit in a few months if it's imminent.

Pedro Filho's profile picture
Pedro Filho3 years ago

This is one of the few use cases that I really use grid

jhey ▲🐻🎈's profile picture
jhey ▲🐻🎈3 years ago

For cards? I find myself often jus' kinda fluidly switching between flex and grid as and when it feels right which is a weird thing to do I guess 😅

Morgan - Freelance frontend developer's profile picture
Morgan - Freelance frontend developer3 years ago

This is one of the use-cases for sub-grid Rachel Andrew wrote about yonks ago. It’s great.

jhey ▲🐻🎈's profile picture
jhey ▲🐻🎈3 years ago

It's nice to finally see it coming into all the browsers. There was a little inconsistency still when I presented it last year. Looks like that is getting ironed out 🙌 Could you think of any other interesting layout use cases?

Related Videos

CSS Tip! 🎠 You can create a responsive infinite marquee animation with container queries and no duplicate items 🤙 li{ animation: slide; } @​keyframes slide { to { translate: 0% calc(var(--i) * -100%);}} The trick is animating the items, not the list 😎 More tricks 👇 To get this one working, you need to animate the items and not the list (Watch the video first?). Each item needs to know its row index (--i) in the list and the parent needs to know how many rows are in the list: ul { --count: 12; } li:nth-of-type(1), li:nth-of-type(2) { --i: 0; } li:nth-of-type(3), li:nth-of-type(4) { --i: 1; } Once you have that, translate each item based on its row index in the list li { translate: 0% calc((var(--count) - var(--i)) * 100%); } Now for the animation. The key here is that each row has an animation-delay calculated from its index (--i). That number is offset to make it negative so the animation start is offset ✨ ul { --duration: 10s; } li { --delay: calc((var(--duration) / var(--count)) * (var(--i) - 8)); animation: slide var(--duration) var(--delay) infinite linear; } Make sure to wrap that animation in: @​media (prefers-reduced-motion: no-preference) { ... } Lastly, the fun parts! 🤓 To create the "vignette" mask. Use a layered mask on the container 😷 .scene { --buff: 3rem; height: 100%; width: 100%; mask: linear-gradient(transparent, white var(--buff) calc(100% - var(--buff)), transparent), linear-gradient(90deg, transparent, white var(--buff) calc(100% - var(--buff)), transparent); mask-composite: intersect; } To create the 3D skewed effect, use a chained transform (Try toggling it in the demo ⚡️): .grid { transform: rotateX(20deg) rotateZ(-20deg) skewX(20deg); } As for the responsive part, use container queries! 🔥 article { container-type: inline-size; } When the article (card) is narrower than 400px update the grid and animation settings 🤙 Double the rows means double the duration! @​container (width < 400px) { .grid { --count: 12; grid-template-columns: 1fr; } li:nth-of-type(1) { --i: 0; } li:nth-of-type(2) { --i: 1; } li:nth-of-type(3) { --i: 2; } li:nth-of-type(4) { --i: 3; } li { --duration: 20s; } } CSS has the magic to be able to update those animations at runtime based on your custom property values 😎 An added bonus in this demo is that it doesn't require any JavaScript at all, for any of it 🤯 We can use CSS :has() for those toggles that update the styles, even the theme toggle! 🫶 Any questions, let me know! Make sure to check out the video. Will do a walkthrough one to follow-up 🤙 CodePen.IO link below! 👇

jhey ʕ•ᴥ•ʔ

542,573 views • 2 years ago

As part of my assignment, I was tasked with designing a high-density data grid for an SEO platform. During development, our analysis of Google Analytics data revealed that the majority of our users access the platform on 13-inch display laptops. This insight necessitated optimizing the data grid for this screen size. A key challenge we encountered was the sidebar housing keyword filters, which occupied a significant portion of the available space. Since this feature was integral to the page, removing it was not an option. Even making it collapsible would have had minimal impact on the overall layout. Our initial approach involved implementing an inner horizontal scroll to accommodate additional columns. However, this solution introduced technical limitations due to the grid’s accordion UI pattern, which enables users to expand rows for detailed views. This functionality effectively split the table in half, making it difficult to synchronize scrolling across two separate grid sections within modern browsers. To address these constraints, I devised an alternative solution: implementing auto-expandable and collapsible columns based on content visibility. For instance, the "Flag" and "Performance" columns dynamically collapse by default and expand when hovered over, allowing users to access the necessary details when needed. This approach enabled us to fit all columns within a 13-inch display without relying on horizontal scrolling, ensuring a more efficient and user-friendly experience.

virgil pana

44,560 views • 1 year 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,730 views • 2 years ago